Skip to content
Draft
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
10 changes: 10 additions & 0 deletions actions/plugins/version-bump-changelog/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## Unreleased

### 🎉 Features

* Support running version bump from tags to prevent race conditions during releases ([#403](https://github.com/grafana/plugin-ci-workflows/issues/403))
- Action now detects when running from a tag (detached HEAD) and handles it appropriately
- Automatically rebases version bump onto latest main if main has moved ahead since tag creation
- Maintains full backward compatibility with branch-based execution
- Provides clear error messages and guidance for conflict scenarios

## [1.1.0](https://github.com/grafana/plugin-ci-workflows/compare/plugins-version-bump-changelog/v1.0.0...plugins-version-bump-changelog/v1.1.0) (2025-10-08)


Expand Down
120 changes: 118 additions & 2 deletions actions/plugins/version-bump-changelog/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Generate changelog version bump changelog
description: |
Bump npm version, create a git tag and optionally generate a changelog on main using the generate-changelog npm package.
Bump npm version, create a git tag and optionally generate a changelog.
Can be run from main branch or from a tag to lock version at specific commit.
When run from a tag, automatically rebases onto latest main if needed.
inputs:
version:
Expand Down Expand Up @@ -57,6 +59,72 @@
git config user.name 'grafana-plugins-platform-bot[bot]'
git config user.email '144369747+grafana-plugins-platform-bot[bot]@users.noreply.github.com'
- name: Prepare branch for version bump
shell: bash
run: |
set -e
# Detect execution context
if ! git symbolic-ref -q HEAD > /dev/null; then
echo "::notice::Detached HEAD detected - running from tag"
IS_TAG_TRIGGER=true
TAG_COMMIT=$(git rev-parse HEAD)
echo "tag-commit=${TAG_COMMIT}" >> $GITHUB_ENV
else
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
echo "::notice::Running from branch: ${CURRENT_BRANCH}"
IS_TAG_TRIGGER=false
fi
echo "is-tag-trigger=${IS_TAG_TRIGGER}" >> $GITHUB_ENV
# Fetch latest remote state
echo "Fetching latest main from remote..."
git fetch origin main:refs/remotes/origin/main
REMOTE_MAIN_SHA=$(git rev-parse origin/main)
echo "remote-main-sha=${REMOTE_MAIN_SHA}" >> $GITHUB_ENV
# Handle tag trigger
if [ "$IS_TAG_TRIGGER" = "true" ]; then
echo "::group::Tag-based workflow preparation"
echo "Tag points to: ${TAG_COMMIT}"
echo "Remote main at: ${REMOTE_MAIN_SHA}"
# Validate tag is in main history
if ! git merge-base --is-ancestor "${TAG_COMMIT}" "${REMOTE_MAIN_SHA}"; then
echo "::error::Tag commit ${TAG_COMMIT} is not in main branch history"
echo "::error::The tag must point to a commit that exists in the main branch"
exit 1
fi
# Create local main branch from tag commit
git checkout -B main "${TAG_COMMIT}"
echo "::notice::Created local main branch at tag commit"
# Check if rebase will be needed
if [ "${TAG_COMMIT}" != "${REMOTE_MAIN_SHA}" ]; then
echo "::warning::Main has moved ahead since tag was created"
echo "::warning::Version bump will be rebased onto latest main before pushing"
echo "needs-rebase=true" >> $GITHUB_ENV
# Calculate commits that will be rebased over
COMMITS_AHEAD=$(git rev-list --count ${TAG_COMMIT}..${REMOTE_MAIN_SHA})
echo "::notice::Main is ${COMMITS_AHEAD} commit(s) ahead"
else
echo "::notice::Tag is at main HEAD - fast-forward push"
echo "needs-rebase=false" >> $GITHUB_ENV
fi
echo "::endgroup::"
else
# Running from branch - validate
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "${CURRENT_BRANCH}" != "main" ]; then
echo "::error::Running from branch '${CURRENT_BRANCH}' but expected 'main'"
echo "::error::This action must be run from main branch or from a tag"
exit 1
fi
echo "needs-rebase=false" >> $GITHUB_ENV
fi
Comment on lines +64 to +126

Check failure

Code scanning / zizmor

dangerous use of environment file Error

dangerous use of environment file
Comment on lines +64 to +126

Check failure

Code scanning / zizmor

dangerous use of environment file Error

dangerous use of environment file
Comment on lines +64 to +126

Check failure

Code scanning / zizmor

dangerous use of environment file Error

dangerous use of environment file
- name: Get previous tag before bumping
id: previous-tag
if: ${{ inputs.generate-changelog == 'true' }}
Expand Down Expand Up @@ -111,11 +179,59 @@
git add package-lock.json || true
git add CHANGELOG.md || true # No-op if changelog not generated
git commit -m "chore(version): bump version to ${NEW_VERSION}"
git push origin main
env:
GITHUB_TOKEN: ${{ steps.generate-github-token.outputs.token }}
NEW_VERSION: ${{ steps.bump.outputs.new-version }}

- name: Rebase on latest main (if needed)
if: env.needs-rebase == 'true'
shell: bash
run: |
set -e
echo "::group::Rebasing version bump onto latest main"
echo "Rebasing commit: $(git log -1 --oneline)"
echo "Onto: origin/main (${REMOTE_MAIN_SHA})"
# Perform rebase
if ! git rebase origin/main; then
echo "::error::Rebase failed with conflicts"
echo "::error::Files modified by version bump conflict with changes in main"
echo "::error::This typically means package.json, package-lock.json, or CHANGELOG.md"
echo "::error::were modified in commits merged to main since tag was created"
echo "::error::"
echo "::error::Resolution options:"
echo "::error:: 1. Create a new tag at current main HEAD and re-run workflow"
echo "::error:: 2. Manually resolve conflicts and push"
# Abort rebase to leave clean state
git rebase --abort
exit 1
fi
echo "::notice::Rebase successful"
echo "::notice::Version bump commit now on top of latest main"
echo "::notice::New commit: $(git log -1 --oneline)"
echo "::endgroup::"
env:
REMOTE_MAIN_SHA: ${{ env.remote-main-sha }}

- name: Push to main
shell: bash
run: |
echo "::group::Pushing to origin/main"
if git push origin main; then
echo "::notice::Successfully pushed version bump to main"
else
EXIT_CODE=$?
echo "::error::Failed to push to origin/main"
echo "::error::Check permissions and branch protection rules"
exit $EXIT_CODE
fi
echo "::endgroup::"
env:
GITHUB_TOKEN: ${{ steps.generate-github-token.outputs.token }}

- name: Create git tag
shell: bash
run: |
Expand Down
27 changes: 27 additions & 0 deletions examples/extra/version-bump-changelog.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# Version Bump with Changelog Generation
#
# This workflow bumps the npm version, generates a changelog, and creates a git tag.
#
# USAGE OPTIONS:
#
# Option 1: Run from main branch (traditional)
# - Trigger this workflow while on the main branch
# - Version bump is applied directly to latest main
# - Simple and straightforward for low-traffic repos
#
# Option 2: Run from a tag (prevents race conditions - RECOMMENDED)
# - Create a tag at the desired commit: git tag v1.0.0-prepare && git push origin v1.0.0-prepare
# - Trigger this workflow using that tag (select the tag in GitHub Actions UI)
# - Benefits:
# * Locks the version bump to a specific commit
# * Prevents race conditions if PRs are merged during the release process
# * Action automatically rebases onto latest main if needed
# - If main has moved ahead since tag creation:
# * Version bump is automatically rebased onto latest main before pushing
# * If rebase conflicts occur, clear error messages guide resolution
#
# WHEN TO USE TAG-BASED WORKFLOW:
# Use tags when you need to ensure no new commits are unintentionally included
# in your release, especially in active repositories where PRs may be merged
# during the versioning process.
#
name: Version bump, changelog

on:
Expand Down
Loading