Skip to content

PFM-ISSUE-34283 - Consolidate the FE 2.0 release flow into a single workflow - #183

Open
vladimir-arsov wants to merge 3 commits into
masterfrom
improvement/PFM-ISSUE-34283-Consolidate-the-FE-2-0-release-flow-into-a-master
Open

vladimir-arsov wants to merge 3 commits into
masterfrom
improvement/PFM-ISSUE-34283-Consolidate-the-FE-2-0-release-flow-into-a-master

Conversation

@vladimir-arsov

Copy link
Copy Markdown
Contributor

Summary

Replaces the two-run FE 2.0 release (branch push → fe-tag.yml pushes a tag → tag push → fe-release.yml publishes) with one run per push to release/* or manual dispatch:

guard → install-deps → build ∥ e2e → release (tag + publish, one job) → GitHub release

Ticket: PFM-ISSUE-34283

Changes

  • .github/workflows/fe-release-flow.yml (new reusable workflow)
    • inputs FORCE and RUN_E2E
    • a guard job that fails a dispatch on any ref other than the default branch or release/*
    • a release job that tags and publishes
    • a github-release job that uses GITHUB_TOKEN, sets the notes range from the previous tag of the line, and marks "Latest" only on the highest version/* tag
  • Artifacts tool gets a RELEASE_FLOW mode. It computes the next version, then checks for affected projects since the previous tag of the line (skipped when FORCE is set or for X.Y.1). It then pushes the tag and publishes all projects at that version.
    • Outputs: released, tag, previous_tag and is_latest, exposed through the composite action.
    • A forced dispatch on the default branch publishes a snapshot of all projects.
    • The [branch-off] guard still runs first.
  • run-many turns an empty or undefined ref into '', so GHA_REF: '' selects all projects again. This was the original intent: pushes to main and release branches build all projects, PRs build only the affected ones.
  • fe-install-deps.yml loses its job-level cancel-in-progress concurrency. The new caller has its own run-level, non-cancelling concurrency instead.
  • Caller template fe-release.yml is replaced: push to release/*, plus workflow_dispatch with force, plus secrets: inherit. The fe-tag-pushed.yml template is deleted.
  • README gets an "FE Release Flow" section: migration (including the double-publish warning), triggers and force, secrets, recovery, concurrency.

Behavior notes

  • Every push runs the flow, upmerges included, as in the backend repos. Only [branch-off] commits are never tagged or published.
  • Recovery after a failed publish is a forced dispatch. A re-run finds nothing affected since the tag it already pushed.
  • Re-running a successful forced dispatch cuts another patch. The README warns about this.

Not in scope

  • A version/* tag ruleset, a tag-triggered recovery path, and skip-if-exists or resumable publish.
  • Pushing the tag with GITHUB_TOKEN (34282), immutable releases (34284), retiring GIT_USER* (34286).
  • Changes to fe-tag.yml / workflows/fe-release.yml. Unmigrated callers keep the old flow.
  • Migrating consumer repos (pilot PFM-ISSUE-34287).
  • Master only: release lines 25.4–26.4 don't get the new workflow. The first line with it is the next branch-off.

Verification

  • jest: new affected-projects, artifacts-handler-release-flow (including [branch-off] over force) and utils tests pass. The only failures are the 5 known Windows path-separator tests, which also fail on master.
  • tsc --noEmit is clean.
  • actionlint is clean on the new and changed workflows and the caller template. A copy with the reusable refs rewritten to local paths is also clean, which checks the nested inputs and secrets.
  • Live validation is still pending and will be done manually on a throwaway release/99.x line (see plan.md, "Manual Testing Steps").

🤖 Generated with Claude Code

vladimir-arsov and others added 2 commits October 20, 2026 11:58
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…orkflow

- Add fe-release-flow.yml: guard -> install-deps -> build || e2e -> release (tag + publish) -> GitHub release in one run
- Artifacts tool: RELEASE_FLOW mode with FORCE; affected check since the previous tag of the line; outputs released/tag/previous_tag/is_latest
- run-many: normalize an empty/undefined ref so GHA_REF '' selects all projects
- Remove the cancelling concurrency from fe-install-deps.yml
- Replace the fe-release caller template (push release/* + dispatch force), delete fe-tag-pushed template
- Document the flow in the README

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@Benno42 Benno42 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great! Clear flow, and the tests pass locally. Live validation is still open. maybe we can test it before merging.

} else {
// affected since the previous release of the line, not since the pushed range:
// a push whose queued run was cancelled must not be missed
this.base = previousTag;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❓After a failed publish, "Re-run failed jobs" finds nothing affected and ends green without publishing, but design.md and plan.md promise a release. Is this intended, or should the run fail when the latest tag has no published artifact? 🤖

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, confirmed: with the previous tag as base, the dangling tag became the base and the re-run found nothing. Fixed by switching to publish before tag:

  • the tool writes the version to $RUNNER_TEMP before publishing, publishes all projects, then pushes the tag
  • a new cleanup step in the release job (failure() || cancelled()) unpublishes that version via the existing ONLY_DELETE_ARTIFACTS + TAG mode, unless the tag is already on the remote
  • the constructor-ordering bug is fixed so TAG on a release/* branch keeps its own version (needed for the cleanup)

Result: a version/* tag always means a complete release, and "Re-run failed jobs" (or the next push) releases the same version. design.md, plan.md and the README are updated accordingly.

Comment thread .github/workflow-templates/fe/fe-release.yml
Comment thread .github/workflows/fe-install-deps.yml
Comment thread tools/scripts/run-many/run-many.ts
Comment thread .github/workflows/fe-release-flow.yml Outdated
Comment thread tools/scripts/artifacts/artifacts-handler-release-flow.test.ts Outdated
Comment thread README.md Outdated
Comment thread .github/workflows/fe-release-flow.yml Outdated
Comment thread tools/scripts/artifacts/artifacts-handler.ts Outdated
Comment thread specs/2026-10-12_PFM-ISSUE-34283_consolidate-fe-release-workflow/design.md Outdated
…, caller concurrency

- Publish first, then tag; a failed or cancelled release is unpublished by a cleanup step (ONLY_DELETE_ARTIFACTS + TAG), so a re-run releases the same version
- Fix the constructor ordering: a TAG on a release branch keeps its own version
- Guard fails while old fe-release/fe-tag callers exist; deprecation warnings in fe-tag.yml and workflows/fe-release.yml; link PFM-ISSUE-34282
- Concurrency moves to the caller templates (fe-pr, fe-main); README migration steps
- Release job: plain npm ci, git identity via env, drop the redundant released output
- calculateNewVersion returns a new Version instead of mutating the tag list
- README recovery and design.md aligned (publish before tag, master only)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@Benno42 Benno42 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: In Review The PR is currently being reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants