Skip to content

Commit 2831c64

Browse files
fboundyclaude
andcommitted
Auto-release on merge to main from patch/dev
Adds a pull_request(closed) trigger: merging a PR from branch `patch` bumps the manifest PATCH version, merging from `dev` bumps MINOR and resets PATCH to 0. Any other source branch is a no-op (workflow_dispatch remains available for manual releases with a bump-type input). Also fixes COMPONENT_NAME (was still "solis_modbus" from before the rebrand, which would have made every step operate on a nonexistent path). Requires a repo secret named PAT (a personal access token from an account with bypass rights on the protected main branch) for both the version-bump push and the release upload — main requires PRs, and only a PAT-authenticated push (not the default GITHUB_TOKEN) will trigger this branch's required status checks on the bump commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 3ab0225 commit 2831c64

1 file changed

Lines changed: 57 additions & 58 deletions

File tree

‎.github/workflows/release.yaml‎

Lines changed: 57 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,97 @@
11
name: Release
22

33
on:
4+
pull_request:
5+
types: [closed]
6+
branches: [main]
47
workflow_dispatch:
8+
inputs:
9+
bump:
10+
description: "Version part to bump"
11+
required: true
12+
type: choice
13+
options: [patch, minor, major]
14+
default: patch
515

616
env:
7-
COMPONENT_NAME: solis_modbus
17+
COMPONENT_NAME: solisconnect
818

919
jobs:
1020
release:
1121
name: Prepare release
22+
# Only release for: a manual run, or a merged (not just closed) PR from patch/dev into main.
23+
if: |
24+
github.event_name == 'workflow_dispatch' ||
25+
(github.event.pull_request.merged == true &&
26+
contains(fromJson('["patch", "dev"]'), github.event.pull_request.head.ref))
1227
runs-on: ubuntu-latest
1328
permissions:
1429
contents: write
15-
id-token: write
1630
steps:
1731
- uses: actions/checkout@v4
1832
with:
33+
ref: main
1934
fetch-depth: 0
35+
# A PAT (not the default GITHUB_TOKEN) is required: main is protected and only an
36+
# admin's own credentials can push directly to it, and only a PAT-authenticated push
37+
# will trigger the branch's required status-check workflows on the bump commit.
38+
token: ${{ secrets.PAT }}
2039

