This commit is contained in:
dal 2025-05-06 18:33:44 -06:00
parent ae609b9075
commit 771256d182
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
3 changed files with 297 additions and 256 deletions

View File

@ -2,8 +2,8 @@ name: CLI Release
on:
push:
tags:
- 'cli/v*' # Trigger on tags like cli/v1.2.3
branches:
- main # Trigger when PR from staging (or any other) is merged to main
# Add permissions for creating releases
permissions:
@ -11,8 +11,47 @@ permissions:
# pull-requests: write # Not typically needed for a tag-triggered release workflow
jobs:
build:
# No specific if condition needed here based on event, tag push is the trigger
prepare_cli_release_info:
name: Prepare CLI Release Information
runs-on: ubuntu-latest
outputs:
cli_version: ${{ steps.version_info.outputs.cli_version }}
cli_tag_name: ${{ steps.version_info.outputs.cli_tag_name }}
steps:
- name: Checkout code from main
uses: actions/checkout@v4
with:
ref: ${{ github.sha }} # Checkout the specific commit on main (merge commit)
- name: Read CLI Version and Determine Tag
id: version_info
shell: bash
run: |
CLI_VERSION=""
if [ -f cli/cli/Cargo.toml ]; then
CLI_VERSION=$(grep '^version' cli/cli/Cargo.toml | head -n 1 | sed 's/version = \"\(.*\)\"/\1/')
echo "Read CLI version '$CLI_VERSION' from cli/cli/Cargo.toml"
else
echo "Error: cli/cli/Cargo.toml not found!"
exit 1
fi
if [ -z "$CLI_VERSION" ]; then
echo "Error: Could not determine CLI version from Cargo.toml."
exit 1
fi
CLI_TAG_NAME="cli/v$CLI_VERSION"
echo "Determined CLI Version: $CLI_VERSION"
echo "Determined CLI Tag Name: $CLI_TAG_NAME"
echo "cli_version=$CLI_VERSION" >> $GITHUB_OUTPUT
echo "cli_tag_name=$CLI_TAG_NAME" >> $GITHUB_OUTPUT
# Separate Build Job (similar to original)
build_cli:
name: Build CLI Binaries
needs: prepare_cli_release_info # Does not strictly need outputs, but runs after version is confirmed
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
@ -32,13 +71,11 @@ jobs:
target: x86_64-pc-windows-msvc
artifact_name: buster-cli-windows-x86_64.zip
use_tar: false
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code at the specific tag
- name: Checkout code from main
uses: actions/checkout@v4
with:
ref: ${{ github.ref }} # Checks out the specific tag that triggered the workflow
fetch-depth: 0 # Useful for some build processes or if release notes need history
ref: ${{ github.sha }}
- name: Install Rust
uses: actions-rs/toolchain@v1
@ -63,60 +100,51 @@ jobs:
- name: Build optimized release
working-directory: ./cli # Assuming this is the workspace root for the cli crate
# If your CLI project is in cli/cli, adjust working-directory to ./cli/cli
run: cargo build --release --target ${{ matrix.target }} --manifest-path ./cli/Cargo.toml
- name: Determine Binary Name and Path
id: binary_info
shell: bash
run: |
# Ensure cli/target directory exists before find, in case of clean builds or different structures
mkdir -p cli/target/${{ matrix.target }}/release
CRATE_NAME_OUTPUT=$(basename $(find cli/target/${{ matrix.target }}/release -maxdepth 1 -type f -executable ! -name '*.dSYM' ! -name '*.pdb' 2>/dev/null || echo "buster")) # Default to buster if not found
# If find returns nothing (e.g. build failed or path is wrong), CRATE_NAME_OUTPUT could be empty or an error message.
# Fallback to a known name or fail if necessary. For now, using "buster" as a placeholder.
if [ -z "$CRATE_NAME_OUTPUT" ] || ! [ -f "cli/target/${{ matrix.target }}/release/$CRATE_NAME_OUTPUT" ]; then
echo "Warning: Could not automatically determine binary name. Assuming 'buster'."
# Attempt to find 'buster' or 'buster.exe' directly if primary find fails
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
CRATE_NAME_CANDIDATE="buster.exe"
else
CRATE_NAME_CANDIDATE="buster"
fi
if [ -f "cli/target/${{ matrix.target }}/release/$CRATE_NAME_CANDIDATE" ]; then
CRATE_NAME_OUTPUT=$CRATE_NAME_CANDIDATE
else
# If even the fallback isn't found, this will cause issues later.
# Consider failing the step: echo "Error: Binary not found."; exit 1
# For now, proceeding with a default name and letting later steps handle missing file
echo "Fallback binary '$CRATE_NAME_CANDIDATE' also not found. Proceeding with this name."
CRATE_NAME_OUTPUT=${CRATE_NAME_CANDIDATE%.exe} # Store without .exe for consistency if needed elsewhere
fi
# Default to 'buster' if find command fails or returns empty
CRATE_NAME_OUTPUT=$(basename $(find cli/target/${{ matrix.target }}/release -maxdepth 1 -type f -executable ! -name '*.dSYM' ! -name '*.pdb' 2>/dev/null) || echo "buster")
if [ "$CRATE_NAME_OUTPUT" == "." ] || [ -z "$CRATE_NAME_OUTPUT" ]; then CRATE_NAME_OUTPUT="buster"; fi # Further fallback for empty/dot
# Check if the determined/fallback name actually exists as a file
if [[ "${{ matrix.os }}" == "windows-latest" ]] && [[ "$CRATE_NAME_OUTPUT" != *.exe ]]; then
EXECUTABLE_NAME="${CRATE_NAME_OUTPUT}.exe"
else
EXECUTABLE_NAME="$CRATE_NAME_OUTPUT"
fi
echo "CRATE_NAME=$CRATE_NAME_OUTPUT"
echo "Binary name: $CRATE_NAME_OUTPUT"
echo "binary_name=$CRATE_NAME_OUTPUT" >> $GITHUB_OUTPUT
echo "binary_path=cli/target/${{ matrix.target }}/release/$CRATE_NAME_OUTPUT"
echo "binary_path_val=cli/target/${{ matrix.target }}/release/$CRATE_NAME_OUTPUT" >> $GITHUB_OUTPUT
if ! [ -f "cli/target/${{ matrix.target }}/release/$EXECUTABLE_NAME" ]; then
echo "Warning: Binary '$EXECUTABLE_NAME' not found after build. Defaulting to 'buster' or 'buster.exe'."
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then CRATE_NAME_FINAL="buster.exe"; else CRATE_NAME_FINAL="buster"; fi
else
CRATE_NAME_FINAL=$EXECUTABLE_NAME
fi
echo "Final binary name for packaging: $CRATE_NAME_FINAL"
echo "binary_name=$CRATE_NAME_FINAL" >> $GITHUB_OUTPUT
# GITHUB_OUTPUT for binary_path_val is not strictly needed by subsequent steps if using artifact names directly
# echo "binary_path_val=cli/target/${{ matrix.target }}/release/$CRATE_NAME_FINAL" >> $GITHUB_OUTPUT
- name: Compress binary (Unix)
if: matrix.use_tar
shell: bash
run: |
cd cli/target/${{ matrix.target }}/release
# Use the exact binary name determined (could be buster or buster.exe from binary_info)
tar czf ${{ matrix.artifact_name }} ${{ steps.binary_info.outputs.binary_name }}
if [[ "${{ runner.os }}" == "macOS" ]]; then
shasum -a 256 ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256
else
sha256sum ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256
fi
if [[ "${{ runner.os }}" == "macOS" ]]; then shasum -a 256 ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256; else sha256sum ${{ matrix.artifact_name }} > ${{ matrix.artifact_name }}.sha256; fi
- name: Compress binary (Windows)
if: matrix.use_tar == false
shell: pwsh
run: |
cd cli/target/${{ matrix.target }}/release
Compress-Archive -Path ${{ steps.binary_info.outputs.binary_name }}.exe -DestinationPath ${{ matrix.artifact_name }}
# Use the exact binary name, which should include .exe on Windows from binary_info
Compress-Archive -Path ${{ steps.binary_info.outputs.binary_name }} -DestinationPath ${{ matrix.artifact_name }}
Get-FileHash -Algorithm SHA256 ${{ matrix.artifact_name }} | Select-Object -ExpandProperty Hash > ${{ matrix.artifact_name }}.sha256
- name: Upload artifacts
@ -128,75 +156,88 @@ jobs:
cli/target/${{ matrix.target }}/release/${{ matrix.artifact_name }}.sha256
retention-days: 1
release:
needs: build
# This job now handles tagging and creating the GitHub release
tag_and_release_cli:
name: Create Git Tag and GitHub Release for CLI
needs: [prepare_cli_release_info, build_cli]
runs-on: ubuntu-latest
# No specific if condition needed here based on event, tag push is the trigger
outputs:
release_tag: ${{ steps.get_tag_info.outputs.cli_tag_name }}
release_version: ${{ steps.get_tag_info.outputs.cli_version }}
outputs:
cli_version: ${{ needs.prepare_cli_release_info.outputs.cli_version }}
cli_tag_name: ${{ needs.prepare_cli_release_info.outputs.cli_tag_name }}
steps:
- name: Checkout code at the specific tag
- name: Checkout code from main (for tagging context)
uses: actions/checkout@v4
with:
ref: ${{ github.ref }} # Checks out the specific tag that triggered the workflow
fetch-depth: 0
- name: Extract CLI Tag and Version from Git Ref
id: get_tag_info
shell: bash
ref: ${{ github.sha }}
fetch-depth: 0
# IMPORTANT: Use a PAT with repo scope to push tags, especially if main is protected
# or if the default GITHUB_TOKEN doesn't have tag push permissions.
# token: ${{ secrets.REPO_ACCESS_PAT }}
- name: Configure Git User
run: |
CLI_TAG_NAME="${{ github.ref_name }}"
# Validate tag format if necessary (e.g., ensure it starts with cli/v)
if [[ ! "$CLI_TAG_NAME" =~ ^cli/v[0-9]+\.[0-9]+\.[0-9]+(.*)$ ]]; then
echo "Error: Tag $CLI_TAG_NAME does not match the expected format 'cli/vX.Y.Z'"
# exit 1 # Optionally fail the job
# For now, we'll proceed and let release creation fail if tag is not suitable
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Create and Push Git Tag
env:
# Get tag name from the prepare_cli_release_info job
CLI_TAG_NAME: ${{ needs.prepare_cli_release_info.outputs.cli_tag_name }}
# Ensure PAT is used if GITHUB_TOKEN is insufficient for pushing tags:
# GH_TOKEN: ${{ secrets.REPO_ACCESS_PAT }} # Uncomment and use your PAT secret
run: |
echo "Creating Git tag: $CLI_TAG_NAME on commit ${{ github.sha }}"
# Create tag pointing to the current commit on main (merge commit)
git tag "$CLI_TAG_NAME" ${{ github.sha }}
echo "Pushing Git tag: $CLI_TAG_NAME"
# If using PAT for push, uncomment the following lines after setting GH_TOKEN env var:
# git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}
# git push origin "refs/tags/$CLI_TAG_NAME"
CLI_VERSION=$(echo "$CLI_TAG_NAME" | sed 's#^cli/v##')
# For now, using default GITHUB_TOKEN. THIS MIGHT NOT WORK FOR PROTECTED BRANCHES/TAGS
# OR IF THE TOKEN LACKS PERMISSION. REPLACE WITH PAT PUSH.
git push origin "refs/tags/$CLI_TAG_NAME"
echo "cli_tag_name=$CLI_TAG_NAME" >> $GITHUB_OUTPUT
echo "cli_version=$CLI_VERSION" >> $GITHUB_OUTPUT
echo "Extracted from Git Ref - CLI Tag: $CLI_TAG_NAME, CLI Version: $CLI_VERSION"
- name: Download build artifacts
- name: Download all build artifacts
uses: actions/download-artifact@v4
# No specific path needed, it downloads all to a directory named after the artifact
with:
path: downloaded-artifacts # Download all artifacts to this directory
- name: List downloaded artifacts (for debugging)
run: ls -R downloaded-artifacts
- name: Create Release
# if: steps.get_tag_info.outputs.cli_tag_name != '' # This check is implicitly handled by the tag trigger pattern
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ steps.get_tag_info.outputs.cli_tag_name }} # Should be same as github.ref_name
name: CLI Release v${{ steps.get_tag_info.outputs.cli_version }}
tag_name: ${{ needs.prepare_cli_release_info.outputs.cli_tag_name }}
name: CLI Release v${{ needs.prepare_cli_release_info.outputs.cli_version }}
files: |
**/buster-cli-linux-x86_64.tar.gz
**/buster-cli-linux-x86_64.tar.gz.sha256
**/buster-cli-darwin-x86_64.tar.gz
**/buster-cli-darwin-x86_64.tar.gz.sha256
**/buster-cli-darwin-arm64.tar.gz
**/buster-cli-darwin-arm64.tar.gz.sha256
**/buster-cli-windows-x86_64.zip
**/buster-cli-windows-x86_64.zip.sha256
downloaded-artifacts/**/buster-cli-linux-x86_64.tar.gz
downloaded-artifacts/**/buster-cli-linux-x86_64.tar.gz.sha256
downloaded-artifacts/**/buster-cli-darwin-x86_64.tar.gz
downloaded-artifacts/**/buster-cli-darwin-x86_64.tar.gz.sha256
downloaded-artifacts/**/buster-cli-darwin-arm64.tar.gz
downloaded-artifacts/**/buster-cli-darwin-arm64.tar.gz.sha256
downloaded-artifacts/**/buster-cli-windows-x86_64.zip
downloaded-artifacts/**/buster-cli-windows-x86_64.zip.sha256
draft: false
prerelease: false
generate_release_notes: true
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Default token is usually fine for softprops action if tag exists
update-homebrew-tap:
update_homebrew_tap:
name: Update Homebrew Tap
needs: release
needs: tag_and_release_cli # Trigger after tag_and_release_cli which now outputs version and tag
runs-on: ubuntu-latest
if: needs.release.outputs.release_tag != '' # Run only if a CLI tag was processed and release was attempted
if: needs.tag_and_release_cli.outputs.cli_tag_name != ''
steps:
- name: Get release version and tag from previous job
id: release_info
run: |
echo "RELEASE_VERSION=${{ needs.release.outputs.release_version }}" >> $GITHUB_ENV
echo "RELEASE_TAG=${{ needs.release.outputs.release_tag }}" >> $GITHUB_ENV
echo "Using version: ${{ needs.release.outputs.release_version }} from tag: ${{ needs.release.outputs.release_tag }}"
echo "RELEASE_VERSION=${{ needs.tag_and_release_cli.outputs.cli_version }}" >> $GITHUB_ENV
echo "RELEASE_TAG=${{ needs.tag_and_release_cli.outputs.cli_tag_name }}" >> $GITHUB_ENV
echo "Using version: ${{ needs.tag_and_release_cli.outputs.cli_version }} from tag: ${{ needs.tag_and_release_cli.outputs.cli_tag_name }}"
- name: Set up GitHub CLI
uses: actions/setup-node@v4 # gh is often bundled, but this ensures it's available or can be installed

