Skip to content
Open
13 changes: 12 additions & 1 deletion .github/actions/artifacts/action.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
name: 'Frontend Artifacts Handler Action'
description: 'Github Action to handle frontend artifacts'
outputs:
tag:
description: 'The pushed version tag, set only once the version is published and tagged (release flow only)'
value: ${{ steps.handler.outputs.tag }}
previous_tag:
description: 'The previous tag of the same release line, empty for X.Y.1 (release flow only)'
value: ${{ steps.handler.outputs.previous_tag }}
is_latest:
description: 'true if the pushed tag is the highest version/* tag (release flow only)'
value: ${{ steps.handler.outputs.is_latest }}
runs:
using: 'composite'
steps:
- run: printenv
shell: bash
- run: cd "$GITHUB_ACTION_PATH/../../.." && pwd && npm ci
shell: bash
- run: npx ts-node "$GITHUB_ACTION_PATH/../../../tools/scripts/artifacts/main.ts"
- id: handler
run: npx ts-node "$GITHUB_ACTION_PATH/../../../tools/scripts/artifacts/main.ts"
shell: bash
5 changes: 5 additions & 0 deletions .github/workflow-templates/fe/fe-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ permissions:
actions: read
checks: write

# a new push to the branch cancels the run of the previous one
concurrency:
group: fe-main-${{ github.ref }}
cancel-in-progress: true

env:
NX_BRANCH: ${{ github.event.number }}
NX_RUN_GROUP: ${{ github.run_id }}
Expand Down
5 changes: 5 additions & 0 deletions .github/workflow-templates/fe/fe-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ permissions:
actions: read
checks: write

# a new push to the PR cancels the run of the previous one
concurrency:
group: fe-pr-${{ github.event.pull_request.number }}
cancel-in-progress: true

env:
NX_BRANCH: ${{ github.event.number }}
NX_RUN_GROUP: ${{ github.run_id }}
Expand Down
61 changes: 20 additions & 41 deletions .github/workflow-templates/fe/fe-release.yml
Original file line number Diff line number Diff line change
@@ -1,53 +1,32 @@
# Replaces the old two-file release (this file as tagger + fe-tag-pushed.yml / on_tag_pushed.yaml / tag_pushed.yml).
Comment thread
Benno42 marked this conversation as resolved.
Resolved
# Delete BOTH old caller files in the same commit that adds this one: the release flow still pushes
# the tag with the PAT, so a tag-push workflow left in the tree would publish that tag again (and
# release manually pushed tags). The release flow's guard job fails while an old caller exists.
# PFM-ISSUE-34282 (pushing the tag with GITHUB_TOKEN) removes the tag-push trigger for good.
name: 'Frontend Release CI'
on:
push:
branches:
- 'release/*'
workflow_dispatch:
inputs:
force:
description: 'Tag and publish (release/*) or publish a snapshot of all projects (default branch). Unticked: build and test only, nothing is tagged or published.'
type: boolean
default: false

permissions:
contents: write
pull-requests: write
actions: read
checks: write

env:
NX_BRANCH: ${{ github.event.number }}
NX_RUN_GROUP: ${{ github.run_id }}
# one release run per branch at a time; a running release is never cancelled
concurrency:
group: fe-release-${{ github.ref }}
cancel-in-progress: false

jobs:
install-deps:
uses: collaborationFactory/github-actions/.github/workflows/fe-install-deps.yml@master
release-flow:
uses: collaborationFactory/github-actions/.github/workflows/fe-release-flow.yml@master
with:
GHA_REF: ''
secrets:
DOT_NPMRC: ${{ secrets.DOT_NPMRC }}

e2e-tests:
needs: install-deps
uses: collaborationFactory/github-actions/.github/workflows/fe-e2e.yml@master
with:
GHA_REF: ''
GHA_BASE: ${{ github.event.before }}
secrets:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

build:
needs: install-deps
uses: collaborationFactory/github-actions/.github/workflows/fe-build.yml@master
with:
GHA_REF: ''
GHA_BASE: ${{ github.event.before }}

tag:
needs: [build, e2e-tests]
uses: collaborationFactory/github-actions/.github/workflows/fe-tag.yml@master
with:
GHA_REF: ''
GHA_BASE: ${{ github.event.before }}
secrets:
JFROG_BASE64_TOKEN: ${{ secrets.JFROG_BASE64_TOKEN }}
JFROG_URL: ${{ secrets.JFROG_URL }}
JFROG_USER: ${{ secrets.JFROG_USER }}
GIT_USER_TOKEN: ${{ secrets.GIT_USER_TOKEN }}
GIT_USER: ${{ secrets.GIT_USER }}
GIT_USER_EMAIL: ${{ secrets.GIT_USER_EMAIL }}
FORCE: ${{ inputs.force == true }}
# RUN_E2E: false # only for repos that do not run e2e before a release
secrets: inherit
24 changes: 0 additions & 24 deletions .github/workflow-templates/fe/fe-tag-pushed.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .github/workflows/fe-install-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ on:
jobs:
install-deps:
runs-on: ubuntu-latest
Comment thread
Benno42 marked this conversation as resolved.
Resolved
concurrency:
group: fe-install-deps-${{ github.ref }}
cancel-in-progress: true
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
Expand Down
212 changes: 212 additions & 0 deletions .github/workflows/fe-release-flow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
name: Frontend Release Flow Workflow

on:
workflow_call:
inputs:
FORCE:
description: 'release/*: release even if no project is affected. Default branch: publish a snapshot of all projects. false: build and test only.'
type: boolean
required: false
default: false
RUN_E2E:
type: boolean
required: false
default: true
secrets:
JFROG_BASE64_TOKEN:
required: true
JFROG_URL:
required: true
JFROG_USER:
required: true
DOT_NPMRC:
required: true
GIT_USER_TOKEN:
required: true
GIT_USER:
required: true
GIT_USER_EMAIL:
required: true
PERCY_TOKEN:
required: false

env:
NX_BRANCH: ${{ github.event.number }}
NX_RUN_GROUP: ${{ github.run_id }}

