diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3eec1ff..51231bf 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -14,6 +14,21 @@ Contributions to this project are [released](https://help.github.com/articles/gi 6. Push to your fork and [submit a pull request](https://github.com/docker/setup-buildx-action/compare) 7. Pat yourself 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: - Make sure the `README.md` and any other relevant **documentation are kept up-to-date**. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a3e05e9..f3e91a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,6 +12,19 @@ on: - "**.md" jobs: + test-containerized: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2.3.2 + - + name: Validate + run: docker buildx bake validate + - + name: Test + run: docker buildx bake test + test: runs-on: ubuntu-latest steps: diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..489c285 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +#syntax=docker/dockerfile:1.1-experimental + +FROM node:14 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 +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"] diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts index 72ac22b..8720846 100644 --- a/__tests__/buildx.test.ts +++ b/__tests__/buildx.test.ts @@ -1,4 +1,5 @@ import fs = require('fs'); +import * as docker from '../src/docker'; import * as buildx from '../src/buildx'; import * as path from 'path'; import * as os from 'os'; @@ -6,6 +7,10 @@ import * as os from 'os'; const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'setup-buildx-')); describe('buildx', () => { + async function isDaemonRunning() { + return await docker.isDaemonRunning(); + } + it('is available', async () => { expect(await buildx.isAvailable()).toBe(true); }, 100000); @@ -16,12 +21,16 @@ describe('buildx', () => { expect(countBuilders).toBeGreaterThan(0); }, 100000); - it('platforms', async () => { - const platforms = await buildx.platforms(); - console.log(`platforms: ${platforms}`); - expect(platforms).not.toBeUndefined(); - expect(platforms).not.toEqual(''); - }, 100000); + (isDaemonRunning() ? it : it.skip)( + 'platforms', + async () => { + const platforms = buildx.platforms(); + console.log(`platforms: ${platforms}`); + expect(platforms).not.toBeUndefined(); + expect(platforms).not.toEqual(''); + }, + 100000 + ); it('acquires v0.2.2 version of buildx', async () => { const buildxBin = await buildx.install('v0.2.2', tmpDir); diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..f7f1745 --- /dev/null +++ b/docker-bake.hcl @@ -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" +} \ No newline at end of file diff --git a/hack/shell b/hack/shell new file mode 100755 index 0000000..97b23ea --- /dev/null +++ b/hack/shell @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +iidfile=$(mktemp -t docker-iidfile.XXXXXXXXXX) +DOCKER_BUILDKIT=1 docker build --iidfile $iidfile --progress=plain . +docker run -it --rm $(cat $iidfile) +docker rmi $(cat $iidfile) diff --git a/src/docker.ts b/src/docker.ts new file mode 100644 index 0000000..a35b384 --- /dev/null +++ b/src/docker.ts @@ -0,0 +1,7 @@ +import * as exec from './exec'; + +export async function isDaemonRunning(): Promise { + return await exec.exec(`docker`, ['version', '--format', '{{.Server.Os}}'], true).then(res => { + return !res.stdout.includes(' ') && res.success; + }); +}