diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index daf1028..97a2567 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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) 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: - 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 99f996b..ae0a65d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,6 +9,19 @@ on: - master 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: runs-on: ubuntu-latest steps: diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..85ed642 --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts index 50f31cc..9f04124 100644 --- a/__tests__/buildx.test.ts +++ b/__tests__/buildx.test.ts @@ -2,6 +2,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as semver from 'semver'; import * as buildx from '../src/buildx'; +import * as docker from '../src/docker'; import * as context from '../src/context'; const tmpNameSync = path.join('/tmp/.docker-build-push-jest', '.tmpname-jest').split(path.sep).join(path.posix.sep); @@ -91,11 +92,18 @@ describe('isLocalOrTarExporter', () => { }); describe('getVersion', () => { - it('valid', async () => { - const version = await buildx.getVersion(); - console.log(`version: ${version}`); - expect(semver.valid(version)).not.toBeNull(); - }, 100000); + async function isDaemonRunning() { + return await docker.isDaemonRunning(); + } + (isDaemonRunning() ? it : it.skip)( + 'valid', + async () => { + const version = await buildx.getVersion(); + console.log(`version: ${version}`); + expect(semver.valid(version)).not.toBeNull(); + }, + 100000 + ); }); describe('parseVersion', () => { diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 0000000..e01c414 --- /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" +} 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; + }); +}