@@ -66,10 +66,94 @@ jobs:
6666 go build -v ./cmd/agent
6767 ./arcane-agent --help || echo "Binary built successfully"
6868
69+ version-check :
70+ name : Check Version Bump
71+ runs-on : ubuntu-latest
72+ if : github.event_name == 'push' && github.ref == 'refs/heads/main'
73+ outputs :
74+ should_release : ${{ steps.version.outputs.should_release }}
75+ new_version : ${{ steps.version.outputs.new_version }}
76+ release_type : ${{ steps.version.outputs.release_type }}
77+ changelog : ${{ steps.version.outputs.changelog }}
78+ steps :
79+ - uses : actions/checkout@v4
80+ with :
81+ fetch-depth : 0 # Need full history for conventional commits
82+
83+ - name : Determine version bump
84+ id : version
85+ run : |
86+ # Get the latest tag
87+ LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
88+ echo "Latest tag: $LATEST_TAG"
89+
90+ # Extract current version (remove 'v' prefix)
91+ CURRENT_VERSION=${LATEST_TAG#v}
92+ echo "Current version: $CURRENT_VERSION"
93+
94+ # Function to increment version
95+ increment_version() {
96+ local version=$1
97+ local part=$2
98+ IFS='.' read -r -a parts <<<"$version"
99+ case $part in
100+ "major")
101+ parts[0]=$((parts[0] + 1))
102+ parts[1]=0
103+ parts[2]=0
104+ ;;
105+ "minor")
106+ parts[1]=$((parts[1] + 1))
107+ parts[2]=0
108+ ;;
109+ "patch")
110+ parts[2]=$((parts[2] + 1))
111+ ;;
112+ esac
113+ echo "${parts[0]}.${parts[1]}.${parts[2]}"
114+ }
115+
116+ # Check for breaking changes (major version bump)
117+ if git log "$LATEST_TAG"..HEAD --oneline | grep -E "BREAKING CHANGE|feat!:|fix!:" | grep -q .; then
118+ RELEASE_TYPE="major"
119+ echo "Found breaking changes - major release"
120+ # Check for new features (minor version bump)
121+ elif git log "$LATEST_TAG"..HEAD --oneline | grep -E "feat(\(.*\))?:" | grep -q .; then
122+ RELEASE_TYPE="minor"
123+ echo "Found new features - minor release"
124+ # Check for bug fixes (patch version bump)
125+ elif git log "$LATEST_TAG"..HEAD --oneline | grep -E "fix(\(.*\))?:" | grep -q .; then
126+ RELEASE_TYPE="patch"
127+ echo "Found bug fixes - patch release"
128+ else
129+ echo "No conventional commits found - no release needed"
130+ echo "should_release=false" >> $GITHUB_OUTPUT
131+ exit 0
132+ fi
133+
134+ # Calculate new version
135+ NEW_VERSION=$(increment_version $CURRENT_VERSION $RELEASE_TYPE)
136+ echo "New version: $NEW_VERSION"
137+
138+ # Generate changelog from conventional commits
139+ CHANGELOG=$(git log "$LATEST_TAG"..HEAD --pretty=format:"- %s" --grep="feat\|fix\|BREAKING" | head -20)
140+ if [ -z "$CHANGELOG" ]; then
141+ CHANGELOG="- Various improvements and bug fixes"
142+ fi
143+
144+ # Set outputs
145+ echo "should_release=true" >> $GITHUB_OUTPUT
146+ echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
147+ echo "release_type=$RELEASE_TYPE" >> $GITHUB_OUTPUT
148+ echo "changelog<<EOF" >> $GITHUB_OUTPUT
149+ echo "$CHANGELOG" >> $GITHUB_OUTPUT
150+ echo "EOF" >> $GITHUB_OUTPUT
151+
69152 build :
70153 name : Build
71154 runs-on : ubuntu-latest
72155 needs : test
156+ if : always() && (needs.test.result == 'success')
73157 strategy :
74158 matrix :
75159 include :
@@ -178,17 +262,79 @@ jobs:
178262 cache-from : type=gha
179263 cache-to : type=gha,mode=max
180264
181- release :
182- name : Create Release
265+ auto-release :
266+ name : Auto Release
267+ runs-on : ubuntu-latest
268+ needs : [test, build, version-check]
269+ if : needs.version-check.outputs.should_release == 'true'
270+ steps :
271+ - uses : actions/checkout@v4
272+ with :
273+ token : ${{ secrets.GITHUB_TOKEN }}
274+ fetch-depth : 0
275+
276+ - name : Configure Git
277+ run : |
278+ git config --local user.email "[email protected] " 279+ git config --local user.name "GitHub Action"
280+
281+ - name : Create version tag
282+ env :
283+ NEW_VERSION : ${{ needs.version-check.outputs.new_version }}
284+ run : |
285+ # Create and push tag
286+ git tag "v$NEW_VERSION"
287+ git push origin "v$NEW_VERSION"
288+
289+ - name : Download all artifacts
290+ uses : actions/download-artifact@v4
291+ with :
292+ path : artifacts
293+
294+ - name : Prepare release assets
295+ run : |
296+ mkdir -p release
297+ for dir in artifacts/*/; do
298+ if [ -d "$dir" ]; then
299+ cp "$dir"/* "release/" 2>/dev/null || true
300+ fi
301+ done
302+ ls -la release/
303+
304+ - name : Create GitHub Release
305+ uses : softprops/action-gh-release@v1
306+ with :
307+ tag_name : v${{ needs.version-check.outputs.new_version }}
308+ name : Release v${{ needs.version-check.outputs.new_version }}
309+ body : |
310+ ## Changes in v${{ needs.version-check.outputs.new_version }}
311+
312+ This is a ${{ needs.version-check.outputs.release_type }} release.
313+
314+ ### Changes:
315+ ${{ needs.version-check.outputs.changelog }}
316+
317+ ### Assets
318+ - Linux (amd64, arm64)
319+ - macOS (amd64, arm64)
320+ - Windows (amd64)
321+ - Docker images: `ghcr.io/ofkm/arcane-agent:v${{ needs.version-check.outputs.new_version }}`
322+ files : release/*
323+ draft : false
324+ prerelease : false
325+ env :
326+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
327+
328+ manual-release :
329+ name : Manual Release
183330 runs-on : ubuntu-latest
184331 needs : [test, build]
185332 if : startsWith(github.ref, 'refs/tags/v')
186-
187333 steps :
188334 - uses : actions/checkout@v4
189335
190336 - name : Download all artifacts
191- uses : actions/download-artifact@v3
337+ uses : actions/download-artifact@v4
192338 with :
193339 path : artifacts
194340
0 commit comments