jobs:
guard:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Check dispatch ref
env:
EVENT_NAME: ${{ github.event_name }}
REF: ${{ github.ref }}
DEFAULT_REF: refs/heads/${{ github.event.repository.default_branch }}
run: |
if [ "$EVENT_NAME" = "workflow_dispatch" ] && [ "$REF" != "$DEFAULT_REF" ] && [[ "$REF" != refs/heads/release/* ]]; then
echo "::error::The release flow can only be dispatched on the default branch or a release/* branch, not on $REF"
exit 1
fi

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
sparse-checkout: .github/workflows
persist-credentials: false

# an old tag-push caller would publish manually pushed tags and fail on the tags of this flow
- name: Check for old release callers
run: |
old=$(grep -lE 'github-actions/\.github/workflows/(fe-release|fe-tag)\.yml@' .github/workflows/*.y*ml 2> /dev/null || true)
if [ -n "$old" ]; then
echo "::error::Old release callers found: $(echo $old). Delete them in the same commit that adds the fe-release-flow caller (see 'FE Release Flow' in the github-actions README)."
exit 1
fi

install-deps:
needs: guard
permissions:
contents: read
uses: collaborationFactory/github-actions/.github/workflows/fe-install-deps.yml@master
with:
GHA_REF: ''
secrets:
DOT_NPMRC: ${{ secrets.DOT_NPMRC }}

build:
needs: install-deps
permissions:
contents: read
uses: collaborationFactory/github-actions/.github/workflows/fe-build.yml@master
with:
GHA_REF: ''
GHA_BASE: ${{ github.event.before }}

e2e:
needs: install-deps
if: inputs.RUN_E2E
permissions:
contents: read
uses: collaborationFactory/github-actions/.github/workflows/fe-e2e.yml@master
with:
GHA_REF: ''
GHA_BASE: ${{ github.event.before }}
secrets:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

release:
needs: [build, e2e]
# a skipped e2e (RUN_E2E: false) must not skip the release; a non-forced dispatch is a dry run
if: >-
!cancelled()
&& needs.build.result == 'success'
&& (needs.e2e.result == 'success' || needs.e2e.result == 'skipped')
&& (github.event_name == 'push' || inputs.FORCE)
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
tag: ${{ steps.release.outputs.tag }}
previous_tag: ${{ steps.release.outputs.previous_tag }}
is_latest: ${{ steps.release.outputs.is_latest }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ''
fetch-depth: 0
token: ${{ secrets.GIT_USER_TOKEN }}

- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24.20.0

- name: Cache Node Modules
id: npm-cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}

- name: Use .npmrc
uses: collaborationFactory/github-actions/.github/actions/use-npmrc@master
with:
dot-npmrc: ${{ secrets.DOT_NPMRC }}

- name: Install Modules
if: steps.npm-cache.outputs.cache-hit != 'true'
run: npm ci

- name: Configure git user
env:
GIT_USER: ${{ secrets.GIT_USER }}
GIT_USER_EMAIL: ${{ secrets.GIT_USER_EMAIL }}
run: |
git config user.name "$GIT_USER"
git config user.email "$GIT_USER_EMAIL"

- name: Publish to Jfrog NPM Registry and Tag
id: release
uses: collaborationFactory/github-actions/.github/actions/artifacts@master
env:
JFROG_BASE64_TOKEN: ${{ secrets.JFROG_BASE64_TOKEN }}
JFROG_URL: ${{ secrets.JFROG_URL }}
JFROG_USER: ${{ secrets.JFROG_USER }}
RELEASE_FLOW: true
FORCE: ${{ inputs.FORCE }}

# the release step writes the version before publishing; once the tag is pushed
# the release is complete and must not be unpublished
- name: Check for an incomplete release
id: incomplete
if: failure() || cancelled()
run: |
file="$RUNNER_TEMP/fe-release-version"
if [ ! -f "$file" ]; then
echo "Publishing did not start, nothing to clean up"
exit 0
fi
tag=$(cat "$file")
if git ls-remote --exit-code --tags origin "refs/tags/$tag" > /dev/null; then
echo "$tag is already pushed, the release is complete: nothing to clean up"
exit 0
fi
echo "$tag was not pushed: unpublishing its artifacts"
echo "tag=$tag" >> "$GITHUB_OUTPUT"

- name: Unpublish the incomplete release
if: (failure() || cancelled()) && steps.incomplete.outputs.tag != ''
uses: collaborationFactory/github-actions/.github/actions/artifacts@master
env:
JFROG_BASE64_TOKEN: ${{ secrets.JFROG_BASE64_TOKEN }}
JFROG_URL: ${{ secrets.JFROG_URL }}
JFROG_USER: ${{ secrets.JFROG_USER }}
ONLY_DELETE_ARTIFACTS: true
TAG: ${{ steps.incomplete.outputs.tag }}

github-release:
needs: release
# the tag is set only once the version is published and tagged
if: needs.release.outputs.tag != ''
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG: ${{ needs.release.outputs.tag }}
PREVIOUS_TAG: ${{ needs.release.outputs.previous_tag }}
IS_LATEST: ${{ needs.release.outputs.is_latest }}
run: |
if gh release view "$TAG" > /dev/null 2>&1; then
echo "A GitHub release for $TAG already exists, nothing to do"
exit 0
fi
args=(--verify-tag --generate-notes "--latest=$IS_LATEST")
if [ -n "$PREVIOUS_TAG" ]; then
args+=(--notes-start-tag "$PREVIOUS_TAG")
fi
gh release create "$TAG" "${args[@]}"
3 changes: 3 additions & 0 deletions .github/workflows/fe-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
release-version:
runs-on: ubuntu-latest
steps:
- name: Deprecation notice
run: echo "::warning::fe-release.yml (tag push) is deprecated. Migrate to fe-release-flow.yml, see 'FE Release Flow' in the github-actions README."

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ''
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/fe-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ jobs:
tag:
runs-on: ubuntu-latest
steps:
- name: Deprecation notice
run: echo "::warning::fe-tag.yml is deprecated. Migrate to fe-release-flow.yml, see 'FE Release Flow' in the github-actions README."

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ inputs.GHA_REF }}
Expand Down
Loading