21-
- name: Install jq
22-
run: sudo apt-get install jq
23-
24-
- name: Install Python semver
25-
run: pip install semver
26-
27-
- name: Get latest tag or fail
28-
id: get-latest-tag
29-
run: |
30-
latest_tag=$(git for-each-ref --sort=version:refname --format '%(refname)' refs/tags/ | grep -v 'latest' | tail -1 | sed 's/^refs\/tags\///; s/^v//')
31-
if [ -z "$latest_tag" ]; then
32-
echo "No tags found for the commit."
33-
exit 1
34-
fi
35-
echo "latest_tag=$latest_tag" >> $GITHUB_ENV
36-
37-
- name: Get current version from manifest.json
38-
id: get-version
40+
- name: Install jq and semver
3941
run: |
40-
current_version=$(cat "${{ github.workspace }}/custom_components/${{ env.COMPONENT_NAME }}/manifest.json" | jq -r '.version')
41-
echo "version=$current_version" >> $GITHUB_ENV
42-
43-
- name: Check if version is higher and bump if needed
44-
id: check-version
42+
sudo apt-get install -y jq
43+
pip install semver
44+
45+
- name: Determine bump type
46+
# Values are passed via env, not interpolated into the script, so an attacker-controlled
47+
# branch name (e.g. a fork PR's head ref) can't inject shell commands here.
48+
env:
49+
EVENT_NAME: ${{ github.event_name }}
50+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
51+
BUMP_INPUT: ${{ inputs.bump }}
4552
run: |
46-
latest="${{ env.latest_tag }}"
47-
current="${{ env.version }}"
48-
49-
echo "Current version: $current"
50-
echo "Latest tag: $latest"
51-
52-
# Check if latest tag is a valid SemVer string
53-
if ! python -c "import semver; semver.VersionInfo.parse('$latest')" > /dev/null 2>&1; then
54-
echo "Latest tag '$latest' is not a valid SemVer version, treating it as the current version."
55-
latest=$current # Treat invalid tag as current version
56-
fi
57-
58-
# Check if current version is higher than the latest tag (which is now set to current if invalid)
59-
is_higher=$(python -c "import semver; print(semver.compare('$current', '$latest') > 0)")
60-
61-
if [ "$is_higher" != "True" ]; then
62-
echo "The version is not higher. Bumping patch version..."
63-
bumped=$(python -c "import semver; print(semver.bump_patch('$latest'))")
64-
echo "New version: $bumped"
65-
jq ".version = \"$bumped\"" "${{ github.workspace }}/custom_components/${{ env.COMPONENT_NAME }}/manifest.json" > package.tmp.json && mv package.tmp.json "${{ github.workspace }}/custom_components/${{ env.COMPONENT_NAME }}/manifest.json"
66-
echo "version=$bumped" >> $GITHUB_ENV
53+
if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
54+
bump="$BUMP_INPUT"
55+
elif [ "$HEAD_REF" = "dev" ]; then
56+
bump="minor"
6757
else
68-
echo "version=$current" >> $GITHUB_ENV
58+
bump="patch"
6959
fi
60+
echo "Bump type: $bump"
61+
echo "bump=$bump" >> "$GITHUB_ENV"
7062
71-
echo "is_higher_version=true" >> $GITHUB_ENV
63+
- name: Bump version in manifest.json
64+
run: |
65+
manifest="custom_components/${{ env.COMPONENT_NAME }}/manifest.json"
66+
current=$(jq -r '.version' "$manifest")
67+
new=$(python -c "import semver; print(semver.bump_${{ env.bump }}('$current'))")
68+
echo "Bumping $current -> $new (${{ env.bump }})"
69+
jq ".version = \"$new\"" "$manifest" > package.tmp.json && mv package.tmp.json "$manifest"
70+
echo "version=$new" >> "$GITHUB_ENV"
7271
7372
- name: Commit and push version bump
74-
if: env.is_higher_version == 'true'
7573
run: |
76-
git config user.name "github-actions"
77-
git config user.email "github-actions@github.com"
78-
git add custom_components/${{ env.COMPONENT_NAME }}/manifest.json
79-
git diff --exit-code || (git commit -m "chore: bump version to v${{ env.version }}" && git push)
74+
git config user.name "github-actions[bot]"
75+
git config user.email "github-actions[bot]@users.noreply.github.com"
76+
git add "custom_components/${{ env.COMPONENT_NAME }}/manifest.json"
77+
git commit -m "chore: release v${{ env.version }}"
78+
git push origin HEAD:main
8079
8180
- name: Zip ${{ env.COMPONENT_NAME }} dir
8281
run: |
83-
cd "${{ github.workspace }}/custom_components/${{ env.COMPONENT_NAME }}"
84-
zip ${{ env.COMPONENT_NAME }}.zip -r ./
82+
cd "custom_components/${{ env.COMPONENT_NAME }}"
83+
zip "${{ env.COMPONENT_NAME }}.zip" -r ./
8584
8685
- name: Upload zip to release
87-
if: env.is_higher_version == 'true'
8886
uses: softprops/action-gh-release@v2
8987
with:
90-
files: ${{ github.workspace }}/custom_components/${{ env.COMPONENT_NAME }}/${{ env.COMPONENT_NAME }}.zip
88+
files: custom_components/${{ env.COMPONENT_NAME }}/${{ env.COMPONENT_NAME }}.zip
9189
tag_name: v${{ env.version }}
9290
name: v${{ env.version }}
9391
token: ${{ secrets.PAT }}
9492
generate_release_notes: true
9593

9694
- name: 🏷️ Update latest tag
97-
if: env.is_higher_version == 'true'
9895
uses: EndBug/latest-tag@latest
96+
with:
97+
github-token: ${{ secrets.PAT }}

0 commit comments

Comments
 (0)