View File

@ -2,9 +2,8 @@ name: Docker Release
on:
push:
tags:
- 'api/v*'
- 'web/v*'
branches:
- main # Trigger when PR from staging is merged to main
env:
# Placeholder for Docker Hub username/organization or GHCR owner
@ -13,15 +12,72 @@ env:
WEB_IMAGE_NAME: web-service
jobs:
build_and_push_api:
name: Build and Push API Image
if: startsWith(github.ref, 'refs/tags/api/v') # Trigger only for API tags
runs-on: blacksmith-32vcpu-ubuntu-2204 # Updated runner
prepare_docker_release_info:
name: Prepare Docker Release Information
runs-on: ubuntu-latest
outputs:
api_version: ${{ steps.version_info.outputs.api_version }}
web_version: ${{ steps.version_info.outputs.web_version }}
api_version_found: ${{ steps.version_info.outputs.api_version_found }}
web_version_found: ${{ steps.version_info.outputs.web_version_found }}
steps:
- name: Checkout code at the specific tag
- name: Checkout code from main
uses: actions/checkout@v4
with:
ref: ${{ github.ref }} # Checks out the specific API tag
ref: ${{ github.sha }} # Checkout the specific commit on main (merge commit)
- name: Read API and Web Versions
id: version_info
shell: bash
run: |
API_VERSION=""
WEB_VERSION=""
API_VERSION_FOUND="false"
WEB_VERSION_FOUND="false"
# Read API version from api/server/Cargo.toml
if [ -f api/server/Cargo.toml ]; then
API_VERSION=$(grep '^version' api/server/Cargo.toml | head -n 1 | sed 's/version = \"\(.*\)\"/\1/')
if [ -n "$API_VERSION" ]; then
echo "Read API version '$API_VERSION' from api/server/Cargo.toml"
API_VERSION_FOUND="true"
else
echo "API version string not found in api/server/Cargo.toml despite file existing."
fi
else
echo "Warning: api/server/Cargo.toml not found. Cannot determine API version."
fi
# Read Web version from web/package.json
if [ -f web/package.json ]; then
WEB_VERSION=$(jq -r '.version // empty' web/package.json)
if [ -n "$WEB_VERSION" ]; then
echo "Read Web version '$WEB_VERSION' from web/package.json"
WEB_VERSION_FOUND="true"
else
echo "Web version string not found in web/package.json despite file existing."
fi
else
echo "Warning: web/package.json not found. Cannot determine Web version."
fi
echo "api_version=$API_VERSION" >> $GITHUB_OUTPUT
echo "web_version=$WEB_VERSION" >> $GITHUB_OUTPUT
echo "api_version_found=$API_VERSION_FOUND" >> $GITHUB_OUTPUT
echo "web_version_found=$WEB_VERSION_FOUND" >> $GITHUB_OUTPUT
build_and_push_api:
name: Build and Push API Image
needs: prepare_docker_release_info
if: needs.prepare_docker_release_info.outputs.api_version_found == 'true'
runs-on: blacksmith-32vcpu-ubuntu-2204
env:
API_VERSION: ${{ needs.prepare_docker_release_info.outputs.api_version }}
steps:
- name: Checkout code from main
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@ -29,20 +85,6 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract API version from Git tag
id: api_version_extractor # Renamed for clarity
run: |
# github.ref_name will be like "api/v1.2.3"
VERSION=$(echo "${{ github.ref_name }}" | sed 's#^api/v##')
if [ -z "$VERSION" ]; then # Should not happen due to startsWith condition
echo "Could not extract version from tag: ${{ github.ref_name }}"
VERSION="unknown"
fi
echo "API_VERSION_ENV=$VERSION" >> $GITHUB_ENV # Set for current job
echo "api_version_output=$VERSION" >> $GITHUB_OUTPUT # Output for other steps if needed
echo "Extracted API version: $VERSION"
shell: bash
- name: Log in to Docker Registry
uses: docker/login-action@v3
with:
@ -54,24 +96,27 @@ jobs:
uses: useblacksmith/build-push-action@v1
with:
context: ./api
file: ./api/Dockerfile # Assuming this Dockerfile is for api/server
file: ./api/Dockerfile
push: true
tags: |
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.API_IMAGE_NAME }}:${{ env.API_VERSION_ENV }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.API_IMAGE_NAME }}:${{ github.sha }} # SHA of the tag commit
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.API_IMAGE_NAME }}:${{ env.API_VERSION }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.API_IMAGE_NAME }}:${{ github.sha }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.API_IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
build_and_push_web:
name: Build and Push Web Image
if: startsWith(github.ref, 'refs/tags/web/v') # Trigger only for Web tags
runs-on: blacksmith-32vcpu-ubuntu-2204 # Updated runner
needs: prepare_docker_release_info
if: needs.prepare_docker_release_info.outputs.web_version_found == 'true'
runs-on: blacksmith-32vcpu-ubuntu-2204
env:
WEB_VERSION: ${{ needs.prepare_docker_release_info.outputs.web_version }}
steps:
- name: Checkout code at the specific tag
- name: Checkout code from main
uses: actions/checkout@v4
with:
ref: ${{ github.ref }} # Checks out the specific Web tag
ref: ${{ github.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@ -79,20 +124,6 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract Web version from Git tag
id: web_version_extractor # Renamed for clarity
run: |
# github.ref_name will be like "web/v1.2.3"
VERSION=$(echo "${{ github.ref_name }}" | sed 's#^web/v##')
if [ -z "$VERSION" ]; then # Should not happen due to startsWith condition
echo "Could not extract version from tag: ${{ github.ref_name }}"
VERSION="unknown"
fi
echo "WEB_VERSION_ENV=$VERSION" >> $GITHUB_ENV # Set for current job
echo "web_version_output=$VERSION" >> $GITHUB_OUTPUT # Output for other steps if needed
echo "Extracted Web version: $VERSION"
shell: bash
- name: Log in to Docker Registry
uses: docker/login-action@v3
with:
@ -107,8 +138,8 @@ jobs:
file: ./web/Dockerfile
push: true
tags: |
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.WEB_IMAGE_NAME }}:${{ env.WEB_VERSION_ENV }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.WEB_IMAGE_NAME }}:${{ github.sha }} # SHA of the tag commit
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.WEB_IMAGE_NAME }}:${{ env.WEB_VERSION }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.WEB_IMAGE_NAME }}:${{ github.sha }}
${{ env.DOCKER_REGISTRY_OWNER }}/${{ env.WEB_IMAGE_NAME }}:latest
build-args: |
NEXT_PUBLIC_API_URL=${{ secrets.NEXT_PUBLIC_API_URL }}

