Compare commits

...

11 Commits

Author SHA1 Message Date
41a004098f Merge pull request #203 from crazy-max/update-troubleshooting
Update troubleshooting notes
2020-10-23 14:32:04 -07:00
41b2c888ba Merge pull request #204 from crazy-max/cache-issue-fixed
Cache issue is now fixed
2020-10-23 14:30:44 -07:00
72350a828e Cache issue is now fixed
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-10-23 23:06:56 +02:00
5f6cd6b99d Update troubleshooting notes
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-10-23 22:51:59 +02:00
bef45c0027 Merge pull request #201 from mathieubergeron/fix-parse-secret-containing-equal-character
Fix parsing of secrets containing '=' character
2020-10-23 22:39:07 +02:00
c8e09bfd16 Merge remote-tracking branch 'upstream/master' into fix-parse-secret-containing-equal-character
# Conflicts:
#	__tests__/buildx.test.ts
2020-10-23 16:35:54 -04:00
b3b0ca3523 Merge pull request #202 from crazy-max/bake-dev
Container based developer flow
2020-10-23 22:25:15 +02:00
0307a522bb Container based developer flow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-10-23 21:59:05 +02:00
8616d520af Update dist/index.js
Signed-off-by: Mathieu Bergeron <mathieu.bergeron@nuecho.com>
2020-10-23 15:02:42 -04:00
21692b9878 Fix usage of deprecated substr (=> substring)
Signed-off-by: Mathieu Bergeron <mathieu.bergeron@nuecho.com>
2020-10-23 13:49:33 -04:00
fc7e9a2b38 Fix parsing of secrets containing '=' character
Signed-off-by: Mathieu Bergeron <mathieu.bergeron@nuecho.com>
2020-10-23 13:31:33 -04:00
12 changed files with 409 additions and 3198 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
node_modules

View File

