Repository navigation
fix: replace binary auto-PR with a drift check (#114) #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,103 @@ | ||
| --- | ||
| name: Keep binary updated | ||
| # Periodically rebuild from the upstream "latest" releases, then raise a new | ||
| # pull-request if the binary file changed. | ||
| name: Check binary is current | ||
| # Verify that the committed proxy/caddy binary matches what a fresh build | ||
| # produces. This runs as a pull-request check rather than raising an automated | ||
| # pull request of its own, because proxy/caddy (~46 MiB) exceeds the 40 MiB | ||
| # limit the GitHub API imposes when creating git blobs, which is the mechanism | ||
| # any bot-signed commit must use. See issue #114. | ||
| # | ||
| # Cribs heavily from this example: | ||
| # https://github.com/peter-evans/create-pull-request/blob/main/docs/examples.md#use-case-create-a-pull-request-to-modifyfix-pull-requests | ||
| # The docker build is pinned to base image digests, so a fresh build is | ||
| # byte-reproducible: drift can only appear when one of the inputs below | ||
| # changes without the binary being rebuilt and committed alongside it. | ||
| # | ||
| # When this check fails, rebuild and commit the binary yourself -- see | ||
| # "For local development" in README.md. | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| schedule: | ||
| # Runs every night around 4:20am EST/1:20am PST | ||
| - cron: "20 8 * * *" | ||
| pull_request: | ||
| types: | ||
| - opened | ||
| - synchronize | ||
| - reopened | ||
| - ready_for_review | ||
| paths: | ||
| - Dockerfile | ||
| - compose.yaml | ||
| - Makefile | ||
|
|
||
| permissions: | ||
| contents: write | ||
| contents: read | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| keep-binary-up-to-date: | ||
| check-binary-current: | ||
| name: Check committed caddy binary matches a fresh build | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Regenerate binary | ||
|
|
||
| - name: Rebuild binary | ||
| run: make | ||
| - name: Did anything change? | ||
| id: vars | ||
|
|
||
| - name: Compare against committed binary | ||
| id: drift | ||
| run: | | ||
| branchname="binary-update/${GITHUB_REF_NAME}" | ||
| echo "branchname=${branchname}" >> $GITHUB_OUTPUT | ||
| binaryupdated=$(git status --porcelain | cut -d ' ' -f 2 | wc -l) | ||
| echo "binaryupdated=${binaryupdated}" >> $GITHUB_OUTPUT | ||
| - name: Create PR with changes | ||
| if: steps.vars.outputs.binaryupdated != 0 | ||
| uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 | ||
| if git diff --quiet -- proxy/caddy; then | ||
| echo "proxy/caddy is current: a fresh build is byte-identical." | ||
| exit 0 | ||
| fi | ||
| # Read the version statically rather than executing the binary. | ||
| caddy_version=$(go version -m proxy/caddy 2>/dev/null \ | ||
| | awk '$1=="dep" && $2=="github.com/caddyserver/caddy/v2" {print $3; exit}') | ||
| sha256=$(sha256sum proxy/caddy | cut -d ' ' -f 1) | ||
| { | ||
| echo "sha256=${sha256}" | ||
| echo "caddy_version=${caddy_version:-unknown}" | ||
| } >> "$GITHUB_OUTPUT" | ||
| # Echo to the log as well, so the values are visible on | ||
| # workflow_dispatch runs where no pull request comment is posted. | ||
| echo "Expected sha256 after rebuilding: ${sha256}" | ||
| echo "Caddy version in fresh build: ${caddy_version:-unknown}" | ||
| echo "::error::proxy/caddy does not match a fresh build. Rebuild it with 'make' and commit the result." | ||
| exit 1 | ||
|
|
||
| - name: Comment on pull request | ||
| if: failure() && github.event_name == 'pull_request' | ||
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | ||
| env: | ||
| EXPECTED_SHA256: ${{ steps.drift.outputs.sha256 }} | ||
| CADDY_VERSION: ${{ steps.drift.outputs.caddy_version }} | ||
| with: | ||
| commit-message: Update binary for ${{ github.ref_name }} | ||
| title: Update caddy binary for ${{ github.ref_name }} | ||
| body: This is an auto-generated PR to add an updated binary on ${{ github.ref_name }}. | ||
| labels: binary-update, automated-pr | ||
| branch: ${{ steps.vars.outputs.branchname }} | ||
| base: ${{ github.ref_name }} | ||
| draft: always-true | ||
| sign-commits: true | ||
| script: | | ||
| const output = `The committed \`proxy/caddy\` does not match what this branch builds. | ||
|
|
||
| Rebuild and commit it: | ||
|
|
||
| \`\`\`bash | ||
| make | ||
| sha256sum proxy/caddy | ||
| \`\`\` | ||
|
|
||
| Expected after rebuilding: | ||
|
|
||
| | | | | ||
| |---|---| | ||
| | sha256 | \`${process.env.EXPECTED_SHA256}\` | | ||
| | caddy version | \`${process.env.CADDY_VERSION}\` | | ||
|
|
||
| If your local sha256 differs from the value above, the build is not | ||
| reproducing and something other than the pinned inputs has changed -- | ||
| investigate before committing. | ||
|
|
||
| The binary must be committed by a human because \`main\` requires signed | ||
| commits, and bot-signed commits cannot carry a file this large (see #114).`; | ||
|
|
||
| github.rest.issues.createComment({ | ||
| issue_number: context.issue.number, | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| body: output | ||
| }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it only runs in response to pull-requests, but we're not regularly making PRs in this repository... So what is the mechanism that triggers the check on a regular basis?
I think this should still be cron-driven, and I like that it's a staleness drift-check. However, in response to drift, it should open a PR that's unmergeable without an updated binary (implying a separate PR check). The created PR should include instructions for the user to update the binary: