Skip to content

ci: auto-rebuild dist/ for Dependabot production bumps#444

Merged
bdehamer merged 2 commits into
mainfrom
bdehamer/auto-rebuild-dist
Jul 10, 2026
Merged

ci: auto-rebuild dist/ for Dependabot production bumps#444
bdehamer merged 2 commits into
mainfrom
bdehamer/auto-rebuild-dist

Conversation

@bdehamer

Copy link
Copy Markdown
Collaborator

What

Adds a two-workflow pipeline that automatically rebuilds the transpiled dist/ whenever Dependabot bumps a production dependency, so consumers of the action get the updated JavaScript without waiting on a manual rebuild.

Why

Today check-dist.yml detects a stale dist/ and fails the PR, but a human still has to rebuild and push. Every Dependabot prod-dep bump goes red until someone does that by hand.

How

Split across two workflows so untrusted, freshly-bumped dependency code never runs in a job that holds a write token:

  • rebuild-dist.yml — runs unprivileged on the PR (contents: read, no secrets, npm ci --ignore-scripts). Gated to github.actor == 'dependabot[bot]' and dependency-type == 'direct:production' via dependabot/fetch-metadata. Rebuilds dist/; if it changed, uploads the bytes plus PR context (head-ref/head-sha) as an artifact.
  • commit-dist.yml — triggers on workflow_run, so the workflow definition executed here is the trusted copy from main. Downloads the artifact, checks out the PR branch, verifies the head SHA has not moved (race guard), drops in the rebuilt dist/, and commits/pushes with the default GITHUB_TOKEN (contents: write).

Only already-built bytes cross the privilege boundary — no PR-authored or dependency code executes with a write credential.

Notes / trade-offs

  • Uses the built-in GITHUB_TOKEN (no GitHub App to manage). Consequence: the push does not re-trigger check-dist.yml, so the rebuilt dist/ is not independently re-verified. The Verify head is unchanged guard plus the builder's own byte diff are the integrity checks. Swapping to a short-lived App token would restore automatic re-verification if desired.
  • Also corrects two stale comments in check-dist.yml that described Dependabot actor-gating which was never actually implemented.
  • workflows: ["Rebuild dist"] in commit-dist.yml must stay in sync with the name: of rebuild-dist.yml.

Add a two-workflow pipeline that rebuilds the transpiled dist/ whenever
Dependabot bumps a production dependency, so consumers of the action get
the updated JavaScript without a manual rebuild.

- rebuild-dist.yml runs unprivileged on the PR (read-only token, no
  secrets, npm ci --ignore-scripts). Untrusted freshly-bumped dependency
  code executes here and only produces artifacts.
- commit-dist.yml triggers via workflow_run so its definition comes from
  the default branch, downloads the built dist/ bytes, and commits them
  back to the PR branch using GITHUB_TOKEN. No PR code runs privileged.

Also correct two stale comments in check-dist.yml that described
Dependabot actor-gating that was never implemented.

Co-authored-by: Copilot App <[email protected]>
Copilot AI review requested due to automatic review settings July 10, 2026 19:50
@bdehamer
bdehamer requested a review from a team as a code owner July 10, 2026 19:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an automated, two-workflow pipeline to rebuild and auto-commit dist/ for Dependabot direct production dependency bumps, keeping the checked-in transpiled output up to date without a manual rebuild while maintaining a privilege boundary between build and push.

Changes:

  • Adds an unprivileged pull_request workflow (rebuild-dist.yml) to rebuild dist/ for eligible Dependabot PRs and upload the rebuilt bytes + PR context as an artifact.
  • Adds a privileged workflow_run workflow (commit-dist.yml) to download the artifact, verify the PR head SHA hasn’t moved, then commit/push the rebuilt dist/ to the PR branch.
  • Updates check-dist.yml comments to accurately describe how Dependabot dist rebuilds are handled.
Show a summary per file
File Description
.github/workflows/rebuild-dist.yml New unprivileged builder that rebuilds dist/ for Dependabot direct-production bumps and uploads an artifact when changes are detected.
.github/workflows/commit-dist.yml New privileged consumer that downloads the artifact, verifies the PR head SHA, then commits/pushes rebuilt dist/ back to the Dependabot branch.
.github/workflows/check-dist.yml Comment-only updates to reflect the new automatic rebuild/commit behavior for Dependabot production dependency bumps.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment on lines +13 to +15
permissions:
contents: read

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — added pull-requests: read to the workflow permissions in a4018e9 so fetch-metadata can read the PR.

Comment on lines +45 to +52
run: |
if [ -d incoming/dist ] && [ -f incoming/dist-meta/head-ref ]; then
echo "present=true" >> "$GITHUB_OUTPUT"
echo "head-ref=$(cat incoming/dist-meta/head-ref)" >> "$GITHUB_OUTPUT"
echo "head-sha=$(cat incoming/dist-meta/head-sha)" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
fi

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Fixed in a4018e9: the step now reads only the first line, strips CR/LF, and validates head-sha against ^[0-9a-f]{40}$ and head-ref against a safe charset before writing to $GITHUB_OUTPUT — failing closed otherwise. It also requires head-sha to exist before use. Since the values originate from the unprivileged PR-context artifact, this closes the injection vector.

- Grant pull-requests: read in rebuild-dist.yml, required by
  dependabot/fetch-metadata.
- Harden commit-dist.yml: strictly validate head-ref/head-sha read from
  the PR-context artifact (40-hex sha, safe ref charset, single line) and
  require head-sha to exist before use, preventing workflow-command
  injection into $GITHUB_OUTPUT.

Co-authored-by: Copilot App <[email protected]>

@tingx2wang tingx2wang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@bdehamer
bdehamer merged commit 4c65731 into main Jul 10, 2026
6 checks passed
@bdehamer
bdehamer deleted the bdehamer/auto-rebuild-dist branch July 10, 2026 20:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants