name: 'Changelogs'
description: 'Create a PR with version bumps and changelogs, and publish packages when merged'
author: 'wevm'
branding:
icon: 'package'
color: 'orange'
inputs:
version:
description: 'Command to run for versioning'
required: false
default: 'changelogs version'
publish:
description: 'Command to run for publishing (runs when no changelogs are pending)'
required: false
crate-token:
description: 'Crates.io API token for publishing'
required: false
commit:
description: 'Commit message for version bump'
required: false
default: 'Version Packages'
title:
description: 'Pull request title'
required: false
default: 'Version Packages'
branch:
description: 'Branch name for the version PR'
required: false
default: 'changelog-release/main'
github-token:
description: 'GitHub token for creating PRs'
required: false
default: ${{ github.token }}
outputs:
hasChangelogs:
description: 'Whether there are pending changelogs'
value: ${{ steps.check.outputs.hasChangelogs }}
pullRequestNumber:
description: 'The pull request number if created or updated'
value: ${{ steps.pr.outputs.pull-request-number }}
published:
description: 'Whether packages were published'
value: ${{ steps.publish.outputs.published }}
publishedPackages:
description: 'JSON array of published packages'
value: ${{ steps.publish.outputs.publishedPackages }}
runs:
using: 'composite'
steps:
- name: Check for changelogs
id: check
shell: bash
run: |
if [ -d ".changelog" ] && [ "$(find .changelog -name '*.md' ! -name 'README.md' 2>/dev/null | head -1)" ]; then
echo "hasChangelogs=true" >> $GITHUB_OUTPUT
echo "Found pending changelogs"
else
echo "hasChangelogs=false" >> $GITHUB_OUTPUT
echo "No pending changelogs"
fi
- name: Setup Git user
if: steps.check.outputs.hasChangelogs == 'true'
shell: bash
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Run version command
if: steps.check.outputs.hasChangelogs == 'true'
shell: bash
run: ${{ inputs.version }}
- name: Generate PR body
if: steps.check.outputs.hasChangelogs == 'true'
id: body
shell: bash
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "body<<$EOF" >> $GITHUB_OUTPUT
echo "This PR was opened by the Changelogs release workflow." >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "When you're ready to release, merge this PR and the packages will be published." >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "---" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
# Include changelog content
if [ -f "CHANGELOG.md" ]; then
tail -n +3 "CHANGELOG.md" | head -100 >> $GITHUB_OUTPUT
fi
echo "$EOF" >> $GITHUB_OUTPUT
- name: Create or update PR
if: steps.check.outputs.hasChangelogs == 'true'
id: pr
uses: peter-evans/create-pull-request@v7
with:
token: ${{ inputs.github-token }}
branch: ${{ inputs.branch }}
title: ${{ inputs.title }}
body: ${{ steps.body.outputs.body }}
base: ${{ github.ref_name }}
commit-message: ${{ inputs.commit }}
delete-branch: true
- name: Publish packages
if: steps.check.outputs.hasChangelogs == 'false' && inputs.publish != ''
id: publish
shell: bash
env:
CARGO_REGISTRY_TOKEN: ${{ inputs.crate-token }}
run: |
echo "Running publish command: ${{ inputs.publish }}"
output=$(${{ inputs.publish }} 2>&1) || true
echo "$output"
# Parse published packages from output
packages=$(echo "$output" | grep -E "^\s+\S+\s+v[0-9]" | grep "✓" | awk '{print $1}' | jq -R -s -c 'split("\n") | map(select(length > 0))')
if [ "$packages" != "[]" ] && [ -n "$packages" ]; then
echo "published=true" >> $GITHUB_OUTPUT
echo "publishedPackages=$packages" >> $GITHUB_OUTPUT
else
echo "published=false" >> $GITHUB_OUTPUT
echo "publishedPackages=[]" >> $GITHUB_OUTPUT
fi
- name: Push git tags
if: steps.check.outputs.hasChangelogs == 'false' && inputs.publish != '' && steps.publish.outputs.published == 'true'
shell: bash
run: git push --follow-tags