diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 267bc7605..58131d4f9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,12 @@ name: Build and Release Executable +# TODO(definitive-release-workflow): Keep this release workflow aligned with +# opencode-agent-variants where practical. The intended shared shape is: +# centralized config, branch/channel release policy, generated release notes, +# author resolution, community contributor detection, and project-specific +# packaging steps. Do not extract into a separate shared workflow unless more +# projects need it; keep the two workflows readable sibling implementations. + # ╔═══════════════════════════════════════════════════════════════════════════════════════╗ # ║ CONFIGURATION SECTION ║ # ║ Edit the values below to customize build triggers, release contents, and behavior. ║ @@ -107,8 +114,10 @@ on: paths: - 'src/proxy_app/**' # Main application source code - 'src/rotator_library/**' # Key rotation library - - '.github/workflows/build.yml' # This workflow file - - 'cliff.toml' # Changelog configuration + +concurrency: + group: build-release-${{ github.ref }} + cancel-in-progress: false # ════════════════════════════════════════════════════════════════════════════════════════════ # JOBS @@ -234,6 +243,21 @@ jobs: BRANCH_NAME=${{ github.ref_name }} DATE_STAMP_NEW=$(date +'%Y%m%d') DATE_STAMP_OLD=$(date +'%Y.%m.%d') + + EXISTING_TAG=$(gh release list --repo "${{ github.repository }}" --limit 1000 --json tagName,targetCommitish \ + --jq ".[] | select(.tagName | startswith(\"$BRANCH_NAME/build-\")) | select(.targetCommitish == \"${{ github.sha }}\") | .tagName" \ + | head -n 1) + + if [ -n "$EXISTING_TAG" ]; then + echo "Release already exists for this commit: $EXISTING_TAG" + echo "release_title=Build ($BRANCH_NAME): ${EXISTING_TAG#*/build-}" >> $GITHUB_OUTPUT + echo "release_tag=$EXISTING_TAG" >> $GITHUB_OUTPUT + echo "archive_version_part=${EXISTING_TAG%%/*}-${EXISTING_TAG#*/build-}" >> $GITHUB_OUTPUT + echo "version=${EXISTING_TAG#*/build-}" >> $GITHUB_OUTPUT + echo "timestamp=$(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT + echo "should_release=false" >> $GITHUB_OUTPUT + exit 0 + fi # Find the number of releases already created today for this branch, matching either old or new format. # We use grep -E for an OR condition and wrap it to prevent failures when no matches are found. @@ -251,14 +275,17 @@ jobs: echo "archive_version_part=$BRANCH_NAME-$VERSION" >> $GITHUB_OUTPUT echo "version=$VERSION" >> $GITHUB_OUTPUT echo "timestamp=$(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT + echo "should_release=true" >> $GITHUB_OUTPUT - name: Download build artifacts + if: steps.version.outputs.should_release == 'true' uses: actions/download-artifact@v4 with: path: release-assets pattern: proxy-app-build-*-${{ steps.get_sha.outputs.sha }} - name: Archive release files + if: steps.version.outputs.should_release == 'true' id: archive shell: bash run: | @@ -321,6 +348,7 @@ jobs: echo "ASSET_PATHS=$ASSET_PATHS" >> $GITHUB_OUTPUT - name: Install git-cliff + if: steps.version.outputs.should_release == 'true' shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -338,6 +366,7 @@ jobs: sudo mv git-cliff-*/git-cliff /usr/local/bin/ - name: Prepare git-cliff config + if: steps.version.outputs.should_release == 'true' shell: bash run: | # Inject the GitHub repo URL into your template @@ -346,6 +375,7 @@ jobs: head -20 .github/cliff.toml - name: Generate Changelog + if: steps.version.outputs.should_release == 'true' id: changelog shell: bash env: @@ -474,6 +504,7 @@ jobs: fi - name: Resolve GitHub Usernames in Changelog + if: steps.version.outputs.should_release == 'true' id: resolve_usernames shell: bash env: @@ -652,39 +683,55 @@ jobs: if [ -n "$PREV_TAG" ]; then echo "🔍 Layer PR: Generating Community Contributions section..." - # Get all merge commits in the range - MERGE_COMMITS=$(git log "$PREV_TAG".."$CURRENT_SHA" --oneline --grep="Merge pull request" 2>/dev/null || true) - - if [ -n "$MERGE_COMMITS" ]; then + OWNER="${{ github.repository_owner }}" + REPO_NAME="${{ github.event.repository.name }}" + PR_NUMBERS="" + + # Layer PR-1: parse PR numbers from commit subjects. This keeps the old + # merge-commit behavior and also catches squash commits that include #123. + SUBJECT_PRS=$(git log "$PREV_TAG".."$CURRENT_SHA" --format='%s' 2>/dev/null | grep -oE 'Merge pull request #[0-9]+|#[0-9]+' | grep -oE '[0-9]+' || true) + PR_NUMBERS=$(printf '%s\n%s\n' "$PR_NUMBERS" "$SUBJECT_PRS") + + # Layer PR-2: GraphQL associatedPullRequests catches squash/rebase flows + # even when the commit subject does not include a PR number. + COMMIT_SHAS=$(git rev-list "$PREV_TAG".."$CURRENT_SHA" 2>/dev/null || true) + while read -r SHA; do + if [ -z "$SHA" ]; then + continue + fi + ASSOCIATED_PRS=$(gh api graphql \ + -f owner="$OWNER" \ + -f name="$REPO_NAME" \ + -f oid="$SHA" \ + -f query='query($owner:String!, $name:String!, $oid:GitObjectID!) { repository(owner:$owner, name:$name) { object(oid:$oid) { ... on Commit { associatedPullRequests(first: 10) { nodes { number } } } } } }' \ + --jq '.data.repository.object.associatedPullRequests.nodes[].number' 2>/dev/null || true) + PR_NUMBERS=$(printf '%s\n%s\n' "$PR_NUMBERS" "$ASSOCIATED_PRS") + done <<< "$COMMIT_SHAS" + + PR_NUMBERS=$(printf '%s\n' "$PR_NUMBERS" | grep -E '^[0-9]+$' | sort -n | uniq || true) + + if [ -n "$PR_NUMBERS" ]; then PR_SECTION="" - - while IFS= read -r commit_line; do - if [ -n "$commit_line" ]; then - # Extract PR number from "Merge pull request #XX from ..." - PR_NUM=$(echo "$commit_line" | grep -oE '#[0-9]+' | head -1 | tr -d '#') - - if [ -n "$PR_NUM" ]; then - # Fetch PR info from GitHub API - PR_INFO=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUM" \ - --jq '{title: .title, author: .user.login}' 2>/dev/null || echo "{}") - - PR_TITLE=$(echo "$PR_INFO" | jq -r '.title // empty') - PR_AUTHOR=$(echo "$PR_INFO" | jq -r '.author // empty') - - if [ -n "$PR_TITLE" ] && [ -n "$PR_AUTHOR" ]; then - PR_URL="https://github.com/${{ github.repository }}/pull/$PR_NUM" - PR_SECTION="${PR_SECTION}- ${PR_TITLE} ([#${PR_NUM}](${PR_URL})) by @${PR_AUTHOR}"$'\n' - PR_COUNT=$((PR_COUNT + 1)) - echo " ✅ PR #$PR_NUM: $PR_TITLE by @$PR_AUTHOR" - else - echo " ⚠️ PR #$PR_NUM: Could not fetch info" - fi - fi + while read -r PR_NUM; do + if [ -z "$PR_NUM" ]; then + continue fi - done <<< "$MERGE_COMMITS" - + PR_INFO=$(gh api "repos/${{ github.repository }}/pulls/$PR_NUM" \ + --jq '{title: .title, author: .user.login, url: .html_url}' 2>/dev/null || echo "{}") + PR_TITLE=$(echo "$PR_INFO" | jq -r '.title // empty') + PR_AUTHOR=$(echo "$PR_INFO" | jq -r '.author // empty') + PR_URL=$(echo "$PR_INFO" | jq -r '.url // empty') + + if [ -n "$PR_TITLE" ] && [ -n "$PR_AUTHOR" ] && [ -n "$PR_URL" ]; then + PR_SECTION="${PR_SECTION}- ${PR_TITLE} ([#${PR_NUM}](${PR_URL})) by @${PR_AUTHOR}"$'\n' + PR_COUNT=$((PR_COUNT + 1)) + echo " ✅ PR #$PR_NUM: $PR_TITLE by @$PR_AUTHOR" + else + echo " ⚠️ PR #$PR_NUM: Could not fetch info" + fi + done <<< "$PR_NUMBERS" + if [ "$PR_COUNT" -gt 0 ]; then - # Append PR section to changelog { echo "" echo "### 💜 Community Contributions" @@ -696,7 +743,7 @@ jobs: echo " ✅ Added $PR_COUNT PRs to Community Contributions section" fi else - echo " ℹ️ No merge commits found in range" + echo " ℹ️ No associated PRs found in range" fi else echo "⚠️ Layer PR: Skipped (no previous tag available)" @@ -732,6 +779,7 @@ jobs: fi - name: Debug artifact contents + if: steps.version.outputs.should_release == 'true' shell: bash run: | echo "🔍 Debugging artifact contents..." @@ -748,6 +796,7 @@ jobs: find release-assets -type f 2>/dev/null || echo "No files found in release-assets" - name: Generate Build Metadata + if: steps.version.outputs.should_release == 'true' id: metadata shell: bash env: @@ -810,6 +859,7 @@ jobs: echo " - Contributors: $CONTRIBUTORS_LIST" - name: Create Release + if: steps.version.outputs.should_release == 'true' shell: bash run: | # Prepare changelog content - prefer resolved version if available @@ -921,10 +971,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Prune Old Releases - if: always() # Run even if release creation failed (optional, but safer to run only on success usually. Let's stick to default behavior which is success) - # Actually, if release creation failed, we probably don't want to prune. - # But wait, the user might want to prune even if the new release fails? No, usually we prune to make space for the new one or clean up after. - # Let's stick to running only on success of previous steps. + if: steps.version.outputs.should_release == 'true' shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index 2d0428dd6..d66e4acca 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -1,15 +1,27 @@ name: Cleanup Feature Builds -# Trigger automatically when a branch is deleted (typically after PR merge) -# Also allows manual triggering for testing or cleanup of specific branches on: delete: workflow_dispatch: inputs: - branch_name: - description: 'Branch name to clean up (for manual cleanup)' + cleanup_mode: + description: 'Cleanup mode' required: true + type: choice + default: branch + options: + - branch + - stale_branches + branch_name: + description: 'Branch name for branch mode. Leave empty for stale_branches.' + required: false type: string + default: '' + keep_latest: + description: 'Keep newest N matching releases. 0 deletes all matches.' + required: false + type: string + default: '0' dry_run: description: 'Dry run mode (preview without deleting)' required: false @@ -18,259 +30,197 @@ on: jobs: delete-releases: - # Only run if: - # 1. Automatic trigger: deleted ref was a branch (not a tag) - # 2. Manual trigger: always run if: github.event_name == 'workflow_dispatch' || github.event.ref_type == 'branch' runs-on: ubuntu-latest permissions: contents: write env: - # Configure protected branches that should NEVER be cleaned up - # Modify this list to match your repository's important branches - PROTECTED_BRANCHES: "main,master,production,prod,staging,develop" + PROTECTED_BRANCHES: "main,master,production,prod,staging,develop,dev" steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 + with: + fetch-depth: 0 - - name: Determine branch name and mode + - name: Determine cleanup config id: config shell: bash run: | - # Determine branch name based on trigger type - if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + CLEANUP_MODE="${{ github.event.inputs.cleanup_mode }}" BRANCH_NAME="${{ github.event.inputs.branch_name }}" + KEEP_LATEST="${{ github.event.inputs.keep_latest }}" DRY_RUN="${{ github.event.inputs.dry_run }}" - echo "🔧 Manual trigger detected" else + CLEANUP_MODE="branch" BRANCH_NAME="${{ github.event.ref }}" + KEEP_LATEST="0" DRY_RUN="false" - echo "🗑️ Branch deletion detected" fi - - echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT - echo "dry_run=$DRY_RUN" >> $GITHUB_OUTPUT - - echo "Branch: $BRANCH_NAME" - echo "Dry Run: $DRY_RUN" - - name: Validate branch is not protected - shell: bash - env: - BRANCH_NAME: ${{ steps.config.outputs.branch_name }} - run: | - echo "🔍 Checking if branch '$BRANCH_NAME' is protected..." - - # Convert comma-separated list to array - IFS=',' read -ra PROTECTED <<< "$PROTECTED_BRANCHES" - - # Check if branch is in protected list - for protected in "${PROTECTED[@]}"; do - # Trim whitespace - protected=$(echo "$protected" | xargs) - if [ "$BRANCH_NAME" == "$protected" ]; then - echo "❌ ERROR: Branch '$BRANCH_NAME' is protected and cannot be cleaned up." - echo "" - echo "Protected branches: $PROTECTED_BRANCHES" - echo "" - echo "If you need to clean up this branch, please remove it from the" - echo "PROTECTED_BRANCHES environment variable in .github/workflows/cleanup.yml" - exit 1 - fi - done - - echo "✅ Branch '$BRANCH_NAME' is not protected. Proceeding with cleanup." + case "$CLEANUP_MODE" in + branch|stale_branches) ;; + *) echo "Unsupported cleanup mode: $CLEANUP_MODE" >&2; exit 1 ;; + esac + + if ! printf '%s\n' "$KEEP_LATEST" | grep -Eq '^[0-9]+$'; then + echo "keep_latest must be a non-negative integer, got: $KEEP_LATEST" >&2 + exit 1 + fi + + if [ "$CLEANUP_MODE" = "branch" ] && [ -z "$BRANCH_NAME" ]; then + echo "branch_name is required for branch mode" >&2 + exit 1 + fi + + echo "cleanup_mode=$CLEANUP_MODE" >> "$GITHUB_OUTPUT" + echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT" + echo "keep_latest=$KEEP_LATEST" >> "$GITHUB_OUTPUT" + echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT" + + echo "Mode: $CLEANUP_MODE" + echo "Branch: ${BRANCH_NAME:-'(none)'}" + echo "Keep latest: $KEEP_LATEST" + echo "Dry run: $DRY_RUN" - name: Find and process releases id: cleanup shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CLEANUP_MODE: ${{ steps.config.outputs.cleanup_mode }} BRANCH_NAME: ${{ steps.config.outputs.branch_name }} + KEEP_LATEST: ${{ steps.config.outputs.keep_latest }} DRY_RUN: ${{ steps.config.outputs.dry_run }} run: | - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "🔍 Searching for releases associated with branch: '$BRANCH_NAME'" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - - # List all releases and filter by tag pattern - # Your build.yaml creates tags like: branch_name/build-YYYYMMDD-N-sha - # We search for releases where the tag starts with the branch name followed by "/" - - RELEASES=$(gh release list --repo "${{ github.repository }}" --limit 1000 --json tagName --jq ".[] | select(.tagName | startswith(\"$BRANCH_NAME/\")) | .tagName") - - if [ -z "$RELEASES" ]; then - echo "ℹ️ No releases found for branch '$BRANCH_NAME'." - echo "" - echo "This could mean:" - echo " • The branch never had any builds created" - echo " • The releases were already cleaned up" - echo " • The branch name doesn't match any release tag patterns" - echo "" - echo "searched_pattern=$BRANCH_NAME/" >> $GITHUB_OUTPUT - echo "release_count=0" >> $GITHUB_OUTPUT - echo "deleted_count=0" >> $GITHUB_OUTPUT - echo "failed_count=0" >> $GITHUB_OUTPUT - exit 0 - fi - - # Count releases - RELEASE_COUNT=$(echo "$RELEASES" | wc -l) - echo "📦 Found $RELEASE_COUNT release(s) to process:" - echo "" - echo "$RELEASES" | while read -r tag; do - echo " • $tag" - done - echo "" - - # Optional: Retention policy (commented out by default) - # Uncomment the following lines to keep the last N builds instead of deleting all - # RETENTION_KEEP=3 - # if [ $RELEASE_COUNT -gt $RETENTION_KEEP ]; then - # echo "📌 Retention policy: Keeping last $RETENTION_KEEP build(s)" - # RELEASES=$(echo "$RELEASES" | head -n -$RETENTION_KEEP) - # RELEASE_COUNT=$(echo "$RELEASES" | wc -l) - # echo "📦 Adjusted to delete $RELEASE_COUNT release(s)" - # echo "" - # else - # echo "📌 Retention policy: All releases within retention limit" - # echo "ℹ️ No cleanup needed" - # exit 0 - # fi - - # Process deletions - if [ "$DRY_RUN" == "true" ]; then - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "🧪 DRY RUN MODE - No actual deletions will occur" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - echo "The following releases and tags would be deleted:" - echo "" - echo "$RELEASES" | while read -r TAG_NAME; do - if [ -n "$TAG_NAME" ]; then - echo " 🗑️ Would delete: $TAG_NAME" + is_protected_branch() { + local branch="$1" + IFS=',' read -ra protected <<< "$PROTECTED_BRANCHES" + for item in "${protected[@]}"; do + item="$(echo "$item" | xargs)" + if [ "$branch" = "$item" ]; then + return 0 fi done - echo "" - echo "searched_pattern=$BRANCH_NAME/" >> $GITHUB_OUTPUT - echo "release_count=$RELEASE_COUNT" >> $GITHUB_OUTPUT - echo "deleted_count=0" >> $GITHUB_OUTPUT - echo "failed_count=0" >> $GITHUB_OUTPUT + return 1 + } + + branch_exists() { + git ls-remote --exit-code --heads origin "$1" >/dev/null 2>&1 + } + + releases_for_branch() { + local branch="$1" + gh release list --repo "${{ github.repository }}" --limit 1000 --json tagName,createdAt \ + --jq "sort_by(.createdAt) | reverse | .[] | select(.tagName | startswith(\"$branch/\")) | .tagName" + } + + all_build_releases() { + gh release list --repo "${{ github.repository }}" --limit 1000 --json tagName,createdAt \ + --jq 'sort_by(.createdAt) | reverse | .[] | select(.tagName | contains("/build-")) | .tagName' + } + + select_after_retention() { + local keep="$1" + if [ "$keep" -eq 0 ]; then + cat + return + fi + tail -n +$((keep + 1)) + } + + if [ "$CLEANUP_MODE" = "branch" ]; then + if is_protected_branch "$BRANCH_NAME"; then + echo "Branch '$BRANCH_NAME' is protected and cannot be cleaned up." >&2 + echo "Protected branches: $PROTECTED_BRANCHES" >&2 + exit 1 + fi + SEARCH_PATTERN="$BRANCH_NAME/" + RELEASES="$(releases_for_branch "$BRANCH_NAME" | select_after_retention "$KEEP_LATEST")" else - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "🗑️ Starting deletion process" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - - DELETED=0 - FAILED=0 - - echo "$RELEASES" | while read -r TAG_NAME; do - if [ -n "$TAG_NAME" ]; then - echo "Processing: $TAG_NAME" - - # Delete the release and the associated tag (--cleanup-tag removes the git tag) - if gh release delete "$TAG_NAME" --repo "${{ github.repository }}" --cleanup-tag --yes 2>&1; then - echo " ✅ Successfully deleted: $TAG_NAME" - DELETED=$((DELETED + 1)) - else - echo " ⚠️ Failed to delete: $TAG_NAME" - FAILED=$((FAILED + 1)) + SEARCH_PATTERN="stale unprotected */build-* releases" + RELEASES="$({ + all_build_releases | while read -r tag; do + [ -z "$tag" ] && continue + branch="${tag%/build-*}" + if is_protected_branch "$branch"; then + continue fi - echo "" - - # Brief pause to avoid rate limiting - sleep 0.5 - fi - done - - # Note: The counter variables don't persist from the subshell, so we recalculate - # This is a limitation of bash subshells, but the individual status messages show the details - echo "searched_pattern=$BRANCH_NAME/" >> $GITHUB_OUTPUT - echo "release_count=$RELEASE_COUNT" >> $GITHUB_OUTPUT - # We'll use a different approach to count successes/failures - echo "deleted_count=$RELEASE_COUNT" >> $GITHUB_OUTPUT - echo "failed_count=0" >> $GITHUB_OUTPUT + if branch_exists "$branch"; then + continue + fi + echo "$tag" + done + } | select_after_retention "$KEEP_LATEST")" + fi + + if [ -z "$RELEASES" ]; then + echo "No releases matched cleanup mode '$CLEANUP_MODE'." + echo "searched_pattern=$SEARCH_PATTERN" >> "$GITHUB_OUTPUT" + echo "release_count=0" >> "$GITHUB_OUTPUT" + echo "deleted_count=0" >> "$GITHUB_OUTPUT" + echo "failed_count=0" >> "$GITHUB_OUTPUT" + exit 0 + fi + + RELEASE_COUNT="$(printf '%s\n' "$RELEASES" | grep -c .)" + echo "Found $RELEASE_COUNT release(s):" + printf '%s\n' "$RELEASES" | sed 's/^/ - /' + + if [ "$DRY_RUN" = "true" ]; then + echo "Dry run only. No releases will be deleted." + echo "searched_pattern=$SEARCH_PATTERN" >> "$GITHUB_OUTPUT" + echo "release_count=$RELEASE_COUNT" >> "$GITHUB_OUTPUT" + echo "deleted_count=0" >> "$GITHUB_OUTPUT" + echo "failed_count=0" >> "$GITHUB_OUTPUT" + exit 0 + fi + + DELETED=0 + FAILED=0 + while read -r tag; do + [ -z "$tag" ] && continue + echo "Deleting $tag" + if gh release delete "$tag" --repo "${{ github.repository }}" --cleanup-tag --yes; then + DELETED=$((DELETED + 1)) + else + FAILED=$((FAILED + 1)) + fi + sleep 0.5 + done <<< "$RELEASES" + + echo "searched_pattern=$SEARCH_PATTERN" >> "$GITHUB_OUTPUT" + echo "release_count=$RELEASE_COUNT" >> "$GITHUB_OUTPUT" + echo "deleted_count=$DELETED" >> "$GITHUB_OUTPUT" + echo "failed_count=$FAILED" >> "$GITHUB_OUTPUT" + + if [ "$FAILED" -gt 0 ]; then + exit 1 fi - name: Generate summary shell: bash env: + CLEANUP_MODE: ${{ steps.config.outputs.cleanup_mode }} BRANCH_NAME: ${{ steps.config.outputs.branch_name }} + KEEP_LATEST: ${{ steps.config.outputs.keep_latest }} DRY_RUN: ${{ steps.config.outputs.dry_run }} PATTERN: ${{ steps.cleanup.outputs.searched_pattern }} RELEASE_COUNT: ${{ steps.cleanup.outputs.release_count }} DELETED_COUNT: ${{ steps.cleanup.outputs.deleted_count }} FAILED_COUNT: ${{ steps.cleanup.outputs.failed_count }} run: | - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "📊 Cleanup Summary" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - echo "" - echo "Branch: $BRANCH_NAME" - echo "Search Pattern: ${PATTERN}*" - echo "Releases Found: $RELEASE_COUNT" - - if [ "$DRY_RUN" == "true" ]; then - echo "Mode: 🧪 DRY RUN (no actual deletions)" - echo "" - echo "✅ Dry run completed successfully" - echo " Run again with dry_run=false to perform actual cleanup" - else - echo "Mode: 🗑️ DELETE" - echo "Successfully Deleted: $DELETED_COUNT" - if [ "$FAILED_COUNT" -gt 0 ]; then - echo "Failed: $FAILED_COUNT" - fi - echo "" - - if [ "$RELEASE_COUNT" -eq 0 ]; then - echo "ℹ️ No releases needed cleanup" - elif [ "$FAILED_COUNT" -gt 0 ]; then - echo "⚠️ Cleanup completed with some failures" - echo " Check the logs above for details on failed deletions" - else - echo "✅ Cleanup completed successfully" - fi - fi - echo "" - echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - - # Create GitHub Actions summary { - echo "## 🧹 Cleanup Summary" - echo "" + echo "## Cleanup Summary" + echo echo "| Metric | Value |" - echo "|--------|-------|" - echo "| **Branch** | \`$BRANCH_NAME\` |" - echo "| **Search Pattern** | \`${PATTERN}*\` |" - echo "| **Releases Found** | $RELEASE_COUNT |" - - if [ "$DRY_RUN" == "true" ]; then - echo "| **Mode** | 🧪 Dry Run |" - echo "" - echo "> [!NOTE]" - echo "> This was a dry run. No actual deletions occurred." - echo "> Run the workflow again with \`dry_run=false\` to perform the cleanup." - else - echo "| **Mode** | 🗑️ Delete |" - echo "| **Successfully Deleted** | $DELETED_COUNT |" - if [ "$FAILED_COUNT" -gt 0 ]; then - echo "| **Failed** | $FAILED_COUNT |" - echo "" - echo "> [!WARNING]" - echo "> Some deletions failed. Check the workflow logs for details." - else - if [ "$RELEASE_COUNT" -eq 0 ]; then - echo "" - echo "> [!NOTE]" - echo "> No releases were found that needed cleanup." - else - echo "" - echo "> [!NOTE]" - echo "> All releases and tags were successfully deleted." - fi - fi - fi - } >> $GITHUB_STEP_SUMMARY + echo "| --- | --- |" + echo "| Mode | \`$CLEANUP_MODE\` |" + echo "| Branch | \`${BRANCH_NAME:-'(none)'}\` |" + echo "| Search | \`$PATTERN\` |" + echo "| Keep latest | \`$KEEP_LATEST\` |" + echo "| Dry run | \`$DRY_RUN\` |" + echo "| Releases found | $RELEASE_COUNT |" + echo "| Deleted | $DELETED_COUNT |" + echo "| Failed | $FAILED_COUNT |" + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 230b1f9ca..68acd4878 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -14,7 +14,6 @@ on: paths: - "src/proxy_app/**" - "src/rotator_library/**" - - ".github/workflows/docker-build.yml" - "Dockerfile" - "requirements.txt"