mirror of
https://github.com/Lissy93/dashy.git
synced 2026-04-17 16:56:56 -04:00
👷 Mark issues as released when new tag published
- Fixed issue where tag body was missing PR info - Adds tag logic to mark release version for applicable issues - Trigger rebuild of docs website when version released - Upgraded the github-script action from v7 to v8 - Show summary of changes when workflow completes - Updated code comments to explain wtf is happening
This commit is contained in:
157
.github/workflows/bump-and-tag.yml
vendored
157
.github/workflows/bump-and-tag.yml
vendored
@@ -1,7 +1,14 @@
|
||||
# When a PR is merged into master, this workflow handles versioning:
|
||||
# - If code files changed but version wasn't bumped: auto-increments patch version
|
||||
# Creates a new git tag when a PR is merged
|
||||
#
|
||||
# Here's the flow:
|
||||
# - Triggered whenever a PR is merged, if that PR made code changes
|
||||
# - If version wasn't bumped in PR, increment patch version and update package.json
|
||||
# - Otherwise (if the PR did bump version) we use the new version from package.json
|
||||
# - Creates and pushes a git tag for the new version
|
||||
# - The tag then triggers Docker publishing and release drafting
|
||||
# - That git tag then triggers Docker publishing and release drafting in other CI
|
||||
# - Add tags to issues from newly relesaed features/fixes (if applicable)
|
||||
# - Trigger fresh deploy of docs site, so changelog remains up-to-date
|
||||
# - Finally, shows summary of actions taken and new tag published
|
||||
name: 🔖 Auto Version & Tag
|
||||
|
||||
on:
|
||||
@@ -16,6 +23,7 @@ concurrency:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
version-and-tag:
|
||||
@@ -25,7 +33,7 @@ jobs:
|
||||
steps:
|
||||
- name: Check PR for code changes and version bump 📂
|
||||
id: check_pr
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
@@ -77,7 +85,7 @@ jobs:
|
||||
|
||||
- name: Checkout repository 🛎️
|
||||
if: steps.check_pr.outputs.needs_tag == 'true'
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -87,6 +95,23 @@ jobs:
|
||||
git config user.name "Liss-Bot"
|
||||
git config user.email "liss-bot@d0h.co"
|
||||
|
||||
- name: Extract referenced issues 🔍
|
||||
id: issues
|
||||
if: steps.check_pr.outputs.needs_tag == 'true'
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const body = context.payload.pull_request.body || '';
|
||||
const matches = body.match(/#(\d+)/g);
|
||||
if (!matches) {
|
||||
core.info('No issue references found in PR body');
|
||||
core.setOutput('numbers', '');
|
||||
return;
|
||||
}
|
||||
const unique = [...new Set(matches.map(m => m.replace('#', '')))];
|
||||
core.info(`Found issue references: ${unique.join(', ')}`);
|
||||
core.setOutput('numbers', unique.join(','));
|
||||
|
||||
- name: Bump patch version ⬆️
|
||||
if: steps.check_pr.outputs.needs_bump == 'true'
|
||||
run: |
|
||||
@@ -96,7 +121,13 @@ jobs:
|
||||
git push
|
||||
|
||||
- name: Create and push tag 🏷️
|
||||
id: tag
|
||||
if: steps.check_pr.outputs.needs_tag == 'true'
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
ISSUES: ${{ steps.issues.outputs.numbers }}
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
git fetch --tags --force
|
||||
@@ -111,5 +142,121 @@ jobs:
|
||||
"$PR_TITLE" \
|
||||
"$MERGE_SHA" > tag-message.txt
|
||||
|
||||
if [ -n "$ISSUES" ]; then
|
||||
printf 'Resolves: %s\n' "$(echo "$ISSUES" | sed 's/,/, #/g; s/^/#/')" >> tag-message.txt
|
||||
fi
|
||||
|
||||
git tag -a "$VERSION" -F tag-message.txt
|
||||
git push origin "$VERSION"
|
||||
|
||||
- name: Label referenced issues 🛩️
|
||||
id: label
|
||||
if: steps.check_pr.outputs.needs_tag == 'true' && steps.issues.outputs.numbers != ''
|
||||
continue-on-error: true
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
ISSUES: ${{ steps.issues.outputs.numbers }}
|
||||
with:
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { owner, repo } = context.repo;
|
||||
const { version } = JSON.parse(require('fs').readFileSync('package.json', 'utf8'));
|
||||
const labelName = `🛩️ Released ${version}`;
|
||||
const issues = process.env.ISSUES.split(',').filter(Boolean);
|
||||
|
||||
try {
|
||||
await github.rest.issues.createLabel({
|
||||
owner, repo,
|
||||
name: labelName,
|
||||
color: 'EDEDED',
|
||||
description: `Included in release v${version}`,
|
||||
});
|
||||
core.info(`Created label: ${labelName}`);
|
||||
} catch (e) {
|
||||
if (e.status === 422) {
|
||||
core.info(`Label already exists: ${labelName}`);
|
||||
} else {
|
||||
core.warning(`Failed to create label: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const num of issues) {
|
||||
try {
|
||||
await github.rest.issues.addLabels({
|
||||
owner, repo,
|
||||
issue_number: parseInt(num, 10),
|
||||
labels: [labelName],
|
||||
});
|
||||
core.info(`Labeled issue #${num}`);
|
||||
} catch (e) {
|
||||
core.warning(`Failed to label issue #${num}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
- name: Trigger docs site rebuild 📝
|
||||
id: docs
|
||||
if: steps.tag.outcome == 'success'
|
||||
continue-on-error: true
|
||||
env:
|
||||
HOOK_URL: ${{ secrets.DOCS_SITE_REBUILD_HOOK }}
|
||||
run: |
|
||||
if [ -z "$HOOK_URL" ]; then
|
||||
echo "::warning::DOCS_SITE_REBUILD_HOOK secret is not set, skipping"
|
||||
exit 1
|
||||
fi
|
||||
VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
|
||||
curl -sf -X POST -d '{}' "${HOOK_URL}?trigger_title=v${VERSION}+released" \
|
||||
--max-time 15 --retry 2 --retry-max-time 30
|
||||
echo "Triggered docs rebuild for v${VERSION}"
|
||||
|
||||
- name: Job summary 📋
|
||||
if: always()
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
REPO_URL: ${{ github.server_url }}/${{ github.repository }}
|
||||
NEEDS_BUMP: ${{ steps.check_pr.outputs.needs_bump }}
|
||||
NEEDS_TAG: ${{ steps.check_pr.outputs.needs_tag }}
|
||||
ISSUES: ${{ steps.issues.outputs.numbers }}
|
||||
TAG_OUTCOME: ${{ steps.tag.outcome }}
|
||||
LABEL_OUTCOME: ${{ steps.label.outcome }}
|
||||
DOCS_OUTCOME: ${{ steps.docs.outcome }}
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "unknown")
|
||||
|
||||
{
|
||||
echo "## 🔖 Auto Version & Tag"
|
||||
echo ""
|
||||
echo "| Step | Result |"
|
||||
echo "|------|--------|"
|
||||
echo "| PR | [#${PR_NUMBER}](${REPO_URL}/pull/${PR_NUMBER}) — ${PR_TITLE} |"
|
||||
|
||||
if [ "$NEEDS_BUMP" = "true" ]; then
|
||||
echo "| Version bump | ✅ \`${VERSION}\` |"
|
||||
else
|
||||
echo "| Version bump | ⏭️ Skipped |"
|
||||
fi
|
||||
|
||||
if [ "$NEEDS_TAG" = "true" ] && [ "$TAG_OUTCOME" = "success" ]; then
|
||||
echo "| Tag | ✅ [\`${VERSION}\`](${REPO_URL}/releases/tag/${VERSION}) |"
|
||||
elif [ "$NEEDS_TAG" = "true" ]; then
|
||||
echo "| Tag | ❌ Failed |"
|
||||
else
|
||||
echo "| Tag | ⏭️ Skipped |"
|
||||
fi
|
||||
|
||||
if [ "$DOCS_OUTCOME" = "success" ]; then
|
||||
echo "| Docs rebuild | ✅ Triggered |"
|
||||
elif [ "$DOCS_OUTCOME" = "failure" ]; then
|
||||
echo "| Docs rebuild | ⚠️ Failed |"
|
||||
fi
|
||||
|
||||
if [ -n "$ISSUES" ]; then
|
||||
ISSUE_LINKS=$(echo "$ISSUES" | tr ',' '\n' | sed "s|.*|[#&](${REPO_URL}/issues/&)|" | paste -sd ' ' -)
|
||||
if [ "$LABEL_OUTCOME" = "success" ]; then
|
||||
echo "| Issues labeled | ✅ ${ISSUE_LINKS} |"
|
||||
else
|
||||
echo "| Issues labeled | ⚠️ ${ISSUE_LINKS} |"
|
||||
fi
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
Reference in New Issue
Block a user