-
Notifications
You must be signed in to change notification settings - Fork 21
update release process #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR updates the release process by modifying the GitHub Actions workflow to trigger on PRs merged to main (instead of release) and adds comprehensive documentation explaining the automated devnet release process.
Changes:
- Modified the auto-release workflow to trigger on PR merges to main branch from release branch
- Added mandatory label validation for both version and devnet labels
- Implemented devnet branch management, tag creation, and changelog generation
- Created comprehensive documentation (release-process.md) detailing the step-by-step release process, naming conventions, error scenarios, and best practices
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| .github/workflows/auto-release.yml | Complete workflow refactor to support devnet-based releases with label validation, branch/tag management, and automated changelog generation |
| release-process.md | New documentation file explaining the entire release process, prerequisites, naming conventions, and troubleshooting guidance |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| fi | ||
| fi | ||
| # Merge latest main changes into devnet branch | ||
| git merge main --no-ff -m "Merge main into $DEVNET_BRANCH for deployment" |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The merge operation may fail if there are conflicts between the main branch and the existing devnet branch. This scenario is not handled, and the workflow will fail without a clear resolution path. Consider adding conflict detection and appropriate error messaging to guide users on how to resolve conflicts manually.
| # Get commits with author and PR info for GitHub-style format | ||
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20 | sed 's/ by @/ by @/g' | sed 's/ in / in #/g') | ||
| else | ||
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | ||
| # Get commits between tags with author and PR info | ||
| 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') |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sed substitutions being used here are redundant and incorrect. The pattern 's/ by @/ by @/g' replaces " by @" with " by @" (same text), and 's/ in / in #/g' replaces " in " with " in #" which doesn't properly prepend '#' to commit hashes. The intent appears to be formatting the commit hash with '#', but this will result in text like "in #abc123" instead of proper GitHub commit references. Consider using the proper format string in git log or adjusting the sed pattern to correctly format the output.
| # Get commits with author and PR info for GitHub-style format | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20 | sed 's/ by @/ by @/g' | sed 's/ in / in #/g') | |
| else | |
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | |
| # Get commits between tags with author and PR info | |
| 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') | |
| # Get commits with author and hash info for GitHub-style format | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20) | |
| else | |
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | |
| # Get commits between tags with author and hash info | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" $LAST_DEVNET_TAG..HEAD) |
| # Get commits with author and PR info for GitHub-style format | ||
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20 | sed 's/ by @/ by @/g' | sed 's/ in / in #/g') | ||
| else | ||
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | ||
| # Get commits between tags with author and PR info | ||
| 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') |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as line 136 - the sed substitutions are redundant and incorrect. The pattern 's/ by @/ by @/g' doesn't change anything, and 's/ in / in #/g' doesn't properly format commit references for GitHub.
| # Get commits with author and PR info for GitHub-style format | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20 | sed 's/ by @/ by @/g' | sed 's/ in / in #/g') | |
| else | |
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | |
| # Get commits between tags with author and PR info | |
| 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') | |
| # Get commits with author and commit info for GitHub-style format | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" | head -20) | |
| else | |
| echo "ℹ️ Generating changelog from $LAST_DEVNET_TAG to current" | |
| # Get commits between tags with author and commit info | |
| CHANGELOG=$(git log --oneline --pretty=format:"- %s by @%an in %h" $LAST_DEVNET_TAG..HEAD) |
| - **Version label** - Format: `0.2.0` | ||
| - Examples: `1.2.3`, `2.0.1` |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states that the version label format should be 0.2.0 (with a leading zero for devnet releases), but the examples show 1.2.3 and 2.0.1. This is inconsistent and confusing. According to the Best Practices section (lines 110-119), devnet releases should follow the 0.X.Y format where the first digit is always 0. Either update the examples to follow this convention or clarify that the format shown is just an example and doesn't enforce the 0.X.Y convention.
| - **Devnet Tag**: `Devnet1` (capitalized) - Deployment environment tag | ||
|
|
||
| ### GitHub Release | ||
| - **Name**: `Release v1.2.0 - Devnet1` |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GitHub Release name format documented here as "Release v1.2.0 - Devnet1" is inconsistent with the actual workflow implementation. According to line 192 of the workflow, the actual format is "Release $version - $devnet_tag" which would produce "Release 1.2.0 - Devnet1" (without the 'v' prefix on the version number). Update this to match the actual implementation.
| - **Name**: `Release v1.2.0 - Devnet1` | |
| - **Name**: `Release 1.2.0 - Devnet1` |
| ${CHANGELOG} | ||
|
|
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The heredoc (lines 149-164) uses variable interpolation with GitHub Actions expressions like ${{ steps.get_labels.outputs.devnet_label }}. However, if the CHANGELOG variable contains special characters or formatting, it could break the heredoc structure or produce unexpected output. Consider using a different approach to write the release notes, such as using proper quoting or writing the file programmatically with echo statements that properly escape content.
| ${CHANGELOG} | |
| EOF | |
| # Append the changelog content safely without further shell expansion | |
| printf '%s\n' "$CHANGELOG" >> release_notes.md | |
| printf '\n' >> release_notes.md | |
| cat >> release_notes.md << EOF |
| run: | | ||
| # Get the last devnet tag for changelog comparison | ||
| CURRENT_DEVNET_TAG="${{ steps.get_labels.outputs.devnet_tag }}" | ||
| DEVNET_TAG_PREFIX="$(echo ${{ steps.get_labels.outputs.devnet_label }} | sed 's/^d/D/')" |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tag prefix calculation duplicates the logic from line 66 but is calculated again here. This duplication could lead to maintenance issues if the naming convention changes. Consider reusing the devnet_tag output from the get_labels step instead of recalculating it.
| DEVNET_TAG_PREFIX="$(echo ${{ steps.get_labels.outputs.devnet_label }} | sed 's/^d/D/')" | |
| VERSION="${{ steps.get_labels.outputs.version }}" | |
| DEVNET_TAG_PREFIX="${CURRENT_DEVNET_TAG%-${VERSION}}" |
| git checkout "$DEVNET_BRANCH" | ||
| git pull origin "$DEVNET_BRANCH" | ||
| else | ||
| echo "✅ Creating new branch $DEVNET_BRANCH from main" | ||
| git checkout -b "$DEVNET_BRANCH" | ||
| fi | ||
|
|
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When checking out an existing devnet branch from remote, the code doesn't ensure it's starting from the correct commit state. If the remote devnet branch has diverged from main significantly, or if this is being run after a force push or other Git history manipulation, the merge operation could produce unexpected results. Consider adding a check to verify the devnet branch's relationship to main, or document the expected branch topology.
| git checkout "$DEVNET_BRANCH" | |
| git pull origin "$DEVNET_BRANCH" | |
| else | |
| echo "✅ Creating new branch $DEVNET_BRANCH from main" | |
| git checkout -b "$DEVNET_BRANCH" | |
| fi | |
| # Ensure local devnet branch matches the remote state | |
| git fetch origin "$DEVNET_BRANCH" | |
| git checkout -B "$DEVNET_BRANCH" "origin/$DEVNET_BRANCH" | |
| else | |
| echo "✅ Creating new branch $DEVNET_BRANCH from main" | |
| # Base new devnet branch on the latest origin/main | |
| git fetch origin main | |
| git checkout -B "$DEVNET_BRANCH" origin/main | |
| fi | |
| # Ensure local main is up to date with origin/main before merging | |
| git fetch origin main:main |
| # Get the last devnet tag for changelog comparison | ||
| CURRENT_DEVNET_TAG="${{ steps.get_labels.outputs.devnet_tag }}" | ||
| DEVNET_TAG_PREFIX="$(echo ${{ steps.get_labels.outputs.devnet_label }} | sed 's/^d/D/')" | ||
| LAST_DEVNET_TAG=$(git tag -l "${DEVNET_TAG_PREFIX}*" --sort=-version:refname | grep -v "^$CURRENT_DEVNET_TAG$" | head -n 1) |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow filters tags using version:refname sort, which may not work correctly for tags like "Devnet1", "Devnet2", "Devnet10", etc. This sorting method is designed for semantic version numbers and may produce unexpected results with the "DevnetX" naming convention. For example, "Devnet10" might be sorted before "Devnet2". Consider using a different sorting mechanism or document this limitation.
| LAST_DEVNET_TAG=$(git tag -l "${DEVNET_TAG_PREFIX}*" --sort=-version:refname | grep -v "^$CURRENT_DEVNET_TAG$" | head -n 1) | |
| LAST_DEVNET_TAG=$(git tag -l "${DEVNET_TAG_PREFIX}*" --sort=-creatordate | grep -v "^$CURRENT_DEVNET_TAG$" | head -n 1) |
| VERSION=$(echo $LABELS | jq -r '.[] | select(test("^[0-9]+\\.[0-9]+\\.[0-9]+$"))') | ||
|
|
||
| # Look for zeam network tags (devnet0, devnet1, testnet, mainnet) | ||
| ZEAM_TAG=$(echo $LABELS | jq -r '.[] | select(test("^(devnet[0-9]+|testnet[0-9]*|mainnet)$"))') | ||
| # Look for devnet labels (devnet0, devnet1, devnet2, etc.) - MANDATORY | ||
| DEVNET_LABEL=$(echo $LABELS | jq -r '.[] | select(test("^devnet[0-9]+$"))') |
Copilot
AI
Jan 26, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The workflow extracts label data using jq on JSON that includes user-controlled PR labels. While the current regex patterns provide some validation, if a malicious user creates a label that matches the version or devnet patterns but contains additional shell metacharacters, it could potentially cause issues. The current regex patterns (^[0-9]+\.[0-9]+\.[0-9]+$ and ^devnet[0-9]+$) are strict enough to prevent shell injection, but consider adding explicit validation that the extracted values contain only expected characters before using them in git commands and other shell operations.
Update release process