View File

@ -2,63 +2,66 @@ name: Manage Versions
on:
pull_request:
types: [closed]
types: [opened]
branches:
- main
- staging
workflow_dispatch:
inputs:
component:
description: 'Component to version bump'
description: 'Component to version bump (if running manually)'
required: true
default: 'all'
type: choice
options:
- all
- api
- web
- cli
options: [all, api, web, cli]
version_spec:
description: 'Version bump type (patch, minor, major) or specific version (e.g., 1.2.3)'
description: 'Version bump type or specific version (if running manually)'
required: true
default: 'patch'
type: string
pr_branch:
description: 'Name of the PR source branch (required if dispatching for a PR)'
required: false
type: string
permissions:
contents: write # To push commits and tags
contents: write # To push commits back to the PR branch
jobs:
bump_versions:
bump_versions_in_pr:
runs-on: blacksmith
if: (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || github.event_name == 'workflow_dispatch'
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
outputs:
new_api_version: ${{ steps.bump.outputs.new_api_version }}
new_web_version: ${{ steps.bump.outputs.new_web_version }}
new_cli_version: ${{ steps.bump.outputs.new_cli_version }}
api_tag_created: ${{ steps.tag.outputs.api_tag_created }}
web_tag_created: ${{ steps.tag.outputs.web_tag_created }}
cli_tag_created: ${{ steps.tag.outputs.cli_tag_created }}
versions_bumped: ${{ steps.bump.outputs.versions_bumped }}
steps:
- name: Determine Branch Name and SHA
id: branch_info
- name: Determine Target Branch for Checkout and Push
id: pr_branch_info
shell: bash
run: |
TARGET_BRANCH=""
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "branch_name=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT
echo "checkout_sha=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
TARGET_BRANCH="${{ github.head_ref }}"
echo "Detected PR event. Will operate on PR source branch: $TARGET_BRANCH"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "branch_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "checkout_sha=${{ github.sha }}" >> $GITHUB_OUTPUT
if [[ -z "${{ github.event.inputs.pr_branch }}" ]]; then
echo "Error: 'pr_branch' input is required for manual dispatch to update a PR."
exit 1
fi
TARGET_BRANCH="${{ github.event.inputs.pr_branch }}"
echo "Detected workflow_dispatch event. Will operate on specified PR branch: $TARGET_BRANCH"
else
echo "branch_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "checkout_sha=${{ github.sha }}" >> $GITHUB_OUTPUT
echo "Error: Unhandled event type '${{ github.event_name }}'"
exit 1
fi
echo "target_branch_name=$TARGET_BRANCH" >> $GITHUB_OUTPUT
- name: Checkout code
- name: Checkout PR source branch
uses: actions/checkout@v4
with:
ref: ${{ github.sha }}
ref: ${{ steps.pr_branch_info.outputs.target_branch_name }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v4
@ -79,74 +82,42 @@ jobs:
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Determine Version Spec and Component from Event
- name: Determine Version Spec and Component
id: event_params
shell: bash
run: |
VERSION_SPEC=""
COMPONENT=""
COMMIT_MESSAGE_TEXT=""
echo "Event name: ${{ github.event_name }}"
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION_SPEC="${{ github.event.inputs.version_spec }}"
COMPONENT="${{ github.event.inputs.component }}"
echo "Using workflow_dispatch inputs: version_spec='$VERSION_SPEC', component='$COMPONENT'"
elif [[ "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.merged }}" == "true" ]]; then
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
PR_TITLE=$(echo "${{ github.event.pull_request.title }}" | tr '[:upper:]' '[:lower:]')
echo "Pull Request title (lowercase): $PR_TITLE"
COMPONENT="all"
if echo "$PR_TITLE" | grep -q -E "breaking change|feat!:"; then
VERSION_SPEC="major"
elif echo "$PR_TITLE" | grep -q -E "^feat\\([^)]+\\)!:"; then
VERSION_SPEC="major"
elif echo "$PR_TITLE" | grep -q -E "^feat:"; then
VERSION_SPEC="minor"
elif echo "$PR_TITLE" | grep -q -E "^fix:"; then
VERSION_SPEC="patch"
if echo "$PR_TITLE" | grep -q -E "breaking change|feat!:"; then VERSION_SPEC="major";
elif echo "$PR_TITLE" | grep -q -E "^feat\\([^)]+\\)!:"; then VERSION_SPEC="major";
elif echo "$PR_TITLE" | grep -q -E "^feat:"; then VERSION_SPEC="minor";
elif echo "$PR_TITLE" | grep -q -E "^fix:"; then VERSION_SPEC="patch";
else
echo "No major/minor/fix keyword found in PR title. Defaulting to patch for merged PR."
echo "No conventional commit keyword (major/minor/patch) found in PR title '$PR_TITLE'."
echo "Version bumping will not occur automatically for this push to the PR."
VERSION_SPEC="patch"
fi
echo "Determined for PR merge: version_spec='$VERSION_SPEC', component='$COMPONENT'"
elif [[ "${{ github.event_name }}" == "push" ]]; then
COMMIT_MESSAGE_TEXT=$(echo "${{ github.event.head_commit.message }}" | tr '[:upper:]' '[:lower:]')
echo "Push event. Analyzing commit message (lowercase): $COMMIT_MESSAGE_TEXT"
COMPONENT="all"
if echo "$COMMIT_MESSAGE_TEXT" | grep -q -E "breaking change|feat!:"; then
VERSION_SPEC="major"
elif echo "$COMMIT_MESSAGE_TEXT" | grep -q -E "^feat\\([^)]+\\)!:"; then
VERSION_SPEC="major"
elif echo "$COMMIT_MESSAGE_TEXT" | grep -q -E "^feat:"; then
VERSION_SPEC="minor"
elif echo "$COMMIT_MESSAGE_TEXT" | grep -q -E "^fix:"; then
VERSION_SPEC="patch"
else
echo "No major/minor/fix keyword found in commit message. Defaulting to patch."
VERSION_SPEC="patch"
fi
echo "Determined for push: version_spec='$VERSION_SPEC', component='$COMPONENT'"
else
echo "Unhandled event type: ${{ github.event_name }}. Defaulting to patch and all."
VERSION_SPEC="patch"
COMPONENT="all"
echo "Determined for PR to staging: version_spec='$VERSION_SPEC', component='$COMPONENT'"
fi
if [[ -z "$VERSION_SPEC" ]]; then
echo "Warning: VERSION_SPEC is empty after evaluation. Defaulting to patch."
echo "Warning: VERSION_SPEC is empty. Defaulting to patch."
VERSION_SPEC="patch"
fi
if [[ -z "$COMPONENT" ]]; then
echo "Warning: COMPONENT is empty after evaluation. Defaulting to all."
echo "Warning: COMPONENT is empty. Defaulting to all."
COMPONENT="all"
fi
echo "Final determined version_spec: $VERSION_SPEC"
echo "Final determined component: $COMPONENT"
echo "version_spec=$VERSION_SPEC" >> $GITHUB_OUTPUT
echo "component=$COMPONENT" >> $GITHUB_OUTPUT
@ -231,85 +202,83 @@ jobs:
if [[ "$COMMIT_CHANGES" == true ]]; then
FINAL_COMMIT_MESSAGE=$(echo "$COMMIT_MESSAGE_PREFIX" | sed 's/;$//')
echo "Final Commit Message: $FINAL_COMMIT_MESSAGE [skip ci]"
echo "COMMIT_MESSAGE_CONTENT=$FINAL_COMMIT_MESSAGE [skip ci]" >> $GITHUB_ENV
echo "commit_message=$FINAL_COMMIT_MESSAGE [skip ci]" >> $GITHUB_OUTPUT
echo "Final Commit Message for version files: $FINAL_COMMIT_MESSAGE [skip ci]"
echo "commit_message=$FINAL_COMMIT_MESSAGE [skip ci]" >> $GITHUB_OUTPUT # For the version files commit
echo "versions_bumped=true" >> $GITHUB_OUTPUT
else
echo "No version changes detected."
echo "COMMIT_MESSAGE_CONTENT=" >> $GITHUB_ENV
echo "No version changes detected for source files."
echo "commit_message=" >> $GITHUB_OUTPUT
echo "versions_bumped=false" >> $GITHUB_OUTPUT
fi
echo "New API Version Output: $NEW_API_VERSION"
echo "New Web Version Output: $NEW_WEB_VERSION"
echo "New CLI Version Output: $NEW_CLI_VERSION"
- name: Commit version changes
if: steps.bump.outputs.commit_message != ''
- name: Commit and Push Version File Changes to PR Branch
if: steps.bump.outputs.versions_bumped == 'true'
env:
COMMIT_MESSAGE_TO_USE: ${{ steps.bump.outputs.commit_message }}
TARGET_BRANCH: ${{ steps.pr_branch_info.outputs.target_branch_name }}
COMMIT_MESSAGE_CONTENT: ${{ steps.bump.outputs.commit_message }} # This is the commit message for version files
run: |
git commit -m "$COMMIT_MESSAGE_TO_USE"
echo "Committing version file changes with message: $COMMIT_MESSAGE_CONTENT"
git commit -m "$COMMIT_MESSAGE_CONTENT" # Files were already added by the 'bump' step
echo "Pushing version file changes to PR branch: $TARGET_BRANCH"
git push origin HEAD:"$TARGET_BRANCH"
- name: Create and Push Tags
if: steps.bump.outputs.commit_message != ''
- name: Prepare, Commit, and Push Tag Information File
if: steps.bump.outputs.versions_bumped == 'true' # Only run if versions were actually bumped
id: prepare_tag_info_file
env:
TARGET_BRANCH: ${{ steps.pr_branch_info.outputs.target_branch_name }}
run: |
echo "Creating and pushing tags..."
echo "Preparing tag_info.json file..."
TAG_INFO_FILE="tag_info.json"
echo "{" > $TAG_INFO_FILE
FIRST_TAG=true
FIRST_ENTRY=true
NEW_API_VERSION="${{ steps.bump.outputs.new_api_version }}"
NEW_WEB_VERSION="${{ steps.bump.outputs.new_web_version }}"
NEW_CLI_VERSION="${{ steps.bump.outputs.new_cli_version }}"
if [[ -n "$NEW_API_VERSION" ]]; then
TAG_NAME="api/v$NEW_API_VERSION"
echo "Tagging API: $TAG_NAME"
git tag "$TAG_NAME"
if [ "$FIRST_TAG" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"api_tag\": \"$TAG_NAME\"" >> $TAG_INFO_FILE
FIRST_TAG=false
POTENTIAL_TAG_NAME="api/v$NEW_API_VERSION"
if [ "$FIRST_ENTRY" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"api_tag\": \"$POTENTIAL_TAG_NAME\", \"api_version\": \"$NEW_API_VERSION\"" >> $TAG_INFO_FILE
FIRST_ENTRY=false
fi
if [[ -n "$NEW_WEB_VERSION" ]]; then
TAG_NAME="web/v$NEW_WEB_VERSION"
echo "Tagging Web: $TAG_NAME"
git tag "$TAG_NAME"
if [ "$FIRST_TAG" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"web_tag\": \"$TAG_NAME\"" >> $TAG_INFO_FILE
FIRST_TAG=false
POTENTIAL_TAG_NAME="web/v$NEW_WEB_VERSION"
if [ "$FIRST_ENTRY" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"web_tag\": \"$POTENTIAL_TAG_NAME\", \"web_version\": \"$NEW_WEB_VERSION\"" >> $TAG_INFO_FILE
FIRST_ENTRY=false
fi
if [[ -n "$NEW_CLI_VERSION" ]]; then
TAG_NAME="cli/v$NEW_CLI_VERSION"
echo "Tagging CLI: $TAG_NAME"
git tag "$TAG_NAME"
if [ "$FIRST_TAG" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"cli_tag\": \"$TAG_NAME\"" >> $TAG_INFO_FILE
FIRST_TAG=false
POTENTIAL_TAG_NAME="cli/v$NEW_CLI_VERSION"
if [ "$FIRST_ENTRY" = false ]; then echo "," >> $TAG_INFO_FILE; fi
echo " \"cli_tag\": \"$POTENTIAL_TAG_NAME\", \"cli_version\": \"$NEW_CLI_VERSION\"" >> $TAG_INFO_FILE
FIRST_ENTRY=false
fi
echo "}" >> $TAG_INFO_FILE
echo "Created tag info file:"
echo "Created tag_info.json:"
cat $TAG_INFO_FILE
echo "Committing and pushing tag_info.json to $TARGET_BRANCH..."
git add $TAG_INFO_FILE
# Check if there are changes to commit for tag_info.json to avoid empty commit
if ! git diff --staged --quiet; then
git commit -m "chore: update tag_info.json with potential release versions [skip ci]"
git push origin HEAD:"$TARGET_BRANCH"
echo "tag_info.json pushed to $TARGET_BRANCH."
else
echo "No changes to tag_info.json to commit."
fi
BRANCH_TO_PUSH="${{ steps.branch_info.outputs.branch_name }}"
echo "Pushing commit and tags to branch: $BRANCH_TO_PUSH"
git push origin HEAD:"refs/heads/$BRANCH_TO_PUSH" --follow-tags
echo "api_tag_created=$API_TAG_CREATED" >> $GITHUB_OUTPUT
echo "web_tag_created=$WEB_TAG_CREATED" >> $GITHUB_OUTPUT
echo "cli_tag_created=$CLI_TAG_CREATED" >> $GITHUB_OUTPUT
- name: Upload Tag Information Artifact
if: steps.tag.outputs.api_tag_created == 'true' || steps.tag.outputs.web_tag_created == 'true' || steps.tag.outputs.cli_tag_created == 'true'
- name: Upload Tag Information Artifact (for reference)
if: steps.bump.outputs.versions_bumped == 'true' # Or based on whether tag_info.json was actually changed/committed
uses: actions/upload-artifact@v4
with:
name: version-tag-info
path: tag_info.json
retention-days: 1
- name: Push changes (if only commit, no tags yet or if tag push failed)
if: steps.bump.outputs.commit_message != '' && (steps.bump.outputs.new_api_version == '' && steps.bump.outputs.new_web_version == '' && steps.bump.outputs.new_cli_version == '')
run: |
BRANCH_TO_PUSH="${{ steps.branch_info.outputs.branch_name }}"
echo "Pushing commit to branch: $BRANCH_TO_PUSH (changes made but no version tags generated)."
git push origin HEAD:"refs/heads/$BRANCH_TO_PUSH"
name: version-tag-info-potential
path: tag_info.json # This will upload the latest version from the workspace
retention-days: 7