build: drop docker-bake in favor of plain npm (#551)

* build: drop docker-bake in favor of plain npm

Every TypeScript action maintained by actions/* (checkout, setup-node,
setup-go, cache, upload-artifact) uses plain npm scripts. The bake
setup is a docker/* org convention and adds friction for TS work:
contributors need Docker, the dev loop is ~10x slower than npm, and
Alpine-vs-host byte drift in dist/index.js makes PRs bounce.

Replace with the standard pattern:
- .node-version pins Node 24 so contributors and CI agree
- npm scripts (build, lint, format, test, pre-checkin) replace bake
  targets one-for-one
- validate.yml runs lint + a check-dist diff (mirrors actions/setup-node)
  and a vendor check that npm install --package-lock-only is a no-op
- test.yml uses setup-node + sigstore/cosign-installer, drops bake-action
- dependabot-build.yml regenerates dist via npm instead of bake

CONTRIBUTING.md and README development section updated to match.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* build: align scripts and workflows with actions/* convention

Match the standard layout used by actions/checkout, actions/setup-node,
etc.:

- package.json scripts: split format/format-check (Prettier) from
  lint/lint:fix (ESLint), and have pre-checkin run all four (format,
  lint:fix, build, test) in that order.
- validate.yml lint job runs format-check + lint as separate steps.
- test.yml drops the redundant --coverage flag (now in the test script).
- Drop dependabot-build.yml: actions/* don't auto-rebuild dist on
  dependabot PRs; the check-dist style validate / build job catches
  drift and a maintainer rebuilds locally if needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker
2026-04-18 15:22:23 -03:00
committed by GitHub
parent 213ec80f56
commit 4068afa2f0
9 changed files with 129 additions and 267 deletions
-46
View File
@@ -1,46 +0,0 @@
name: dependabot-build
on:
pull_request:
paths:
- 'package.json'
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
-
name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.head_ref }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
-
name: Vendor
uses: docker/bake-action@82490499d2e5613fcead7e128237ef0b0ea210f7 # v7.0.0
with:
targets: vendor
-
name: Pre-checkin
uses: docker/bake-action@82490499d2e5613fcead7e128237ef0b0ea210f7 # v7.0.0
with:
targets: pre-checkin
-
name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore: update dist and vendor"
git push
fi
+13 -4
View File
@@ -25,11 +25,20 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- -
name: Test name: Setup Node.js
uses: docker/bake-action@82490499d2e5613fcead7e128237ef0b0ea210f7 # v7.0.0 uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
with: with:
source: . node-version-file: '.node-version'
targets: test cache: npm
-
name: Install cosign
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
-
name: Install dependencies
run: npm ci
-
name: Test
run: npm test
- -
name: Upload coverage name: Upload coverage
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
+68 -17
View File
@@ -16,32 +16,83 @@ on:
pull_request: pull_request:
jobs: jobs:
prepare: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps: steps:
- -
name: Checkout name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- -
name: Generate matrix name: Setup Node.js
id: generate uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
uses: docker/bake-action/subaction/matrix@82490499d2e5613fcead7e128237ef0b0ea210f7 # v7.0.0
with: with:
target: validate node-version-file: '.node-version'
cache: npm
-
name: Install dependencies
run: npm ci
-
name: Format check
run: npm run format-check
-
name: Lint
run: npm run lint
validate: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs:
- prepare
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps: steps:
- -
name: Validate name: Checkout
uses: docker/bake-action@82490499d2e5613fcead7e128237ef0b0ea210f7 # v7.0.0 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
-
name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
with: with:
targets: ${{ matrix.target }} node-version-file: '.node-version'
cache: npm
-
name: Install dependencies
run: npm ci --ignore-scripts
-
name: Rebuild dist
run: npm run build
-
name: Compare dist
id: diff
run: |
if [ "$(git diff --ignore-space-at-eol dist | wc -l)" -gt "0" ]; then
echo "Detected uncommitted changes after build. Run 'npm run build' and commit dist/." >&2
git diff dist
exit 1
fi
-
name: Upload built dist on failure
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: dist
path: dist
vendor:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
-
name: Setup Node.js
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v6.0.0
with:
node-version-file: '.node-version'
cache: npm
-
name: Refresh package-lock.json
run: npm install --package-lock-only
-
name: Compare package-lock.json
run: |
if [ -n "$(git status --porcelain -- package-lock.json)" ]; then
echo "package-lock.json is out of sync with package.json. Run 'npm install' and commit." >&2
git diff package-lock.json
exit 1
fi
+1
View File
@@ -0,0 +1 @@
24
+37 -52
View File
@@ -1,78 +1,63 @@
# Contributing # Contributing
Thanks for your interest in contributing! This document covers the development Thanks for your interest in contributing!
workflow needed to get a change ready to commit and push.
## Prerequisites ## Prerequisites
- [Docker](https://docs.docker.com/get-docker/) with [Buildx](https://docs.docker.com/buildx/working-with-buildx/) - [Node.js](https://nodejs.org/) — version pinned in [`.node-version`](./.node-version).
- Git Tools like [`nvm`](https://github.com/nvm-sh/nvm), [`fnm`](https://github.com/Schniz/fnm),
[`asdf`](https://asdf-vm.com/), or [`mise`](https://mise.jdx.dev/) read this file
automatically.
- [`cosign`](https://docs.sigstore.dev/cosign/installation/) — only required if you
want to run the signature-verification integration tests locally.
That's it. Everything else (Node, npm, linters, the test environment) runs ## Setup
inside containers driven by `docker buildx bake`.
```sh
npm ci
```
## Pre-commit checklist ## Pre-commit checklist
Run these commands, in order, before committing any change to `src/`, Before committing changes to `src/`, `__tests__/`, `package.json`,
`__tests__/`, `package.json`, `package-lock.json`, or `action.yml`: `package-lock.json`, or `action.yml`:
```sh ```sh
# 1. Format source, refresh node_modules, regenerate dist/index.js npm run pre-checkin
docker buildx bake pre-checkin
# 2. Run the test suite (unit + integration; needs network for release downloads)
docker buildx bake test
# 3. Validate that everything is committed and reproducible
docker buildx bake validate
``` ```
`validate` is what CI runs. If it passes locally, your PR will pass the That runs `format` + `build` + `test` — the same checks CI runs.
`validate` job too.
### Why `pre-checkin` matters Then commit `dist/` along with your source changes; the action runtime loads
`dist/index.js` directly, so it must stay in sync.
The repository ships the compiled action as `dist/index.js`. CI's If CI's `validate / build` job fails because `dist/` differs from a fresh
`build-validate` target rebuilds it inside an Alpine container and fails if the build, just download the `dist` artifact from the failed run and commit it —
checked-in bytes don't match. **You must commit the `dist/` output produced by or rerun `npm run build` locally with the Node version in `.node-version`.
`docker buildx bake pre-checkin`** — running `npm run build` on macOS or a
non-Alpine host produces slightly different bytes and `validate` will reject
the PR.
If you forget and CI complains about a `dist/` diff, just run: ## npm scripts
```sh | Script | Purpose |
docker buildx bake build | ------------------- | ------------------------------------------------ |
git add dist/ | `npm run build` | Bundle `src/` to `dist/index.js` via `ncc` |
git commit --amend --no-edit | `npm run format` | Run Prettier (write) |
git push --force-with-lease | `npm run format-check` | Run Prettier (check only, used in CI) |
``` | `npm run lint` | Run ESLint (check only, used in CI) |
| `npm run lint:fix` | Run ESLint with `--fix` |
## Available bake targets | `npm test` | Run Jest with coverage |
| `npm run pre-checkin` | `format` + `lint:fix` + `build` + `test` |
| Target | Purpose |
| --------------- | --------------------------------------------------- |
| `build` | Regenerate `dist/index.js` only |
| `format` | Run Prettier on `src/` and `__tests__/` |
| `vendor` | Refresh `node_modules` / `package-lock.json` |
| `pre-checkin` | `vendor` + `format` + `build` (run before commits) |
| `lint` | Prettier check + ESLint |
| `build-validate`| Verify `dist/index.js` matches a fresh build |
| `vendor-validate`| Verify `package-lock.json` is in sync |
| `validate` | `lint` + `build-validate` + `vendor-validate` |
| `test` | Run Jest with coverage in an Alpine container |
## Tests ## Tests
`docker buildx bake test` runs the full Jest suite, including integration `npm test` runs the full Jest suite, including integration tests that:
tests that:
- Download real GoReleaser releases from GitHub - Download real GoReleaser releases from GitHub
- Verify `checksums.txt` against the downloaded archive - Verify `checksums.txt` against the downloaded archive
- Verify the cosign sigstore bundle (`cosign` is installed in the test image) - Verify the cosign sigstore bundle (skipped if `cosign` isn't on `PATH`,
but the CI image always has it installed)
These need outbound network access. If you're behind a restrictive proxy or These need outbound network access. Offline / restrictive-proxy runs will
offline, those tests will fail — that's expected. have those tests fail — that's expected.
## Commit messages ## Commit messages
@@ -82,7 +67,7 @@ Use [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`,
## Pull requests ## Pull requests
- Target `master`. - Target `master`.
- Make sure `docker buildx bake validate` and `docker buildx bake test` pass. - Make sure `npm run pre-checkin` passes.
- One logical change per PR is easier to review. - One logical change per PR is easier to review.
- The `signing` CI job and `goreleaser-pro` matrix entries are skipped on PRs - The `signing` CI job and `goreleaser-pro` matrix entries are skipped on PRs
from forks because they need repository secrets — that's expected and not from forks because they need repository secrets — that's expected and not
+4 -7
View File
@@ -238,14 +238,11 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full development workflow.
Quick reference: Quick reference:
``` ```
# format code and build javascript artifacts # install dependencies
docker buildx bake pre-checkin npm ci
# validate all code has correctly formatted and built # format, build dist/, and run tests
docker buildx bake validate npm run pre-checkin
# run tests
docker buildx bake test
``` ```
## License ## License
-72
View File
@@ -1,72 +0,0 @@
# syntax=docker/dockerfile:1
ARG NODE_VERSION=24
FROM node:${NODE_VERSION}-alpine AS base
RUN apk add --no-cache cpio findutils git
WORKDIR /src
FROM base AS deps
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
npm install && mkdir /vendor && cp package-lock.json /vendor
FROM scratch AS vendor-update
COPY --from=deps /vendor /
FROM deps AS vendor-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /vendor/* .
if [ -n "$(git status --porcelain -- package-lock.json)" ]; then
echo >&2 'ERROR: Vendor result differs. Please vendor your package with "docker buildx bake vendor"'
git status --porcelain -- package-lock.json
exit 1
fi
EOT
FROM deps AS build
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
npm run build && mkdir /out && cp -Rf dist /out/
FROM scratch AS build-update
COPY --from=build /out /
FROM build AS build-validate
RUN --mount=type=bind,target=.,rw <<EOT
set -e
git add -A
cp -rf /out/* .
if [ -n "$(git status --porcelain -- dist)" ]; then
echo >&2 'ERROR: Build result differs. Please build first with "docker buildx bake build"'
git status --porcelain -- dist
exit 1
fi
EOT
FROM deps AS format
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
npm run format \
&& mkdir /out && find . -name '*.ts' -not -path './node_modules/*' | cpio -pdm /out
FROM scratch AS format-update
COPY --from=format /out /
FROM deps AS lint
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
npm run lint
FROM deps AS test
RUN apk add --no-cache cosign
ENV RUNNER_TEMP=/tmp/github_runner
ENV RUNNER_TOOL_CACHE=/tmp/github_tool_cache
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/src/node_modules \
npm run test -- --coverage --coverageDirectory=/tmp/coverage
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage /
-61
View File
@@ -1,61 +0,0 @@
target "_common" {
args = {
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
}
}
group "default" {
targets = ["build"]
}
group "pre-checkin" {
targets = ["vendor", "format", "build"]
}
group "validate" {
targets = ["lint", "build-validate", "vendor-validate"]
}
target "build" {
dockerfile = "dev.Dockerfile"
target = "build-update"
output = ["."]
}
target "build-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "build-validate"
output = ["type=cacheonly"]
}
target "format" {
dockerfile = "dev.Dockerfile"
target = "format-update"
output = ["."]
}
target "lint" {
dockerfile = "dev.Dockerfile"
target = "lint"
output = ["type=cacheonly"]
}
target "vendor" {
dockerfile = "dev.Dockerfile"
target = "vendor-update"
output = ["."]
}
target "vendor-validate" {
inherits = ["_common"]
dockerfile = "dev.Dockerfile"
target = "vendor-validate"
output = ["type=cacheonly"]
}
target "test" {
dockerfile = "dev.Dockerfile"
target = "test-coverage"
output = ["./coverage"]
}
+6 -8
View File
@@ -5,14 +5,12 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"build": "ncc build src/main.ts --minify --license licenses.txt", "build": "ncc build src/main.ts --minify --license licenses.txt",
"lint": "npm run prettier && npm run eslint", "format": "prettier --write \"**/*.ts\"",
"format": "npm run prettier:fix && npm run eslint:fix", "format-check": "prettier --check \"**/*.ts\"",
"eslint": "eslint --max-warnings=0 .", "lint": "eslint --max-warnings=0 \"**/*.ts\"",
"eslint:fix": "eslint --fix .", "lint:fix": "eslint --fix \"**/*.ts\"",
"prettier": "prettier --check \"./**/*.ts\"", "test": "NODE_OPTIONS='--experimental-vm-modules' jest --coverage",
"prettier:fix": "prettier --write \"./**/*.ts\"", "pre-checkin": "npm run format && npm run lint:fix && npm run build && npm test"
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
"all": "npm run build && npm run format && npm test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",