Reusable composite actions for ArcBox Labs CI pipelines.
Publishes a directory of CDN artifacts to a Cloudflare R2 bucket over its S3
endpoint (the buckets behind *.arcboxcdn.com, each served at its R2 custom
domain). Every ArcBox CDN publisher — boot-assets, machine-images,
arcbox-desktop, arctap, the fleet-agent release — goes through this action.
Contract:
- Immutable content first, index last. Every object except the declared
index-filesis uploaded with a one-year immutableCache-Control; the index files are uploaded afterwards with a 60-second TTL. A reader that follows a fresh index therefore always finds its blobs already live. - Keys must be content-unique. Cloudflare caches immutable objects for a
long time and
rclone copyskips objects whose size+mtime match. Never reuse a key for different bytes — put a version in the path instead. - Credentials are an R2 API token with Object Read & Write scoped to the destination bucket(s); the S3 endpoint is derived from the account ID.
- Runs on Linux runners only (rclone is installed from its
.deb). A job that must run on macOS, e.g. to sign with Sparkle, stages its files, uploads them as an artifact, and publishes from a Linux job.
- uses: arcboxlabs/actions/r2-publish@v2
with:
account-id: ${{ vars.R2_ACCOUNT_ID }}
access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
bucket: arcboxcdn-image
source-dir: dist
destination: linux
index-files: index.json
verify-urls: |
https://image.arcboxcdn.com/linux/index.jsonInputs (see r2-publish/action.yml for the full list):
| Input | Description |
|---|---|
account-id |
Cloudflare account ID (repo variable R2_ACCOUNT_ID) |
access-key-id, secret-access-key |
R2 S3 credentials (repo secrets R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY) |
bucket |
Destination bucket |
source-dir |
Local directory to publish |
destination |
Key prefix inside the bucket (namespace, e.g. linux) |
index-files |
Newline-separated mutable pointers, uploaded last |
verify-urls |
Newline-separated URLs checked for HTTP 200 afterwards |
strict-verify |
true fails on a non-200 verify instead of warning |
Consumer repositories share one naming convention so a token rotation is a
single sweep: variable R2_ACCOUNT_ID, secrets R2_ACCESS_KEY_ID and
R2_SECRET_ACCESS_KEY.
Reusable workflow (.github/workflows/fast-forward.yml) that fast-forwards a PR's
head onto its base when someone comments /fast-forward or /ff — commit SHAs
and their GPG/SSH signatures survive untouched, unlike "Rebase and merge". Gating
follows each repository's own rulesets; nothing is redefined here.
Setup and operations: docs/fast-forward.md
Consumers pin a major tag (arcboxlabs/actions/r2-publish@v2). The tag moves
forward on backward-compatible changes; breaking input changes get a new major.
v1 stays on the last b2-publish commit; v2 is the R2 publisher, whose
inputs are not compatible with it.