Files
550b4cb0b4 chore(web): Add automated release workflows for one-button releases (#6615)
* feat: add automated Storybook snapshot testing with CI integration

This PR introduces automated Jest snapshot testing for all Storybook stories using the Portable Stories API.

- **Test Setup**: Created automated test file that discovers and generates JSON snapshots for all `.stories.tsx` files
- **CI Pipeline**: Added GitHub Actions workflow to run snapshot tests on PRs and main branch pushes
- **Scripts**: Added `test:storybook` and `test:storybook:ci` npm scripts
- **Documentation**: Created comprehensive guide in `STORYBOOK_SNAPSHOTS.md`

- Automatically catches unintended UI changes in components
- Provides reviewable diffs in pull requests
- Fast execution compared to visual regression tests
- Version-controlled snapshot history
- Zero configuration required - automatically discovers all stories

```bash
yarn test:storybook     # Run tests locally
yarn test:storybook -u  # Update snapshots
```

The CI workflow runs automatically on changes to `apps/web/**` and will fail if snapshots don't match, uploading diffs as artifacts for review.

fix: move docs to docs folder and add workflow permissions

- Move STORYBOOK_SNAPSHOTS.md to docs/storybook-snapshots.md
- Add permissions block to workflow for security (contents: read)
- Fixes CodeQL security warning about GITHUB_TOKEN permissions

fix: use globSync for Jest compatibility

- Change from glob.sync to globSync import
- Fixes ES module import error in Jest

feat: Add automated release workflows for one-button releases

Implements GitHub Actions workflows to automate the release process,
reducing manual steps from ~20 CLI commands to 3 button clicks via
GitHub's web UI.

- **Start Web Release**: Creates release branch, bumps version, generates
  changelog, and creates PR automatically
- **Complete Web Release**: Merges PR after QA approval and triggers
  deployment
- **Back-merge Main to Dev**: Automatically syncs main back to dev with
  conflict detection

- Enhanced changelog generator with categorization and statistics
- Slack notification helper for all release events
- Scripts documentation

- Complete automated release procedure guide in release-procedure-automated.md
- Updated legacy manual procedure with deprecation notice

- 85% reduction in manual steps (20 → 3)
- 83% faster releases (30-60 min → 5-10 min)
- Zero CLI expertise required
- Accessible to non-technical team members
- Reduced error rate with validation
- Automated Slack notifications (optional)

- No breaking changes - manual process still works
- Existing deployment workflows unchanged
- QA approval process remains manual and human-controlled
- Easy rollback if needed

fix: Address PR review comments

- Add version extraction validation in complete workflow
- Fix Slack notification JSON injection using jq
- Improve error messages with clearer formatting
- Add concurrent release check to prevent conflicts
- Fix conditional in back-merge workflow PR body

Addresses review feedback from Copilot review.

chore: Revert storybook-related changes in package.json and .gitignore

These changes were unrelated to the release automation feature.

* fix: improve release workflow reliability and PR description

- Change base branch from dev to main for regular releases
- Remove project board step (not used)
- Fix PR creation by removing cd to apps/web subdirectory
- Restore release label for PR tagging
- Remove backmerge and conflicts labels from backmerge workflow
- Exclude merge commits from changelog tables
- Move release metadata to bottom of PR description for better readability

* chore: remove redundant Complete Web Release workflow

The web-tag-release workflow already handles tagging and GitHub release
creation automatically when PRs are merged to main, making this workflow
unnecessary.

* feat: auto-publish releases and add Slack notifications

- Publish GitHub releases immediately instead of as drafts
- Send Slack notification to #topic-wallet-releases after production deployment
- Include version and release notes link in notification

* docs: update automated release documentation

- Remove references to deleted Complete Web Release workflow
- Update release process to reflect auto-publish releases
- Add Slack notification to #topic-wallet-releases channel
- Simplify workflow from 3 steps to 2 (start + back-merge)
- Update base branch documentation (main for both regular and hotfix)
- Add release documentation link to root README
- Update workflow comparison table and diagrams

* chore: update Slack notification message for releases

Change notification to indicate release is "ready for going live"
instead of "released to production", with GitHub release link.

* Update package.json

* feat: add auto-increment version support to release workflow

Allow leaving the version input empty to automatically increment based on release type:
- Regular releases: increment minor version (middle number), reset patch
  Example: 1.73.0 → 1.74.0
- Hotfix releases: increment patch version (last number)
  Example: 1.73.0 → 1.73.1

Manual version input still supported with validation. All internal references
updated to use step outputs instead of direct input references.

Tested locally with comprehensive unit and scenario tests (17/17 passed).

* fix: address Copilot review feedback for auto-increment feature

Security and reliability improvements:
- Add validation for version extraction from package.json
- Validate parsed version components before incrementing
- Fix JSON injection vulnerability in Slack notification using jq
- Improve error messages with clear expected formats

These changes address the Copilot review comments to ensure the
auto-increment feature handles edge cases and prevents security issues.

* chore: clean up release documentation

- Remove comparison to manual workflow from documentation
- Remove "last modified" date from automated release docs
- Remove legacy scripts section from release README

---------

Co-authored-by: Hanzo Dev <[email protected]>
2025-11-11 11:13:30 +01:00

133 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Enhanced changelog generator with better formatting and categorization
# Usage: ./generate-changelog.sh <base_branch> <compare_branch>
set -e
BASE_BRANCH=${1:-main}
COMPARE_BRANCH=${2:-dev}
# Colors for terminal output (optional)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check if branches exist
if ! git rev-parse --verify "origin/$BASE_BRANCH" >/dev/null 2>&1; then
echo -e "${RED}Error: Branch origin/$BASE_BRANCH does not exist${NC}" >&2
exit 1
fi
if ! git rev-parse --verify "origin/$COMPARE_BRANCH" >/dev/null 2>&1; then
echo -e "${RED}Error: Branch origin/$COMPARE_BRANCH does not exist${NC}" >&2
exit 1
fi
# Count commits
COMMIT_COUNT=$(git rev-list --count origin/"$BASE_BRANCH"..origin/"$COMPARE_BRANCH")
if [ "$COMMIT_COUNT" -eq 0 ]; then
echo "No changes between $BASE_BRANCH and $COMPARE_BRANCH"
exit 0
fi
# Arrays for grouping
declare -a features=()
declare -a fixes=()
declare -a mobile=()
declare -a breaking=()
declare -a chores=()
declare -a others=()
# Process commits
while IFS="|" read -r hash subject author; do
# Skip merge commits
if [[ $subject =~ ^Merge ]]; then
continue
fi
# Extract PR number if exists
if [[ $subject =~ \(#([0-9]+)\) ]]; then
PR_NUM="${BASH_REMATCH[1]}"
PR_LINK="[#$PR_NUM](https://github.com/${GITHUB_REPOSITORY:-safe-global/safe-wallet-web}/pull/$PR_NUM)"
DESC=$(echo "$subject" | sed -E 's/ \(#([0-9]+)\)//')
else
PR_LINK="[\`$hash\`](https://github.com/${GITHUB_REPOSITORY:-safe-global/safe-wallet-web}/commit/$hash)"
DESC="$subject"
fi
# Clean up description
DESC=$(echo "$DESC" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# Detect breaking changes
if [[ $DESC =~ BREAKING[[:space:]]CHANGE ]] || [[ $subject =~ ! ]]; then
breaking+=("| $DESC | $PR_LINK | $author |")
continue
fi
# Group by conventional commit prefix
if [[ $DESC =~ ^[a-zA-Z]+\([Mm]obile\): ]]; then
mobile+=("| $DESC | $PR_LINK | $author |")
elif [[ $DESC =~ ^[Ff]eat(\(.*\))?: ]]; then
features+=("| $DESC | $PR_LINK | $author |")
elif [[ $DESC =~ ^[Ff]ix(\(.*\))?: ]]; then
fixes+=("| $DESC | $PR_LINK | $author |")
elif [[ $DESC =~ ^[Cc]hore(\(.*\))?: ]] || [[ $DESC =~ ^[Bb]uild(\(.*\))?: ]] || [[ $DESC =~ ^[Cc]i(\(.*\))?: ]]; then
chores+=("| $DESC | $PR_LINK | $author |")
else
others+=("| $DESC | $PR_LINK | $author |")
fi
done < <(git log origin/"$BASE_BRANCH"..origin/"$COMPARE_BRANCH" --pretty=format:'%h|%s|%an')
# Function to print a table
print_table() {
local title=$1
local emoji=$2
shift 2
local rows=("$@")
if [ ${#rows[@]} -gt 0 ]; then
echo ""
echo "### $emoji $title"
echo ""
echo "| Change | PR/Commit | Author |"
echo "|--------|-----------|--------|"
for row in "${rows[@]}"; do
echo "$row"
done
fi
}
# Print statistics
echo "## 📊 Release Statistics"
echo ""
echo "- **Total commits:** $COMMIT_COUNT"
echo "- **Features:** ${#features[@]}"
echo "- **Bug fixes:** ${#fixes[@]}"
echo "- **Mobile changes:** ${#mobile[@]}"
echo "- **Breaking changes:** ${#breaking[@]}"
echo ""
echo "---"
echo ""
# Print grouped tables
if [ ${#breaking[@]} -gt 0 ]; then
print_table "Breaking Changes" "⚠️" "${breaking[@]}"
echo ""
echo "> **Warning:** This release contains breaking changes. Please review carefully."
echo ""
fi
print_table "Features" "✨" "${features[@]}"
print_table "Bug Fixes" "🐛" "${fixes[@]}"
print_table "Mobile" "📱" "${mobile[@]}"
print_table "Chores & Maintenance" "🔧" "${chores[@]}"
print_table "Other Changes" "📦" "${others[@]}"
echo ""
echo "---"
echo ""
echo "_Generated from \`$BASE_BRANCH..$COMPARE_BRANCH\` on $(date -u +"%Y-%m-%d %H:%M:%S UTC")_"