Skip to content

Automate cloudflared updates with multi-arch smoke tests - #41

Open
Hazmi35 wants to merge 1 commit into
Erisa:mainfrom
hzmifork:workflow
Open

Hazmi35 wants to merge 1 commit into
Erisa:mainfrom
hzmifork:workflow

Conversation

@Hazmi35

@Hazmi35 Hazmi35 commented Mar 9, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to the discussion in this PR. It automates the manual test (bake, run with --hello-world, request the tunnel URL several times) on every architecture, and merges new versions automatically once they pass and nobody has objected for 24 hours.

docker-build.yml

  • Adds a workflow_dispatch trigger, as suggested here.
  • Adds a smoke-test job for all 8 platforms. It runs on every push and PR, next to the existing multi-arch build. Each job:
    • builds an image for its platform,
    • checks that cloudflared version matches CLOUDFLARED_VERSION,
    • starts a quick tunnel with --hello-world,
    • requests it 5 times and expects the hello world page each time.
Platform Runs on
linux/amd64, linux/386 ubuntu-latest, natively
linux/arm64 ubuntu-24.04-arm, natively
linux/arm/v7 QEMU, emulating a Cortex-A7 (Raspberry Pi 2)
linux/arm/v6 QEMU, emulating an ARM1176 (Raspberry Pi 1/Zero)
linux/s390x, linux/ppc64le, linux/riscv64 QEMU

The v6 job emulates the actual Pi 1 CPU, so a regression of the GOARM=6 fix gets caught. I checked this: the v7 binary crashes with Illegal instruction on that CPU, and the v6 binary runs.

update-cloudflared.yml

Runs every 6 hours, or manually, optionally for a specific version.

  1. Merges a tested update. It merges the open update PR when all of these hold:

    • its build and every smoke test passed,
    • its last update was at least 24 hours ago,
    • it only has bot commits,
    • it doesn't have the hold label.

    It squash-merges, then runs docker-build on main to publish. A merge made with GITHUB_TOKEN doesn't trigger the push build, so this step is needed. If the build fails, it re-runs the failed jobs once, because quick tunnels are best effort. If they fail again, it comments once on the PR and mentions the repo owner.

  2. Opens or updates the PR.

    • Bumps CLOUDFLARED_VERSION to the latest upstream release.
    • Bumps GOVERSION to the newest golang:X.Y.Z-alpine$ALPINEVERSION image on Docker Hub, for the Go minor that the release's go.mod requires. It never downgrades. It keeps the Dockerfile's ARG GOVERSION default on the same minor.
      • This matters right now: cloudflared 2026.10.1+ needs Go 1.27. The golang images set GOTOOLCHAIN=local, so bumping only the cloudflared version would fail to build.
    • Opens or updates a single update-cloudflared PR, then runs docker-build on it with gh workflow run.

To stop an update:

  • Close the PR to skip that version. It won't be reopened.
  • Add a hold label to wait. Create the label the first time you use it.
  • Push a commit to the branch, e.g. to fix the build. The bot then leaves the PR alone, and it needs merging by hand.

Worth knowing

  • This relies on Allow GitHub Actions to create and approve pull requests, which is already enabled.
  • Bot PRs may also show a pull_request run waiting for approval. It can be ignored, because the dispatched run is the one that counts.
  • New quick tunnel hostnames don't resolve reliably on the runners at first. So the smoke test waits for the first request to get through, then reuses that IP for the other requests.
  • The build on the update branch can only be dispatched once this is on main, because workflow_dispatch is read from the default branch.
  • GitHub disables scheduled workflows after 60 days without repository activity. Re-enable it from the Actions tab if that happens.
  • ALPINEVERSION is still bumped by hand. If a release needs a Go minor that has no image for the pinned Alpine, the updater fails and says so.
  • Go patch releases on their own don't open a PR. Go is bumped along with cloudflared releases.
  • The QEMU platforms are emulated, not real hardware. They catch build mistakes, wrong instruction sets and crashes, not hardware-specific issues.

Tested on GitHub's runners (in my fork)

  • Full flow, with the wait set to 0:
    1. The updater opened Upgrade cloudflared to 2026.10.2, Go to 1.27.3.
    2. It ran the matrix on that branch.
    3. A flaky job was retried automatically.
    4. Once green, the PR was squash-merged and the main build was started.
    5. That build stopped at Docker Hub login, because the fork has no token, so nothing was published.
  • The final version of the smoke tests passed 32/32 jobs across 4 full matrix runs.
  • The v7 binary on the emulated ARM1176 failed with Illegal instruction. So the CPU setting reaches QEMU on the runners, and the v6 check would catch a regression.

Tested locally

  • Ran the updater against a copy of main: 2026.8.2 → 2026.10.2, Go 1.26.6 → 1.27.3, Dockerfile default 1.26 → 1.27. A second run made no changes.
  • Built that with docker buildx bake (golang:1.27.3-alpine3.24) and the smoke test passed.
  • Ran every non-amd64 binary from the published 2026.8.2 image under QEMU 10.2.3. Each came up as a quick tunnel in about 10s and served every request.
  • Tested both workflow steps with a stubbed gh:
    • Opening the PR: new PR, updating a PR with only bot commits, already up to date, human commits, closed version, fork PR with the same branch name.
    • Merging: no PR, human commits, hold, no build, build running, failed (comments only once), passed but under 24h, passed and merged.

Copilot AI review requested due to automatic review settings March 9, 2026 17:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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/cloudflared release
  • Parses and updates the CLOUDFLARED_VERSION default value in docker-bake.hcl using awk
  • Opens a PR via peter-evans/create-pull-request if the version has changed

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

Comment thread .github/workflows/update-cloudflared-version.yml Outdated
Comment thread .github/workflows/update-cloudflared-version.yml Outdated
Comment thread .github/workflows/update-cloudflared-version.yml Outdated
@Erisa

Erisa commented Mar 9, 2026

Copy link
Copy Markdown
Owner

maybe make it just directly commit to main

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

@Erisa

Erisa commented Mar 9, 2026

Copy link
Copy Markdown
Owner

That testing could probably be automated nowadays though, I just don't feel like doing it myself. I build the image with docker bake, run it with --hello-world and then request the resulting tunnel URL several times to make sure it works.

@Hazmi35

Hazmi35 commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator Author

maybe make it just directly commit to main

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

I see, then keep with the PR approach

@Erisa
Erisa self-requested a review March 12, 2026 04:26
@Hazmi35 Hazmi35 changed the title Add updater workflow Automate cloudflared updates with multi-arch smoke tests Oct 21, 2026
Checks for new cloudflared releases every 6 hours and opens a pull request
bumping CLOUDFLARED_VERSION, plus GOVERSION when the release needs a newer Go.
Every platform is tested by running a hello world quick tunnel and requesting
it, and updates that pass are merged after 24 hours unless someone objects.
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