chore: merge-sync-to-experimental publish afterwards - #483
Conversation
Test this pull request
|
decentraland-bot
left a comment
There was a problem hiding this comment.
Review — PR #483: chore: merge-sync-to-experimental publish afterwards
Summary
This PR solves a real and well-understood problem: GITHUB_TOKEN-pushed merges to experimental don't trigger the build-deploy workflow, so @dcl/protocol@experimental silently falls behind the branch. The fix is clean — add a workflow_dispatch trigger to build-and-publish.yml and dispatch it from the merge-sync workflow after a successful push.
Analysis
Correctness ✅
workflow_dispatchwith--ref experimentalcorrectly setsgithub.ref_nametoexperimental, so theBRANCH_TAGenv var resolves as expected andoddish-actionpublishes with theexperimentalnpm tag.- The step-output signal (
echo "pushed=true" >> "$GITHUB_OUTPUT") and conditional (if: steps.merge.outputs.pushed == 'true') are idiomatic and correctly gate the dispatch — no-op and merge-failure paths never reach the output line. - The
notify_deploymentjob inbuild-and-publish.ymlgates ongithub.event.pull_request.number, which is empty forworkflow_dispatchevents — so it correctly skips (no notification noise).
Retry logic ✅
- 5 attempts × 5s sleep is reasonable for GitHub's ref-indexing delay. The comment explains the race correctly: the merge push may be what first places the
workflow_dispatchtrigger onexperimental, and GitHub needs a moment to index it.
Error handling ✅
- If dispatch fails after all retries, the step exits 1 with a
::error::annotation and a clear recovery path ("run build-deploy manually"). The merge itself is already pushed, so only the publish is lost — correct tradeoff. - The
set -euo pipefailat the top of the Publish step is good practice.
No double-publish risk ✅
- The whole point is that
GITHUB_TOKENpushes don't trigger workflows, so there's no push-triggered run to race with the dispatched one.
Permissions ✅
actions: writeis the minimum scope needed forgh workflow run. It does also grant cancel/cache powers on the repo token, but the incremental risk over the existingcontents: writeis negligible.
ADR-6 compliance ✅
- PR title:
chore: merge-sync-to-experimental publish afterwards— valid<type>: <summary>format. - Branch:
chore/sync-main-to-experimental-publish-afterwards— valid<type>/<summary>pattern.
Consumer impact: Not applicable — only CI workflow files are changed, no public API surface is modified.
Suggestions (P2 — non-blocking)
-
[P2] Consider adding a branch guard to
workflow_dispatchinbuild-and-publish.yml.
Sinceworkflow_dispatchaccepts any ref and the workflow runs with npm/S3/GitLab credentials, a collaborator could dispatch it against an arbitrary branch to publish modified code as a snapshot package. Adding a job-level guard would limit exposure:jobs: check_and_build: if: >- github.event_name != 'workflow_dispatch' || github.ref_name == 'main' || github.ref_name == 'experimental'
This is defense-in-depth — the blast radius is limited to snapshot tags (not
latest), and only write-access collaborators can dispatch. Not blocking, but good hygiene for a workflow with publish credentials. -
[P2] Pre-existing: no concurrency group on
build-and-publish.yml.
If a manual dispatch and an automated dispatch overlap (unlikely but possible), two builds could publish concurrently. A concurrency group keyed ongithub.refwould serialize them. Not introduced by this PR, just noted.
Security Review
- No expression injection: the new
run:block contains only hardcoded strings — no${{ }}interpolation of untrusted inputs. - No script injection: no attacker-controlled data (PR title, branch name, issue body) flows into any shell command.
- No secrets exposure:
GITHUB_TOKENis passed viaenv:, not interpolated in shell. - The
actions: writepermission scope is appropriate for the dispatch use case. - No new secrets or credentials introduced.
No security issues found.
Verdict: ✅ APPROVE
The PR is well-designed, correctly solves the problem, and the code is clear. The two P2 suggestions are hardening improvements for a future pass — nothing blocks merge.
Reviewed by Jarvis 🤖 · Requested by Pravus (<@UDJQDQC0Z>) via Slack
| on: | ||
| # An extra entry point; the push trigger below is unchanged. For workflows like | ||
| # merge-sync-to-experimental.yml, whose merge is pushed with GITHUB_TOKEN: GitHub | ||
| # starts no workflow from that token's events, and workflow_dispatch is the exception. |
There was a problem hiding this comment.
[P2] Consider adding a job-level branch guard so workflow_dispatch can only publish from main or experimental:
jobs:
check_and_build:
if: >-
github.event_name != 'workflow_dispatch'
|| github.ref_name == 'main'
|| github.ref_name == 'experimental'This is defense-in-depth — only write-access collaborators can dispatch, and non-main/experimental publishes produce snapshot tags. But the workflow runs with npm/S3/GitLab credentials, so restricting the dispatch surface is good hygiene.
Added
merge-sync-to-experimental.ymlworkflow last step to triggerbuild-and-publish.ymlworkflow otherwise@dcl/protocol@experimentaldoesn't get auto-released.