1- name : Auto Release on Release Branch
1+ name : Auto Release on Main Branch
22
33on :
44 pull_request :
55 types : [ closed ]
6- branches : [ release ]
6+ branches : [ main ]
77
88permissions :
99 contents : write
1010
1111jobs :
1212 auto-release :
13- # Only run if PR was merged to release branch (not just closed)
14- if : github.event.pull_request.merged == true
13+ # Only run if PR was merged from release branch to main and contains release label
14+ if : github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'release' && contains(github.event.pull_request.labels.*.name, 'release')
1515 runs-on : ubuntu-latest
1616
1717 steps :
@@ -20,96 +20,179 @@ jobs:
2020 with :
2121 fetch-depth : 0
2222
23- - name : Extract tags from PR labels
24- id : get_tags_labels
23+ - name : Extract and validate required labels
24+ id : get_labels
2525 run : |
26- # Get PR labels and extract version
26+ # Get PR labels
2727 LABELS='${{ toJson(github.event.pull_request.labels.*.name) }}'
2828 echo "PR Labels: $LABELS"
2929
30- # Look for version label (e.g., "v1 .0.0", "version:1.0.0", etc.)
31- VERSION=$(echo $LABELS | jq -r '.[] | select(test("^(v|version:)? [0-9]+\\.[0-9]+\\.[0-9]+")) | gsub("^(v|version:)"; "" )')
30+ # Look for version label in x.x.x format (e.g., "1 .0.0", "2.1.3") - MANDATORY
31+ VERSION=$(echo $LABELS | jq -r '.[] | select(test("^[0-9]+\\.[0-9]+\\.[0-9]+$") )')
3232
33- # Look for zeam network tags (devnet0, devnet1, testnet, mainnet)
34- ZEAM_TAG=$(echo $LABELS | jq -r '.[] | select(test("^(devnet[0-9]+|testnet[0-9]*|mainnet)$"))')
33+ # Look for devnet labels (devnet0, devnet1, devnet2, etc.) - MANDATORY
34+ DEVNET_LABEL=$(echo $LABELS | jq -r '.[] | select(test("^devnet[0-9]+$"))')
35+
36+ # Check for mandatory labels - both version and devnet are required
37+ MISSING_LABELS=""
3538
3639 if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
37- echo "ℹ️ No version label found"
38- else
39- echo "version=$VERSION" >> $GITHUB_OUTPUT
40- echo "git_tag=v$VERSION" >> $GITHUB_OUTPUT
41- echo "✅ Version found: $VERSION"
40+ MISSING_LABELS="version label (e.g., 1.0.0)"
4241 fi
4342
44- if [ -n "$ZEAM_TAG" ] && [ "$ZEAM_TAG" != "null" ]; then
45- echo "zeam_tag=$ZEAM_TAG" >> $GITHUB_OUTPUT
46- echo "has_network_tag=true" >> $GITHUB_OUTPUT
47- echo "✅ Found network tag: $ZEAM_TAG"
48- else
49- echo "has_network_tag=false" >> $GITHUB_OUTPUT
50- echo "ℹ️ No network tag found (optional)"
43+ if [ -z "$DEVNET_LABEL" ] || [ "$DEVNET_LABEL" = "null" ]; then
44+ if [ -n "$MISSING_LABELS" ]; then
45+ MISSING_LABELS="$MISSING_LABELS and devnet label (devnet0, devnet1, devnet2, etc.)"
46+ else
47+ MISSING_LABELS="devnet label (devnet0, devnet1, devnet2, etc.)"
48+ fi
5149 fi
5250
53- # Require at least one label (version or network)
54- if { [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; } && { [ -z "$ZEAM_TAG" ] || [ "$ZEAM_TAG" = "null" ]; }; then
55- echo "❌ No usable label found! Please add a version (e.g. v1.0.0) or network tag (e.g. devnet0, testnet, mainnet)"
51+ # Exit if any required labels are missing
52+ if [ -n "$MISSING_LABELS" ]; then
53+ echo "❌ Missing required labels: $MISSING_LABELS"
54+ echo "Please add all required labels to proceed with the release."
5655 exit 1
5756 fi
5857
59- - name : Create and push git tags
60- id : create_tags
58+ # Check if version tag already exists (add 'v' prefix for git tag)
59+ VERSION_TAG="v$VERSION"
60+ if git rev-parse "$VERSION_TAG" >/dev/null 2>&1; then
61+ echo "❌ Version tag $VERSION_TAG already exists. Please use a new version."
62+ exit 1
63+ fi
64+
65+ # Create proper naming to avoid branch/tag conflicts
66+ DEVNET_TAG="$(echo $DEVNET_LABEL | sed 's/^d/D/')" # devnet1 -> Devnet1
67+ DEVNET_BRANCH="$DEVNET_LABEL" # devnet1
68+
69+ # Set outputs only after validation passes
70+ echo "version=$VERSION" >> $GITHUB_OUTPUT
71+ echo "git_tag=$VERSION_TAG" >> $GITHUB_OUTPUT
72+ echo "devnet_label=$DEVNET_LABEL" >> $GITHUB_OUTPUT
73+ echo "devnet_tag=$DEVNET_TAG" >> $GITHUB_OUTPUT
74+ echo "devnet_branch=$DEVNET_BRANCH" >> $GITHUB_OUTPUT
75+ echo "✅ Found version: $VERSION and devnet label: $DEVNET_LABEL"
76+ echo "✅ Will create branch: $DEVNET_BRANCH and tag: $DEVNET_TAG"
77+
78+ echo "✅ All required labels validated"
79+
80+ - name : Delete existing devnet tag and release if present
81+ run : |
82+ DEVNET_TAG="${{ steps.get_labels.outputs.devnet_tag }}"
83+
84+ # Check if tag exists and delete it
85+ if git rev-parse "$DEVNET_TAG" >/dev/null 2>&1; then
86+ echo "🗑️ Deleting existing tag $DEVNET_TAG"
87+ git tag -d "$DEVNET_TAG" 2>/dev/null || true
88+ git push origin --delete "$DEVNET_TAG" 2>/dev/null || true
89+ echo "✅ Deleted existing tag $DEVNET_TAG"
90+ else
91+ echo "ℹ️ Tag $DEVNET_TAG does not exist"
92+ fi
93+
94+ # Delete GitHub release if it exists
95+ echo "🗑️ Attempting to delete existing GitHub release $DEVNET_TAG"
96+ gh release delete "$DEVNET_TAG" --yes 2>/dev/null || echo "ℹ️ Release $DEVNET_TAG does not exist or already deleted"
97+ env :
98+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
99+
100+ - name : Create/Update devnet branch
61101 run : |
62102 git config user.name "github-actions[bot]"
63103 git config user.email "github-actions[bot]@users.noreply.github.com"
64104
65- CREATE_VERSION_TAG=false
66- CREATE_NETWORK_TAG=false
105+ DEVNET_BRANCH="${{ steps.get_labels.outputs.devnet_branch }}"
67106
68- # Check if version tag should be created
69- if [ -n "${{ steps.get_tags_labels.outputs.version }}" ] && [ "${{ steps.get_tags_labels.outputs.version }}" != "null" ] ; then
70- if git rev-parse "${{ steps.get_tags_labels.outputs.git_tag }}" >/dev/null 2>&1; then
71- echo "❌ Version tag ${{ steps.get_tags_labels.outputs.git_tag }} already exists. Please create a new tag. "
72- exit 1
73- else
74- CREATE_VERSION_TAG=true
75- fi
107+ # Check if devnet branch already exists remotely
108+ if git ls-remote --heads origin "$DEVNET_BRANCH" | grep -q "$DEVNET_BRANCH" ; then
109+ echo "ℹ️ Branch $DEVNET_BRANCH already exists remotely"
110+ git checkout "$DEVNET_BRANCH "
111+ git pull origin "$DEVNET_BRANCH"
112+ else
113+ echo "✅ Creating new branch $DEVNET_BRANCH from main"
114+ git checkout -b "$DEVNET_BRANCH"
76115 fi
77116
78- # Check if network tag should be created
79- if [ "${{ steps.get_tags_labels.outputs.has_network_tag }}" = "true" ]; then
80- ZEAM_GIT_TAG="${{ steps.get_tags_labels.outputs.zeam_tag }}"
81- if git rev-parse "$ZEAM_GIT_TAG" >/dev/null 2>&1; then
82- echo "❌ Network tag $ZEAM_GIT_TAG already exists. Please create a new tag."
83- exit 1
84- else
85- CREATE_NETWORK_TAG=true
86- fi
87- fi
117+ # Merge latest main changes into devnet branch
118+ git merge main --no-ff -m "Merge main into $DEVNET_BRANCH for deployment"
119+ git push -u origin "$DEVNET_BRANCH"
120+ echo "✅ Updated branch $DEVNET_BRANCH with latest main changes"
88121
89- # Create version tag if needed
90- if [ "$CREATE_VERSION_TAG" = "true" ]; then
91- git tag -a "${{ steps.get_tags_labels.outputs.git_tag }}" -m "Release version ${{ steps.get_tags_labels.outputs.version }}"
92- git push origin "${{ steps.get_tags_labels.outputs.git_tag }}"
93- echo "✅ Created version tag ${{ steps.get_tags_labels.outputs.git_tag }}"
122+ # Switch back to main for tagging
123+ git checkout main
124+
125+ - name : Generate changelog
126+ id : changelog
127+ run : |
128+ # Get the last devnet tag for changelog comparison
129+ CURRENT_DEVNET_TAG="${{ steps.get_labels.outputs.devnet_tag }}"
130+ DEVNET_TAG_PREFIX="$(echo ${{ steps.get_labels.outputs.devnet_label }} | sed 's/^d/D/')"
131+ LAST_DEVNET_TAG=$(git tag -l "${DEVNET_TAG_PREFIX}*" --sort=-version:refname | grep -v "^$CURRENT_DEVNET_TAG$" | head -n 1)
132+
133+ if [ -z "$LAST_DEVNET_TAG" ]; then
134+ echo "ℹ️ No previous devnet tag found, generating changelog from last 20 commits"
135+ # Get commits with author and PR info for GitHub-style format
136+ CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20 | sed 's/ by @/ by @/g' | sed 's/ in / in #/g')
137+ else
138+ echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current"
139+ # Get commits between tags with author and PR info
140+ CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" $LAST_DEVNET_TAG..HEAD | sed 's/ by @/ by @/g' | sed 's/ in / in #/g')
94141 fi
95142
96- # Create network tag if needed
97- if [ "$CREATE_NETWORK_TAG" = "true" ]; then
98- git tag -a "$ZEAM_GIT_TAG" -m "Zeam network tag for $ZEAM_GIT_TAG"
99- git push origin "$ZEAM_GIT_TAG"
100- echo "✅ Created zeam tag $ZEAM_GIT_TAG"
143+ # If no commits found, add a default message
144+ if [ -z "$CHANGELOG" ]; then
145+ CHANGELOG="- No changes found in this release"
101146 fi
102- echo "create_version_tag=$CREATE_VERSION_TAG" >> $GITHUB_OUTPUT
103- echo "create_network_tag=$CREATE_NETWORK_TAG" >> $GITHUB_OUTPUT
147+
148+ # Create release notes with GitHub-style changelog
149+ cat > release_notes.md << EOF
150+ # Release Notes
151+
152+ **Network:** ${{ steps.get_labels.outputs.devnet_label }}
153+ **Version:** ${{ steps.get_labels.outputs.version }}
154+ **Tag:** ${{ steps.get_labels.outputs.devnet_tag }}
155+ **Branch:** ${{ steps.get_labels.outputs.devnet_branch }}
156+ **Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
157+
158+ ## What's Changed
159+
160+ ${CHANGELOG}
161+
162+ **Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ steps.get_labels.outputs.devnet_tag }}
163+
164+ EOF
165+
166+ echo "✅ Generated changelog with $(echo "$CHANGELOG" | wc -l) commits"
167+ echo "changelog_file=release_notes.md" >> $GITHUB_OUTPUT
168+
169+ - name : Create and push tags on main
170+ id : create_tags
171+ run : |
172+ git config user.name "github-actions[bot]"
173+ git config user.email "github-actions[bot]@users.noreply.github.com"
174+
175+ VERSION_TAG="${{ steps.get_labels.outputs.git_tag }}"
176+ DEVNET_TAG="${{ steps.get_labels.outputs.devnet_tag }}"
177+
178+ # Create version tag on main
179+ git tag -a "$VERSION_TAG" -m "Release version ${{ steps.get_labels.outputs.version }}"
180+ git push origin "$VERSION_TAG"
181+ echo "✅ Created version tag $VERSION_TAG on main branch"
182+
183+ # Create devnet tag on main (already deleted if existed)
184+ git tag -a "$DEVNET_TAG" -m "Devnet deployment tag for $DEVNET_TAG"
185+ git push origin "$DEVNET_TAG"
186+ echo "✅ Created devnet tag $DEVNET_TAG on main branch"
104187
105188 - name : Create GitHub Release
106- if : ${{ steps.create_tags.outputs.create_version_tag == 'true' || steps.create_tags.outputs.create_network_tag == 'true' }}
107189 uses : softprops/action-gh-release@v1
108190 with :
109- tag_name : ${{ steps.get_tags_labels .outputs.git_tag != '' && steps.get_tags_labels.outputs.git_tag != 'null' && steps.get_tags_labels.outputs.git_tag || steps.get_tags_labels.outputs.zeam_tag }}
110- name : Release ${{ steps.get_tags_labels .outputs.git_tag != '' && steps.get_tags_labels .outputs.git_tag != 'null' && steps.get_tags_labels.outputs.git_tag || steps.get_tags_labels.outputs.zeam_tag }}
111- body_path : ./README.md
191+ tag_name : ${{ steps.get_labels .outputs.devnet_tag }}
192+ name : Release ${{ steps.get_labels .outputs.version }} - ${{ steps.get_labels .outputs.devnet_tag }}
193+ body_path : ${{ steps.changelog.outputs.changelog_file }}
112194 draft : false
113- prerelease : false
195+ prerelease : true
196+ target_commitish : main
114197 env :
115198 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments