Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 42 additions & 55 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Prepare Nucleus Release

on:
push:
pull_request:
types: [closed]
branches: [main]
workflow_dispatch:
inputs:
Expand All @@ -24,7 +25,18 @@ permissions:

jobs:
prepare-release:
if: github.ref == 'refs/heads/main'
if: >-
(github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
(
github.event_name == 'pull_request' &&
github.event.pull_request.merged == true &&
!startsWith(github.event.pull_request.head.ref, 'release/v') &&
(
contains(github.event.pull_request.labels.*.name, 'major') ||
contains(github.event.pull_request.labels.*.name, 'minor') ||
contains(github.event.pull_request.labels.*.name, 'patch')
)
)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
Expand All @@ -34,10 +46,9 @@ jobs:
- name: Plan release PR
id: plan
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MANUAL_BUMP: ${{ inputs.bump }}
MERGE_SHA: ${{ github.sha }}
REPOSITORY: ${{ github.repository }}
MANUAL_BUMP: ${{ github.event.inputs.bump || '' }}
PR_NUMBER: ${{ github.event.pull_request.number || '' }}
PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
git fetch origin main --tags
git checkout -B main origin/main
Expand All @@ -62,69 +73,45 @@ jobs:
git rev-parse "$VERSION_TAG" >/dev/null 2>&1
}

set_output() {
echo "$1=$2" >> "$GITHUB_OUTPUT"
}

CURRENT_VERSION=$(tr -d '[:space:]' < VERSION)
PREVIOUS_VERSION="v${CURRENT_VERSION}"
echo "previous_version=$PREVIOUS_VERSION" >> "$GITHUB_OUTPUT"
set_output "previous_version" "$PREVIOUS_VERSION"

if [ -n "$MANUAL_BUMP" ]; then
NEXT_VERSION=$(next_version "$CURRENT_VERSION" "$MANUAL_BUMP")
VERSION_TAG="v${NEXT_VERSION}"
if release_exists "$VERSION_TAG"; then
echo "Tag $VERSION_TAG already exists. Skipping release preparation."
echo "action=skip" >> "$GITHUB_OUTPUT"
BUMP="$MANUAL_BUMP"
SOURCE="manual"
SOURCE_PR=""
else
RELEASE_LABELS=$(echo "$PR_LABELS" | jq -r '
map(select(. == "major" or . == "minor" or . == "patch"))
')
RELEASE_LABEL_COUNT=$(echo "$RELEASE_LABELS" | jq 'length')
BUMP=$(echo "$RELEASE_LABELS" | jq -r '.[0] // empty')
SOURCE="pr"
SOURCE_PR="$PR_NUMBER"

if [ "$RELEASE_LABEL_COUNT" -ne 1 ]; then
echo "Expected exactly one release label, found $RELEASE_LABEL_COUNT. Skipping release preparation."
set_output "action" "skip"
exit 0
fi
echo "action=create_pr" >> "$GITHUB_OUTPUT"
echo "version=$VERSION_TAG" >> "$GITHUB_OUTPUT"
echo "source=manual" >> "$GITHUB_OUTPUT"
exit 0
fi

PR_JSON=$(gh api \
-H "Accept: application/vnd.github+json" \
"/repos/$REPOSITORY/commits/$MERGE_SHA/pulls" \
--jq 'map(select(.merged_at != null)) | .[0]')

if [ "$PR_JSON" = "null" ] || [ -z "$PR_JSON" ]; then
echo "No merged PR found for $MERGE_SHA. Skipping release preparation."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

HEAD_REF=$(echo "$PR_JSON" | jq -r '.head.ref')
PR_NUMBER=$(echo "$PR_JSON" | jq -r '.number')

if [[ "$HEAD_REF" == release/v* ]]; then
echo "Release PR merge detected from $HEAD_REF. Skipping release preparation."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

BUMP=$(echo "$PR_JSON" | jq -r '
.labels
| map(.name)
| map(select(. == "major" or . == "minor" or . == "patch"))
| first
// empty
')

if [ -z "$BUMP" ]; then
echo "No release label on merged PR. Skipping release preparation."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

NEXT_VERSION=$(next_version "$CURRENT_VERSION" "$BUMP")
VERSION_TAG="v${NEXT_VERSION}"
if release_exists "$VERSION_TAG"; then
echo "Tag $VERSION_TAG already exists. Skipping release preparation."
echo "action=skip" >> "$GITHUB_OUTPUT"
set_output "action" "skip"
exit 0
fi
echo "action=create_pr" >> "$GITHUB_OUTPUT"
echo "version=$VERSION_TAG" >> "$GITHUB_OUTPUT"
echo "source=pr" >> "$GITHUB_OUTPUT"
echo "source_pr=$PR_NUMBER" >> "$GITHUB_OUTPUT"
set_output "action" "create_pr"
set_output "version" "$VERSION_TAG"
set_output "source" "$SOURCE"
set_output "source_pr" "$SOURCE_PR"

- uses: actions/setup-node@v5
if: steps.plan.outputs.action == 'create_pr'
Expand Down
73 changes: 11 additions & 62 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
name: Publish Nucleus Release

on:
push:
pull_request:
types: [closed]
branches: [main]
workflow_dispatch:
inputs:
merge_sha:
description: Release merge commit SHA to publish. Defaults to the triggering commit on push.
required: false
type: string

concurrency:
group: publish-release-main
Expand All @@ -20,7 +15,9 @@ permissions:

jobs:
release:
if: github.ref == 'refs/heads/main'
if: >-
github.event.pull_request.merged == true &&
startsWith(github.event.pull_request.head.ref, 'release/v')
runs-on: ubuntu-latest
outputs:
version: ${{ steps.plan.outputs.version }}
Expand All @@ -34,67 +31,19 @@ jobs:
- name: Detect merged release PR
id: plan
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MERGE_SHA: ${{ github.event.inputs.merge_sha || github.sha }}
REPOSITORY: ${{ github.repository }}
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
run: |
git fetch origin main --tags
git checkout -B main origin/main

resolve_pr_from_commit() {
gh api \
-H "Accept: application/vnd.github+json" \
"/repos/$REPOSITORY/commits/$MERGE_SHA/pulls" \
--jq 'map(select(.merged_at != null)) | .[0]'
set_output() {
echo "$1=$2" >> "$GITHUB_OUTPUT"
}

resolve_pr_from_subject() {
local subject pr_number
subject=$(git log -1 --pretty=%s "$MERGE_SHA")

if [[ "$subject" =~ \(#([0-9]+)\)$ ]]; then
pr_number="${BASH_REMATCH[1]}"
elif [[ "$subject" =~ ^Merge\ pull\ request\ #([0-9]+)\ ]]; then
pr_number="${BASH_REMATCH[1]}"
else
return 1
fi

gh api \
-H "Accept: application/vnd.github+json" \
"/repos/$REPOSITORY/pulls/$pr_number"
}

PR_JSON=$(resolve_pr_from_commit)

if [ "$PR_JSON" = "null" ] || [ -z "$PR_JSON" ]; then
PR_JSON=$(resolve_pr_from_subject || true)
fi

if [ "$PR_JSON" = "null" ] || [ -z "$PR_JSON" ]; then
echo "No merged PR found for $MERGE_SHA. Skipping publish."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

if [ "$(echo "$PR_JSON" | jq -r '.merged_at // empty')" = "" ]; then
echo "Resolved PR for $MERGE_SHA is not merged. Skipping publish."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

HEAD_REF=$(echo "$PR_JSON" | jq -r '.head.ref')

if [[ "$HEAD_REF" != release/v* ]]; then
echo "Merged PR was not a release PR ($HEAD_REF). Skipping publish."
echo "action=skip" >> "$GITHUB_OUTPUT"
exit 0
fi

CURRENT_VERSION=$(tr -d '[:space:]' < VERSION)
echo "action=publish" >> "$GITHUB_OUTPUT"
echo "target_sha=$MERGE_SHA" >> "$GITHUB_OUTPUT"
echo "version=v${CURRENT_VERSION}" >> "$GITHUB_OUTPUT"
set_output "action" "publish"
set_output "target_sha" "$MERGE_SHA"
set_output "version" "v${CURRENT_VERSION}"

- name: Tag merged release commit
id: tag
Expand Down
Loading