Skip to content

Commit febb203

Browse files
Run action locally and improve release workflow (#152)
Co-authored-by: ChristophShyper <[email protected]>
1 parent 27a6cb3 commit febb203

File tree

4 files changed

+146
-60
lines changed

4 files changed

+146
-60
lines changed

.github/VERSION-DETECTION.md

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ This file demonstrates how the automated version detection works with different
55
## Branch-Based Version Detection
66

77
### ✅ Minor Version Bump (v0.10.2 → v0.11.0)
8-
**Trigger**: Merging from `feat*` branches
8+
**Trigger**: Merging from `feat*` branches or commits with `feat:` prefix
99

1010
```bash
11-
# Developer workflow:
11+
# Feature branch workflow:
1212
git checkout master
1313
git checkout -b feat/new-user-authentication
14-
git commit -m "add OAuth login support"
15-
git commit -m "add user profile management"
14+
git commit -m "feat: add OAuth login support"
15+
git commit -m "feat: add user profile management"
1616
git push origin feat/new-user-authentication
1717

1818
# Create PR and merge to master
1919
# Result: Automatic minor version bump v0.10.2 → v0.11.0
2020
```
2121

2222
### ✅ Patch Version Bump (v0.10.2 → v0.10.3)
23-
**Trigger**: Merging from any other branch
23+
**Trigger**: Merging from any other branch or non-feature commits
2424

2525
```bash
2626
# Bug fix:
@@ -31,40 +31,90 @@ git commit -m "fix: resolve session timeout issue"
3131
# Documentation:
3232
git checkout -b docs/update-api-guide
3333
git commit -m "docs: update API documentation"
34-
# Result: v0.10.2 → v0.10.3
34+
# Result: skipped - docs don't trigger releases
3535

3636
# Refactoring:
3737
git checkout -b refactor/cleanup-auth
3838
git commit -m "refactor: simplify authentication flow"
3939
# Result: v0.10.2 → v0.10.3
4040
```
4141

42-
## Detection Priority
42+
## 🚫 Skipped Releases
43+
44+
The system automatically skips releases for:
45+
46+
- **Dependency updates**: Branches starting with `dep*` or `dependabot*`
47+
- **Documentation**: Branches starting with `docs*` or commits with `docs:`
48+
- **Release commits**: Prevents infinite loops from release automation
49+
- **Version bumps**: Updates to dependencies or version files
50+
51+
```bash
52+
# These will NOT trigger releases:
53+
git checkout -b deps/update-actions
54+
git commit -m "deps: update GitHub Actions to latest"
55+
56+
git checkout -b docs/fix-readme
57+
git commit -m "docs: fix typos in README"
58+
59+
# Direct commits to master with these patterns also skip releases
60+
```
61+
62+
## Detection Priority & Logic
4363

4464
The system checks in this order:
4565

46-
1. **Feature branches** (highest priority)
47-
- Checks merged branch names for `feat*` pattern
48-
- Also checks commit messages for `feat:` prefix
66+
1. **Skip conditions** (highest priority)
67+
- Dependency/docs/release branch patterns
68+
- Dependency/docs/release commit message patterns
69+
- Existing release commit patterns (prevents loops)
70+
71+
2. **Feature detection** (second priority)
72+
- Merged branch names matching `feat*` pattern
73+
- Commit messages with `feat:`, `feat():`, or `feature:` prefix
74+
- Breaking change indicators (treated as minor for safety)
4975
- Results in minor version bump (Y)
5076

51-
2. **Everything else** (default)
77+
3. **Everything else** (default)
5278
- All other branch merges and commits
5379
- Results in patch version bump (Z)
5480

55-
## Example Scenarios
81+
## Enhanced Example Scenarios
82+
83+
| Branch Name | Commit Message | Result | Reason |
84+
|-----------------|------------------------------|-------------------|---------------------------------|
85+
| `feat/auth` | "feat: add login system" | v0.10.2 → v0.11.0 | Feature branch + feat commit |
86+
| `fix/bug` | "fix: resolve crash" | v0.10.2 → v0.10.3 | Non-feature branch |
87+
| `docs/readme` | "docs: update guide" | **Skipped** | Documentation update |
88+
| `deps/actions` | "deps: update actions" | **Skipped** | Dependency update |
89+
| `fix/bug` | "feat: add new feature" | v0.10.2 → v0.11.0 | feat in commit message |
90+
| `refactor/code` | "BREAKING CHANGE: new API" | v0.10.2 → v0.11.0 | Breaking change (conservative) |
91+
| `any-branch` | "🤖 Fully Automated Release" | **Skipped** | Release commit (prevents loops) |
92+
93+
## Advanced Features
94+
95+
### 🔄 **Infinite Loop Prevention**
96+
- Detects its own release commits and skips them
97+
- Prevents cascading releases from automation
98+
99+
### 🎯 **Smart Branch Analysis**
100+
- Analyzes both branch names and commit messages
101+
- Handles various conventional commit formats
102+
- Conservative approach to breaking changes
103+
104+
### **Validation & Safety**
105+
- Validates version format before processing
106+
- Checks for existing tags to prevent duplicates
107+
- Provides detailed logging for debugging
56108

57-
| Branch Name | Commit Message | Version Change | Reason |
58-
|-------------|----------------|----------------|---------|
59-
| `feat/auth` | "add login system" | v0.10.2 → v0.11.0 | feat branch (minor) |
60-
| `fix/bug` | "fix: resolve crash" | v0.10.2 → v0.10.3 | non-feat branch (patch) |
61-
| `docs/readme` | "docs: update guide" | v0.10.2 → v0.10.3 | non-feat branch (patch) |
62-
| `fix/bug` | "feat: add new feature" | v0.10.2 → v0.11.0 | feat in commit (minor) |
63-
| `refactor/code` | "refactor: improve structure" | v0.10.2 → v0.10.3 | non-feat branch (patch) |
109+
### 🔧 **Manual Override**
110+
- Supports manual workflow dispatch
111+
- Allows override of auto-detection logic
112+
- Useful for emergency releases or major versions
64113

65114
This ensures that:
115+
- ✅ Major version (X) requires manual intervention for safety
66116
- ✅ New features always increment minor version (Y number)
67117
- ✅ Bug fixes and other changes increment patch version (Z number)
68-
-Major version (X) is only incremented manually
69-
-Documentation and dependency updates don't trigger releases
70-
-No manual version management needed
118+
-Documentation and dependency updates don't clutter releases
119+
-No manual version management needed for regular development
120+
-Robust protection against automation loops

.github/workflows/AUTO-RELEASE.yml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,19 @@ jobs:
6363
echo "✅ Updated Makefile fallback version to: ${VERSION}"
6464
6565
- name: Create release branch and commit changes
66-
uses: devops-infra/[email protected]
66+
uses: ./
6767
with:
6868
github_token: ${{ secrets.GITHUB_TOKEN }}
6969
target_branch: release/${{ github.event.inputs.version }}
7070
commit_message: |
71-
Automated Release ${{ github.event.inputs.version }}
72-
73-
This is an **automated release** created via workflow dispatch.
71+
🤖 Automated Release ${{ github.event.inputs.version }}
7472
7573
Release Details
7674
- **Version**: `${{ github.event.inputs.version }}`
7775
- **Type**: `${{ github.event.inputs.release_type }}`
7876
- **Triggered by**: @${{ github.actor }}
7977
- **Date**: ${{ steps.date.outputs.date }}
80-
81-
Changes in this release
82-
- ✅ Updated `action.yml` to reference Docker image `${{ github.event.inputs.version }}`
83-
- ✅ Updated `Makefile` fallback version to `${{ github.event.inputs.version }}`
84-
78+
8579
What happens when this PR is merged?
8680
1. 🐳 Docker images will be built and pushed to Docker Hub and GitHub Packages
8781
2. 🏷️ A GitHub release will be created with tag `${{ github.event.inputs.version }}`
@@ -94,4 +88,4 @@ jobs:
9488
**⚠️ Important:** Once merged, this will immediately publish Docker images to production registries.
9589
9690
---
97-
*This release was created automatically. No manual intervention required.*
91+
*🤖 Fully automated release - zero manual intervention required!*

.github/workflows/AUTO-VERSION.yml

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,21 @@ jobs:
7070
echo "$COMMIT_MESSAGES"
7171
7272
# Skip release for dependency and docs updates
73-
if echo "$MERGED_BRANCHES" | grep -iE "^dep|^dependabot|^docs|/dep|/docs"; then
74-
echo "Skipping release for dependency/docs updates"
73+
if echo "$MERGED_BRANCHES" | grep -iE "^dep|^dependabot|^docs|^release|/dep|/docs|/release"; then
74+
echo "Skipping release for dependency/docs/release updates"
7575
echo "should_release=false" >> $GITHUB_OUTPUT
7676
exit 0
7777
fi
7878
79-
if echo "$COMMIT_MESSAGES" | grep -i "^dep:\|^docs:\|^dependencies:\|^dependency:"; then
80-
echo "Skipping release for dependency/docs commits"
79+
if echo "$COMMIT_MESSAGES" | grep -iE "^dep:|^docs:|^dependencies:|^dependency:|^release:|update.*dependenc|bump.*version"; then
80+
echo "Skipping release for dependency/docs/version update commits"
81+
echo "should_release=false" >> $GITHUB_OUTPUT
82+
exit 0
83+
fi
84+
85+
# Skip if this is already a release commit to prevent infinite loops
86+
if echo "$COMMIT_MESSAGES" | grep -E "^🤖 Fully Automated Release|^🤖 Automated Release"; then
87+
echo "Skipping release for release commits to prevent loops"
8188
echo "should_release=false" >> $GITHUB_OUTPUT
8289
exit 0
8390
fi
@@ -89,7 +96,10 @@ jobs:
8996
if echo "$MERGED_BRANCHES" | grep -iE "^feat|/feat"; then
9097
VERSION_TYPE="minor"
9198
# Check for feat in commit messages as fallback
92-
elif echo "$COMMIT_MESSAGES" | grep -i "^feat\|feat:"; then
99+
elif echo "$COMMIT_MESSAGES" | grep -iE "^feat:|feat\(.*\):|^feature:"; then
100+
VERSION_TYPE="minor"
101+
# Check for breaking changes (should be major, but we'll be conservative and use minor)
102+
elif echo "$COMMIT_MESSAGES" | grep -iE "BREAKING CHANGE|breaking:|^break:"; then
93103
VERSION_TYPE="minor"
94104
# Everything else is patch (Z)
95105
else
@@ -99,8 +109,13 @@ jobs:
99109
100110
echo "Detected version type: $VERSION_TYPE"
101111
102-
# Calculate new version
112+
# Calculate new version with validation
103113
CURRENT_VERSION=${LATEST_TAG#v}
114+
if [[ ! $CURRENT_VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
115+
echo "Error: Invalid current version format: $CURRENT_VERSION" >&2
116+
exit 1
117+
fi
118+
104119
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
105120
MAJOR=${VERSION_PARTS[0]:-0}
106121
MINOR=${VERSION_PARTS[1]:-0}
@@ -116,10 +131,20 @@ jobs:
116131
patch)
117132
NEW_VERSION="v${MAJOR}.${MINOR}.$((PATCH + 1))"
118133
;;
134+
*)
135+
echo "Error: Invalid version type: $VERSION_TYPE" >&2
136+
exit 1
137+
;;
119138
esac
120139
121140
echo "New version: $NEW_VERSION"
122141
142+
# Validate new version doesn't already exist
143+
if git tag -l | grep -q "^${NEW_VERSION}$"; then
144+
echo "Error: Version $NEW_VERSION already exists" >&2
145+
exit 1
146+
fi
147+
123148
# Set outputs
124149
echo "should_release=true" >> $GITHUB_OUTPUT
125150
echo "version_type=$VERSION_TYPE" >> $GITHUB_OUTPUT
@@ -149,7 +174,7 @@ jobs:
149174
echo "✅ Updated Makefile fallback version to: ${VERSION}"
150175
151176
- name: Create release branch and commit changes
152-
uses: devops-infra/[email protected]
177+
uses: ./
153178
with:
154179
github_token: ${{ secrets.GITHUB_TOKEN }}
155180
target_branch: release/${{ needs.check_for_release.outputs.new_version }}
@@ -165,11 +190,6 @@ jobs:
165190
- **Actor**: @${{ github.actor }}
166191
- **Date**: $(date +'%Y-%m-%d %H:%M:%S UTC')
167192
168-
🔄 Automated Changes
169-
- ✅ Updated `action.yml` Docker image reference
170-
- ✅ Updated `Makefile` fallback version
171-
- ✅ Version auto-detected from commit messages
172-
173193
🚀 What happens when merged?
174194
1. 🐳 Multi-architecture Docker images built and pushed
175195
2. 🏷️ GitHub release created with auto-generated notes

.github/workflows/RELEASE.yml

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -114,30 +114,37 @@ jobs:
114114
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
115115
TERM: xterm-256color
116116
VERSION: ${{ steps.version.outputs.version }}
117-
run: make push
117+
run: |
118+
echo "Building and pushing Docker images for version: $VERSION"
119+
make push || {
120+
echo "❌ Docker build/push failed"
121+
exit 1
122+
}
123+
echo "✅ Docker images built and pushed successfully"
118124
119125
- name: Create GitHub Release
120126
uses: softprops/[email protected]
121127
with:
122128
tag_name: ${{ steps.version.outputs.version }}
123-
name: Release ${{ steps.version.outputs.version }}
129+
name: ${{ steps.version.outputs.version }}
124130
body: |
125131
## Release ${{ steps.version.outputs.version }}
126132
127-
This release was automatically created after merging the release PR.
128-
129-
### Docker Images
130-
- **Docker Hub:** `devopsinfra/action-commit-push:${{ steps.version.outputs.version }}`
131-
- **GitHub Packages:** `ghcr.io/devops-infra/action-commit-push:${{ steps.version.outputs.version }}`
132-
133-
Both images are built for `amd64` and `arm64` architectures.
134-
135-
### Usage
133+
### 🚀 Usage
136134
```yaml
137135
- uses: devops-infra/action-commit-push@${{ steps.version.outputs.version }}
136+
with:
137+
github_token: ${{ secrets.GITHUB_TOKEN }}
138+
commit_message: "Your commit message"
138139
```
139140
140-
For full documentation, see the [README](https://github.com/devops-infra/action-commit-push#readme).
141+
### 📦 Docker Images
142+
- `docker://devopsinfra/action-commit-push:${{ steps.version.outputs.version }}`
143+
- `docker://devopsinfra/action-commit-push:latest`
144+
145+
### 🏗️ Architecture Support
146+
- `linux/amd64`
147+
- `linux/arm64`
141148
generate_release_notes: true
142149
draft: false
143150
prerelease: false
@@ -152,10 +159,25 @@ jobs:
152159

153160
- name: Clean up release branch
154161
run: |
162+
RELEASE_BRANCH="${{ github.event.pull_request.head.ref }}"
163+
echo "Attempting to clean up release branch: $RELEASE_BRANCH"
164+
155165
# Check if the release branch exists before attempting to delete it
156-
if git ls-remote --exit-code origin "${{ github.event.pull_request.head.ref }}"; then
157-
echo "Deleting branch \"${{ github.event.pull_request.head.ref }}\"..."
158-
git push origin --delete "${{ github.event.pull_request.head.ref }}"
166+
if git ls-remote --exit-code --heads origin "$RELEASE_BRANCH" >/dev/null 2>&1; then
167+
echo "✅ Branch $RELEASE_BRANCH exists on remote, deleting..."
168+
git push origin --delete "$RELEASE_BRANCH" || {
169+
echo "⚠️ Warning: Failed to delete remote branch $RELEASE_BRANCH"
170+
echo "This is not critical - the branch can be cleaned up manually"
171+
}
172+
echo "✅ Remote branch $RELEASE_BRANCH deleted successfully"
159173
else
160-
echo "Branch ${{ github.event.pull_request.head.ref }} does not exist. Skipping deletion."
174+
echo "ℹ️ Branch $RELEASE_BRANCH does not exist on remote (may have been auto-deleted)"
175+
fi
176+
177+
# Also try to clean up any local reference
178+
if git show-ref --verify --quiet "refs/heads/$RELEASE_BRANCH"; then
179+
echo "🧹 Cleaning up local branch reference..."
180+
git branch -D "$RELEASE_BRANCH" 2>/dev/null || true
161181
fi
182+
183+
echo "✅ Branch cleanup completed"

0 commit comments

Comments
 (0)