Distribute the activity script as a GitHub Action - #4
Merged
Merged
Conversation
Assisted-by: Claude <noreply@anthropic.com>
kasperg
force-pushed
the
distribute-action
branch
18 times, most recently
from
September 15, 2026 12:19
8f88a91 to
b5a0a3c
Compare
Consumer repositories run the action to create or update the script integration in their Upsun project and set GH_TOKEN and GH_REPO on it. Ownership is decided by a single rule: a script integration is ours only if it carries the UPSUN_GITHUB_ENV_SYNC_VERSION variable. The action never reads or changes integrations without it, so projects with other script integrations keep working and hand installs are never adopted. The variable doubles as a record of the installed release, read from package.json in the action checkout. On create it is written first so a failure later in the run leaves an integration the next run finds. All API calls go through `upsun api:curl`, which handles authentication. Creating through the API returns the new ID directly, so no list diffing is needed. The Upsun CLI is installed from the upsun/cli installer into a runner temp directory so the step does not depend on sudo. Assisted-by: Claude <noreply@anthropic.com>
The installer reads VERSION and falls back to the latest release when it is empty, so consumers can pin only when a CLI release breaks them. Assisted-by: Claude <noreply@anthropic.com>
Every push to main with a feat or fix commit creates a GitHub release and tag, updates CHANGELOG.md and package.json, and moves the floating major tag so consumers can pin either an exact tag or vN. Nothing is published to a registry: npmPublish is off and the package stays private. The npm plugin is kept only for the version bump, which the action reads back as the installed version. The release commit is pushed with a token that has bypass rights on the main ruleset, since the workflow token cannot be added to a bypass list. The version starts at 0.0.0 so the first release is 0.1.0. semantic- release derives versions from tags, so a v0.0.0 tag on main is needed before the first run, otherwise it starts at 1.0.0. Assisted-by: Claude <noreply@anthropic.com>
Assisted-by: Claude <noreply@anthropic.com>
Node 20 was chosen as the oldest LTS supporting ES2021, the level Upsun documents for activity scripts. Upsun does not document a Node version, and the script runs in a sandbox that is not Node: fetch is synchronous and the storage module exists only there. ES2021 compatibility is guarded by the es2021 target in the type check, not by the local Node version. Node 20 is end of life, and the release and commit lint tooling needs Node 22 or newer. Assisted-by: Claude <noreply@anthropic.com>
npm run lint:commits checks every commit between origin/main and HEAD with the same config as the pull request check, so a rejected message is found before the push. Assisted-by: Claude <noreply@anthropic.com>
semantic-release reads every commit that lands on main, so each pull request runs the same commitlint script that developers run locally. The commitlint version is pinned in package.json, so Dependabot keeps it current. Assisted-by: Claude <noreply@anthropic.com>
Nightly schedule so releases of the action roll out without a consumer commit, manual dispatch for first install and debugging, and push on the workflow path so a new consumer is installed on merge. Assisted-by: Claude <noreply@anthropic.com>
Replaces the manual CLI install instructions with the action-based install, documents the ownership rule, the version tags, the release process and the token expiry symptom. Assisted-by: Claude <noreply@anthropic.com>
Since activities lost their default commits, this test took the environment-name fallback for the ref. Use the push helper like the other push tests so it covers a failing POST after a successful head-commit lookup. Assisted-by: Claude <noreply@anthropic.com>
kasperg
force-pushed
the
distribute-action
branch
from
September 15, 2026 13:01
b5a0a3c to
8056cd9
Compare
|
🎉 This PR is included in version 0.1.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Distributes the activity script to Upsun projects through a composite GitHub Action instead of hand installs with the CLI.
Consumer repositories copy
examples/upsun-github-env-sync.yml. It runs the action weekly, on manual dispatch and when the workflow file changes. The action creates or updates a script integration in the Upsun project and setsGH_TOKEN,GH_REPOandUPSUN_GITHUB_ENV_SYNC_VERSIONon it. Ownership is decided by that version variable alone: integrations without it are never read or changed, and hand installs are not adopted. Creation and update go throughupsun api:curl, so the new integration ID comes back from the response.Releases are cut by semantic-release on push to
mainfrom conventional commits. Afeatorfixcommit creates a tag and a GitHub release and moves the floating major tag, so consumers on@v1pick up each release on their next nightly run. Nothing is published to a registry. CI lints every commit in a pull request, andnpm run lint:commitsdoes the same locally.Development moves to Node 24. Upsun documents ES2021 for activity scripts and no Node version, and the ES2021 target in the type check is what guards compatibility. Node 20 is end of life and the release tooling needs Node 22 or newer.
Verified locally:
npm run checkon Node 24, commitlint over all commits, actionlint over the three workflows, and a dry run of semantic-release in a throwaway clone. With thev0.0.0tag onmain, the first release from this branch is 0.1.0. The documentation already refers to@v1, which exists once 1.0.0 is released.Before merging:
uses: reload/upsun-github-env-sync@v1resolves from other repositories. The history contains no secrets.UPSUN_API_TOKENfrom the shared Reload Upsun API user.After merging, bupl is the first consumer: delete its hand-installed integration, add the example workflow, and run it once by hand. That run is the first real test of the create payload.