Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a GitHub Actions workflow to automatically keep the CLOUDFLARED_VERSION variable in docker-bake.hcl up to date. The workflow runs on a schedule (every 6 hours) and can also be triggered manually; it fetches the latest release tag from cloudflare/cloudflared and opens an automated PR if a newer version is found.
Changes:
- Adds a new scheduled GitHub Actions workflow that checks for the latest
cloudflare/cloudflaredrelease - Parses and updates the
CLOUDFLARED_VERSIONdefault value indocker-bake.hclusingawk - Opens a PR via
peter-evans/create-pull-requestif the version has changed
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const release = await github.rest.repos.getLatestRelease({ | ||
| owner: 'cloudflare', | ||
| repo: 'cloudflared' | ||
| }); | ||
| if (!release?.data?.tag_name) { | ||
| core.setFailed('Failed to resolve cloudflared release tag'); | ||
| return; | ||
| } | ||
| core.setOutput('latest_tag', release.data.tag_name); | ||
There was a problem hiding this comment.
The github.rest.repos.getLatestRelease() API call can throw an exception (e.g., an HTTP 404 if there are no releases, or a network error), which would cause the step to fail with an unhandled error rather than a clean core.setFailed message. The if (!release?.data?.tag_name) guard only handles cases where the call succeeds but returns unexpected data — it doesn't catch errors thrown during the API call. Wrapping the call in a try/catch block and calling core.setFailed(error.message) in the catch handler would make error handling more robust and the failure message more informative.
| const release = await github.rest.repos.getLatestRelease({ | |
| owner: 'cloudflare', | |
| repo: 'cloudflared' | |
| }); | |
| if (!release?.data?.tag_name) { | |
| core.setFailed('Failed to resolve cloudflared release tag'); | |
| return; | |
| } | |
| core.setOutput('latest_tag', release.data.tag_name); | |
| try { | |
| const release = await github.rest.repos.getLatestRelease({ | |
| owner: 'cloudflare', | |
| repo: 'cloudflared' | |
| }); | |
| if (!release?.data?.tag_name) { | |
| core.setFailed('Failed to resolve cloudflared release tag'); | |
| return; | |
| } | |
| core.setOutput('latest_tag', release.data.tag_name); | |
| } catch (error) { | |
| core.setFailed(error && error.message ? error.message : String(error)); | |
| } |
| echo "changed=true" >> "$GITHUB_OUTPUT" | ||
| echo "current_version=$current_version" >> "$GITHUB_OUTPUT" | ||
| echo "new_version=$LATEST_TAG" >> "$GITHUB_OUTPUT" |
There was a problem hiding this comment.
Writing externally controlled values directly into $GITHUB_OUTPUT using echo "key=$value" is a known GitHub Actions security concern. If $LATEST_TAG or $current_version contains a newline character (e.g., a maliciously crafted release tag), it could inject additional key=value pairs into $GITHUB_OUTPUT, potentially influencing downstream steps. The recommended mitigation is to use a multi-line delimiter approach with a random delimiter (the EOF pattern using $GITHUB_OUTPUT with heredoc syntax), for example:
echo "new_version<<EOF
$LATEST_TAG
EOF" >> "$GITHUB_OUTPUT"
But more practically, since these values should be single-line version strings, adding an explicit newline/whitespace check before writing would be a sufficient guard.
| - name: Create pull request | ||
| if: steps.update.outputs.changed == 'true' | ||
| uses: peter-evans/create-pull-request@v6 | ||
| with: | ||
| branch: chore/update-cloudflared-${{ steps.update.outputs.new_version }} | ||
| commit-message: "chore: update cloudflared to ${{ steps.update.outputs.new_version }}" | ||
| title: "chore: update cloudflared to ${{ steps.update.outputs.new_version }}" | ||
| body: | | ||
| Automated update of `CLOUDFLARED_VERSION` in `docker-bake.hcl`. | ||
| - Previous version: `${{ steps.update.outputs.current_version }}` | ||
| - New version: `${{ steps.update.outputs.new_version }}` | ||
| Source: `cloudflare/cloudflared` latest GitHub release tag. |
There was a problem hiding this comment.
When using the default GITHUB_TOKEN, pull requests created by peter-evans/create-pull-request will not trigger other GitHub Actions workflows (like docker-build.yml). This is a deliberate GitHub security restriction to prevent recursive workflow runs. Since the docker-build.yml workflow runs on every PR, the automated PR created by this workflow won't have CI checks run against it unless a person with write access closes and reopens the PR, or pushes a new commit to the branch. To make CI trigger automatically, a Personal Access Token (PAT) or a GitHub App token should be passed via the token parameter of this action.
There was a problem hiding this comment.
you can bypass this by setting docker-build to also be triggerable by workflow dispatch and running gh workflow run on the branch after the PR is made
I manually test every new version before I merge it to main, there have been several new versions which justified this practice because of various changes they made upstream with no regard for my image |
|
That testing could probably be automated nowadays though, I just don't feel like doing it myself. I build the image with |
This PR adds an automatic workflow to keep CLOUDFLARED_VERSION updated. It checks the latest release tag from cloudflare/cloudflared every 6 hours (and can be run manually), then opens a PR if a newer version is found.
It only supports one update at a time though, maybe make it just directly commit to main? There's a Cloudflared version that we missed.
2026.2.0