Skip to content

chore(react): Update dependency @types/react to ^19.2.18 #354

chore(react): Update dependency @types/react to ^19.2.18

chore(react): Update dependency @types/react to ^19.2.18 #354

Workflow file for this run

name: Release
on:
pull_request_target:
types: [closed]
branches: [main]
workflow_dispatch:
# Manual trigger — use when a publish needs to be retried without re-merging
# the release PR (e.g. after a partial failure where tags were already pushed).
# cancel-in-progress: false ensures an in-flight publish is never interrupted.
concurrency:
group: release
cancel-in-progress: false
env:
NX_DAEMON: false
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
LEFTHOOK: "0"
jobs:
# ─── BUILD AND PUBLISH ────────────────────────────────────────────────────────
# First job — runs when the release/next PR is merged into main.
# Uses pull_request_target so the trigger is based on the branch name
# (head.ref == 'release/next'), not a commit message — works correctly for
# regular merge commits, squash merges, and rebase merges alike.
#
# Authenticates to npm via OIDC (Trusted Publishing — no stored token needed).
# Builds all packages, publishes to npm with provenance, and sets the `latest`
# dist-tag on each package.
#
# Tags are intentionally NOT created here — they are pushed in the `tag` job
# only after a successful publish, so a failed publish never leaves orphaned
# git tags pointing at versions that don't exist in the registry.
#
# Downstream jobs are skipped automatically when this job is skipped or fails.
build-and-publish:
name: Build and Publish
runs-on: ubuntu-latest
timeout-minutes: 25
if: |
(github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'release/next') ||
github.event_name == 'workflow_dispatch'
permissions:
contents: read
id-token: write
steps:
- name: 📥 Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 1
- name: 💾 Cache git objects
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .git/objects
key: git-${{ runner.os }}-${{ github.sha }}
restore-keys: |
git-${{ runner.os }}-
- name: 🔧 Setup Node and install dependencies
uses: ./.github/actions/node-setup-and-install
- name: 🔐 Configure npm registry for OIDC
run: |
# Write ONLY the registry URL — no _authToken line so that npm uses
# the OIDC token (from id-token: write) instead of a static token.
cat >> .npmrc << 'EOF'
registry=https://registry.npmjs.org
EOF
- name: 💾 Cache build outputs
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
packages/*/dist
configs/*/dist
key: build-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ github.run_id }}
restore-keys: |
build-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-
build-${{ runner.os }}-
- name: 📤 Publish to npm
run: |
# Build packages first
pnpm nx run-many -t build
# Track failures
FAILED=""
# Publish each public package with provenance and public access.
# Already-published versions are skipped so workflow_dispatch retries
# don't fail on packages that succeeded in a previous run.
for pkg_json in packages/*/package.json configs/*/package.json; do
private=$(jq -r '.private // false' "$pkg_json")
[ "$private" = "false" ] || continue
pkg_dir=$(dirname "$pkg_json")
name=$(jq -r '.name' "$pkg_json")
version=$(jq -r '.version' "$pkg_json")
if npm view "${name}@${version}" version 2>/dev/null | grep -qx "${version}"; then
echo "⏭️ Already published ${name}@${version} — skipping"
continue
fi
echo "Publishing ${name}@${version}..."
cd "$pkg_dir"
if ! npm publish --provenance --access public; then
echo "❌ Failed to publish $pkg_dir"
FAILED="$FAILED $pkg_dir"
else
echo "✅ Successfully published $pkg_dir"
fi
cd - > /dev/null
done
# Fail if any package failed to publish
if [ -n "$FAILED" ]; then
echo "::error::The following packages failed to publish:$FAILED"
exit 1
fi
# Runs after publish so dist-tags are only updated once the new versions
# are confirmed live in the registry. Moving this before publish would
# point `latest` at a version that may not exist if publish fails.
- name: 🏷️ Ensure latest dist-tag is set for all packages
run: |
for pkg_json in packages/*/package.json configs/*/package.json; do
private=$(jq -r '.private // false' "$pkg_json")
[ "$private" = "false" ] || continue
name=$(jq -r '.name' "$pkg_json")
version=$(jq -r '.version' "$pkg_json")
npm dist-tag add "${name}@${version}" latest 2>/dev/null \
&& echo "✅ Set latest tag: ${name}@${version}" \
|| echo "⚠️ Skipped (not yet published): ${name}@${version}"
done
# ─── TAG ──────────────────────────────────────────────────────────────────────
# Runs only after build-and-publish succeeds — guarantees that every pushed
# tag has a corresponding published version in the registry. A failed publish
# therefore never leaves orphaned tags that would corrupt future release windows
# or confuse `nx release` version anchoring.
#
# Safe to re-run: the tagging step skips tags that already exist.
tag:
name: Create and Push Git Tags
needs: build-and-publish
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- name: 📥 Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- name: 💾 Cache git objects
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .git/objects
key: git-${{ runner.os }}-${{ github.sha }}
restore-keys: |
git-${{ runner.os }}-
- name: 🏷️ Fetch all tags
run: git fetch --tags --force
- name: 🎯 Create and push git tags
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
for pkg_json in packages/*/package.json configs/*/package.json; do
private=$(jq -r '.private // false' "$pkg_json")
[ "$private" = "false" ] || continue
name=$(jq -r '.name' "$pkg_json")
version=$(jq -r '.version' "$pkg_json")
tag="${name}@${version}"
if git rev-parse "$tag" >/dev/null 2>&1; then
echo "Tag already exists: $tag (skipping)"
else
git tag -a "$tag" -m "$tag"
echo "Created tag: $tag"
fi
done
git push origin --tags
# ─── GITHUB RELEASES ──────────────────────────────────────────────────────────
# Creates one GitHub Release per package using the CHANGELOG.md section for
# the current version as release notes.
#
# Runs on ubuntu-latest — only needs gh CLI and the repo checkout, no fe-runner.
# Safe to re-run after a partial failure: skips releases that already exist.
# Skipped automatically if tag was skipped or failed.
github-releases:
name: Create GitHub Releases
needs: tag
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: 📥 Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 1
# gh is pre-installed on ubuntu-latest — no setup step needed.
# Creates a GitHub Release per package, using the CHANGELOG.md section for
# the current version as the release notes. Skipped for packages whose
# release already exists (safe to re-run after a partial failure).
- name: 🎉 Create GitHub Releases
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
for pkg_json in packages/*/package.json configs/*/package.json; do
private=$(jq -r '.private // false' "$pkg_json")
[ "$private" = "false" ] || continue
name=$(jq -r '.name' "$pkg_json")
version=$(jq -r '.version' "$pkg_json")
tag="${name}@${version}"
pkg_dir=$(dirname "$pkg_json")
if gh release view "$tag" --repo "$REPO" >/dev/null 2>&1; then
echo "GitHub Release already exists for $tag — skipping"
continue
fi
# Extract the changelog section for this version: everything between
# "## {version}" and the next "## " header.
changelog_file="${pkg_dir}/CHANGELOG.md"
notes=""
if [ -f "$changelog_file" ]; then
notes=$(awk -v ver="${version}" \
'substr($0, 1, length("## " ver)) == ("## " ver) { flag=1; next }
/^## / { if (flag) exit }
flag { print }' \
"$changelog_file")
fi
printf '%s\n' "${notes:-"No changelog available."}" > /tmp/release-notes.txt
gh release create "$tag" \
--repo "$REPO" \
--title "$tag" \
--notes-file /tmp/release-notes.txt
echo "Created GitHub Release: $tag"
done