@ -15,6 +15,21 @@ Contributions to this project are [released](https://help.github.com/articles/gi
7. Push to your fork and [submit a pull request](https://github.com/docker/build-push-action/compare) 7. Push to your fork and [submit a pull request](https://github.com/docker/build-push-action/compare)
8. Pat your self on the back and wait for your pull request to be reviewed and merged. 8. Pat your self on the back and wait for your pull request to be reviewed and merged.
## Container based developer flow
If you don't want to maintain a Node developer environment that fits this project you can use containerized commands instead of invoking yarn directly.
```
# format code and build javascript artifacts
docker buildx bake pre-checkin
# validate all code has correctly formatted and built
docker buildx bake validate
# run tests
docker buildx bake test
```
Here are a few things you can do that will increase the likelihood of your pull request being accepted: Here are a few things you can do that will increase the likelihood of your pull request being accepted:
- Make sure the `README.md` and any other relevant **documentation are kept up-to-date**. - Make sure the `README.md` and any other relevant **documentation are kept up-to-date**.

View File

@ -381,10 +381,8 @@ jobs:
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v1
with: with:
# TODO: Remove image=moby/buildkit:buildx-stable-1 when moby/buildkit#1727 fixed
driver-opts: | driver-opts: |
network=host network=host
image=moby/buildkit:buildx-stable-1
- -
name: Build and push (1) name: Build and push (1)
id: docker_build id: docker_build
@ -481,10 +479,8 @@ jobs:
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v1
with: with:
# TODO: Remove image=moby/buildkit:buildx-stable-1 when moby/buildkit#1727 fixed
driver-opts: | driver-opts: |
network=host network=host
image=moby/buildkit:buildx-stable-1
- -
name: Cache Docker layers name: Cache Docker layers
uses: actions/cache@v2 uses: actions/cache@v2
@ -551,10 +547,8 @@ jobs:
id: buildx id: buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v1
with: with:
# TODO: Remove image=moby/buildkit:buildx-stable-1 when moby/buildkit#1727 fixed
driver-opts: | driver-opts: |
network=host network=host
image=moby/buildkit:buildx-stable-1
- -
name: Cache Docker layers name: Cache Docker layers
uses: actions/cache@v2 uses: actions/cache@v2

View File

@ -9,6 +9,19 @@ on:
- master - master
jobs: jobs:
test-containerized:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2.3.3
-
name: Validate
run: docker buildx bake validate
-
name: Test
run: docker buildx bake test
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:

52
Dockerfile Normal file
View File

@ -0,0 +1,52 @@
#syntax=docker/dockerfile:1.1-experimental
FROM node:12 AS deps
WORKDIR /src
COPY package.json yarn.lock ./
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \
yarn install
FROM scratch AS update-yarn
COPY --from=deps /src/yarn.lock /
FROM deps AS validate-yarn
COPY .git .git
RUN status=$(git status --porcelain -- yarn.lock); if [ -n "$status" ]; then echo $status; exit 1; fi
FROM deps AS base
COPY . .
FROM base AS build
RUN yarn build
FROM deps AS test
COPY --from=docker /usr/local/bin/docker /usr/bin/
ARG TARGETOS
ARG TARGETARCH
ARG BUILDX_VERSION=v0.4.2
ENV RUNNER_TEMP=/tmp/github_runner
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
RUN mkdir -p /usr/local/lib/docker/cli-plugins && \
curl -fsSL https://github.com/docker/buildx/releases/download/$BUILDX_VERSION/buildx-$BUILDX_VERSION.$TARGETOS-$TARGETARCH > /usr/local/lib/docker/cli-plugins/docker-buildx && \
chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx && \
docker buildx version
COPY . .
RUN yarn run test
FROM base AS run-format
RUN yarn run format
FROM scratch AS format
COPY --from=run-format /src/src/*.ts /src/
FROM base AS validate-format
RUN yarn run format-check
FROM scratch AS dist
COPY --from=build /src/dist/ /dist/
FROM build AS validate-build
RUN status=$(git status --porcelain -- dist); if [ -n "$status" ]; then echo $status; exit 1; fi
FROM base AS dev
ENTRYPOINT ["bash"]

View File

@ -1,6 +1,114 @@
# Troubleshooting # Troubleshooting
## Errors on pushing to registry * [`auto-push is currently not implemented for docker driver`](#auto-push-is-currently-not-implemented-for-docker-driver)
* [Cannot push to a registry](#cannot-push-to-a-registry)
## `auto-push is currently not implemented for docker driver`
If you're using the default builder (which uses the docker driver) without using our `setup-buildx-action`, you may
encounter this error message if you try to push your image:
```
Run docker/build-push-action@v2
📣 Buildx version: 0.4.2
🏃 Starting build...
/usr/bin/docker buildx build --tag localhost:5000/name/app:latest --iidfile /tmp/docker-build-push-eYl8PB/iidfile --file ./test/Dockerfile --push ./test
auto-push is currently not implemented for docker driver
Error: buildx call failed with: auto-push is currently not implemented for docker driver
```
While waiting for an implementation to be done on buildx/buildkit, you have the following possibilities
to solve this atm:
### With `docker-container` driver and `setup-buildx`
> Recommended solution
```yaml
jobs:
build:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ env.USER }}
password: ${{ secrets.PASSWORD }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: .
tags: ${{ env.REGISTRY }}/myapp:latest
push: true
```
### With `docker` driver
```yaml
jobs:
build:
-
name: Checkout
uses: actions/checkout@v2
-
name: Login
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ env.USER }}
password: ${{ secrets.PASSWORD }}
-
name: Build
uses: docker/build-push-action@v2
with:
context: .
tags: ${{ env.REGISTRY }}/myapp:latest
load: true
-
name: Push
run: docker push ${{ env.REGISTRY }}/myapp:latest
```
### With `docker` driver and `setup-buildx`
```yaml
jobs:
build:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
with:
driver: docker
-
name: Login
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ env.USER }}
password: ${{ secrets.PASSWORD }}
-
name: Build
uses: docker/build-push-action@v2
with:
context: .
tags: ${{ env.REGISTRY }}/myapp:latest
load: true
-
name: Push
run: docker push ${{ env.REGISTRY }}/myapp:latest
```
## Cannot push to a registry
While pushing to a registry, you may encounter these kinds of issues: While pushing to a registry, you may encounter these kinds of issues:

View File

@ -2,9 +2,10 @@ import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as semver from 'semver'; import * as semver from 'semver';
import * as buildx from '../src/buildx'; import * as buildx from '../src/buildx';
import * as exec from '@actions/exec'; import * as docker from '../src/docker';
import * as context from '../src/context'; import * as context from '../src/context';
const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep);
const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9'; const digest = 'sha256:bfb45ab72e46908183546477a08f8867fc40cebadd00af54b071b097aed127a9';
jest.spyOn(context, 'tmpDir').mockImplementation((): string => { jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
@ -16,7 +17,7 @@ jest.spyOn(context, 'tmpDir').mockImplementation((): string => {
}); });
jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => { jest.spyOn(context, 'tmpNameSync').mockImplementation((): string => {
return path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); return tmpNameSync;
}); });
describe('getImageID', () => { describe('getImageID', () => {
@ -91,11 +92,18 @@ describe('isLocalOrTarExporter', () => {
}); });
describe('getVersion', () => { describe('getVersion', () => {
it('valid', async () => { async function isDaemonRunning() {
return await docker.isDaemonRunning();
}
(isDaemonRunning() ? it : it.skip)(
'valid',
async () => {
const version = await buildx.getVersion(); const version = await buildx.getVersion();
console.log(`version: ${version}`); console.log(`version: ${version}`);
expect(semver.valid(version)).not.toBeNull(); expect(semver.valid(version)).not.toBeNull();
}, 100000); },
100000
);
}); });
describe('parseVersion', () => { describe('parseVersion', () => {
@ -107,3 +115,18 @@ describe('parseVersion', () => {
expect(await buildx.parseVersion(stdout)).toEqual(expected); expect(await buildx.parseVersion(stdout)).toEqual(expected);
}); });
}); });
describe('getSecret', () => {
test.each([
['A_SECRET', 'abcdef0123456789'],
['GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789'],
['MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==']
])('given %p key and %p secret', async (key, secret) => {
const secretArgs = await buildx.getSecret(`${key}=${secret}`);
console.log(`secretArgs: ${secretArgs}`);
expect(secretArgs).toEqual(`id=${key},src=${tmpNameSync}`);
const secretContent = await fs.readFileSync(tmpNameSync, 'utf-8');
console.log(`secretValue: ${secretContent}`);
expect(secretContent).toEqual(secret);
});
});

View File

@ -1,6 +1,5 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as buildx from '../src/buildx';
import * as context from '../src/context'; import * as context from '../src/context';
jest.spyOn(context, 'defaultContext').mockImplementation((): string => { jest.spyOn(context, 'defaultContext').mockImplementation((): string => {
@ -107,7 +106,7 @@ describe('getArgs', () => {
'0.4.2', '0.4.2',
new Map<string, string>([ new Map<string, string>([
['context', '.'], ['context', '.'],
['secrets', 'GIT_AUTH_TOKEN=abcdefghijklmno0123456789'], ['secrets', 'GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'],
]), ]),
[ [
'buildx', 'buildx',
@ -139,7 +138,7 @@ describe('getArgs', () => {
['context', 'https://github.com/docker/build-push-action.git#heads/master'], ['context', 'https://github.com/docker/build-push-action.git#heads/master'],
['tag', 'localhost:5000/name/app:latest'], ['tag', 'localhost:5000/name/app:latest'],
['platforms', 'linux/amd64,linux/arm64'], ['platforms', 'linux/amd64,linux/arm64'],
['secrets', 'GIT_AUTH_TOKEN=abcdefghijklmno0123456789'], ['secrets', 'GIT_AUTH_TOKEN=abcdefghijklmno=0123456789'],
['file', './test/Dockerfile'], ['file', './test/Dockerfile'],
['builder', 'builder-git-context-2'], ['builder', 'builder-git-context-2'],
['push', 'true'] ['push', 'true']

3311
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

42
docker-bake.hcl Normal file
View File

@ -0,0 +1,42 @@
group "default" {
targets = ["build"]
}
group "pre-checkin" {
targets = ["update-yarn", "format", "build"]
}
group "validate" {
targets = ["validate-format", "validate-build", "validate-yarn"]
}
target "update-yarn" {
target = "update-yarn"
output = ["."]
}
target "build" {
target = "dist"
output = ["."]
}
target "test" {
target = "test"
}
target "format" {
target = "format"
output = ["."]
}
target "validate-format" {
target = "validate-format"
}
target "validate-build" {
target = "validate-build"
}
target "validate-yarn" {
target = "validate-yarn"
}

View File

@ -18,7 +18,9 @@ export async function getImageID(): Promise<string | undefined> {
} }
export async function getSecret(kvp: string): Promise<string> { export async function getSecret(kvp: string): Promise<string> {
const [key, value] = kvp.split('='); const delimiterIndex = kvp.indexOf('=');
const key = kvp.substring(0, delimiterIndex);
const value = kvp.substring(delimiterIndex + 1);
const secretFile = context.tmpNameSync({ const secretFile = context.tmpNameSync({
tmpdir: context.tmpDir() tmpdir: context.tmpDir()
}); });

7
src/docker.ts Normal file
View File

@ -0,0 +1,7 @@
import * as exec from './exec';
export async function isDaemonRunning(): Promise<boolean> {
return await exec.exec(`docker`, ['version', '--format', '{{.Server.Os}}'], true).then(res => {
return !res.stdout.includes(' ') && res.success;
});
}