[SIV] Weekly Build Tagging #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "[SIV] Weekly Build Tagging" | |
| on: | |
| schedule: | |
| - cron: '0 15 * * 2' # Every Tuesday at 15:00 UTC | |
| workflow_dispatch: | |
| permissions: {} | |
| jobs: | |
| update-submodules-and-tag: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Checkout repository with submodules | |
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #5.0.0 | |
| with: | |
| token: ${{ secrets.SIV_USER_TOKEN_GH }} | |
| submodules: recursive | |
| fetch-depth: 0 | |
| - name: Configure Git | |
| run: | | |
| git config user.name "${{ secrets.SIV_USER }}" | |
| git config user.email "${{ secrets.SIV_USER_EMAIL }}" | |
| - name: Update all submodules to latest | |
| run: | | |
| echo "🧹 Resetting submodules to clean state..." | |
| git submodule foreach --recursive git reset --hard | |
| git submodule foreach --recursive git clean -fdx | |
| echo "🔄 Updating submodules to their latest commits..." | |
| # Get all submodule paths from .gitmodules | |
| ALL_SUBMODULES=$(git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | awk '{print $2}') | |
| # Get shallow submodule paths | |
| SHALLOW_SUBMODULES=$(git config -f .gitmodules --get-regexp '^submodule\..*\.shallow$' | grep 'true' | while read line; do | |
| # Extract submodule name from "submodule.NAME.shallow true" | |
| name=$(echo "$line" | sed 's/submodule\.\(.*\)\.shallow true/\1/') | |
| # Get the path for this submodule | |
| git config -f .gitmodules --get "submodule.${name}.path" || true | |
| done) | |
| echo "📋 Shallow submodules (will be skipped from --remote update):" | |
| echo "$SHALLOW_SUBMODULES" | |
| echo "" | |
| # Update each top-level submodule individually | |
| for submodule in $ALL_SUBMODULES; do | |
| # Check if this submodule is shallow | |
| if echo "$SHALLOW_SUBMODULES" | grep -qx "$submodule"; then | |
| echo "⏭️ Skipping shallow submodule: $submodule" | |
| else | |
| echo "🔄 Updating: $submodule" | |
| git submodule update --remote "$submodule" || echo "⚠️ Warning: Failed to update $submodule" | |
| fi | |
| done | |
| echo "✅ Submodules updated successfully" | |
| - name: Show submodule status | |
| id: submodule-status | |
| run: | | |
| echo "📋 Submodule Status:" | |
| echo "====================" | |
| git submodule status --recursive | |
| echo "" | |
| echo "📝 Git Status:" | |
| echo "==============" | |
| git status | |
| echo "" | |
| # Check if there are any submodule pointer changes to commit | |
| if git diff --quiet --ignore-submodules=dirty; then | |
| echo "ℹ️ No submodule updates detected" | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "✅ Submodule changes detected" | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| echo "" | |
| echo "📊 Changed submodules:" | |
| git diff --name-only | |
| fi | |
| - name: Commit submodule updates | |
| id: commit | |
| if: steps.submodule-status.outputs.has_changes == 'true' | |
| run: | | |
| echo "📝 Creating commit with submodule updates..." | |
| git add -A | |
| git commit -m "[SIV] auto-update submodules to latest commits | |
| Automated weekly update of all submodules to their latest upstream commits. | |
| Updated on: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" | |
| COMMIT_SHA=$(git rev-parse HEAD) | |
| echo "✅ Commit created: $COMMIT_SHA" | |
| echo "sha=$COMMIT_SHA" >> $GITHUB_OUTPUT | |
| - name: Create PR and merge changes | |
| if: steps.submodule-status.outputs.has_changes == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.SIV_USER_TOKEN_GH }} | |
| TARGET_BRANCH: ${{ github.ref_name }} | |
| run: | | |
| # Create a unique branch name for the PR | |
| PR_BRANCH="siv-auto-update-submodules-$(date +'%Y%m%d-%H%M%S')" | |
| echo "🌿 Creating branch: $PR_BRANCH" | |
| # Push to the new branch | |
| git push origin HEAD:$PR_BRANCH | |
| echo "✅ Changes pushed to branch: $PR_BRANCH" | |
| # Create the PR | |
| echo "📝 Creating Pull Request..." | |
| PR_URL=$(gh pr create \ | |
| --base "$TARGET_BRANCH" \ | |
| --head "$PR_BRANCH" \ | |
| --title "[SIV] Auto-update submodules to latest commits" \ | |
| --body "Automated weekly update of all submodules to their latest upstream commits. | |
| Updated on: $(date -u '+%Y-%m-%d %H:%M:%S UTC') | |
| This PR was automatically created by the weekly build workflow.") | |
| echo "✅ PR created: $PR_URL" | |
| # Merge the PR | |
| echo "🔀 Merging Pull Request..." | |
| gh pr merge "$PR_URL" --squash --delete-branch | |
| echo "✅ PR merged successfully" | |
| # Fetch to get the merge commit | |
| git fetch origin "$TARGET_BRANCH" | |
| - name: Get commit SHA for tagging | |
| id: get-sha | |
| env: | |
| TARGET_BRANCH: ${{ github.ref_name }} | |
| run: | | |
| if [ "${{ steps.submodule-status.outputs.has_changes }}" == "true" ]; then | |
| # Get the latest commit from the target branch after merge | |
| git fetch origin "$TARGET_BRANCH" | |
| COMMIT_SHA=$(git rev-parse origin/$TARGET_BRANCH) | |
| else | |
| # If no changes, get the current HEAD SHA | |
| COMMIT_SHA=$(git rev-parse HEAD) | |
| fi | |
| echo "📍 Commit SHA for tagging: $COMMIT_SHA" | |
| echo "sha=$COMMIT_SHA" >> $GITHUB_OUTPUT | |
| - name: Create annotated tag via API | |
| run: | | |
| TAG_NAME="${{ vars.SIV_WEEKLY_BUILD_PREFIX }}-$(date +'%Y%m%d')" | |
| COMMIT_SHA="${{ steps.get-sha.outputs.sha }}" | |
| TAG_MESSAGE="Weekly Build - ${TAG_NAME}" | |
| echo "🚀 Creating tag: $TAG_NAME" | |
| echo "📍 Target commit: $COMMIT_SHA" | |
| echo "📝 Tag message: $TAG_MESSAGE" | |
| if [ "$COMMIT_SHA" = "" ] || [ "$COMMIT_SHA" = "null" ]; then | |
| echo "❌ Invalid commit SHA: $COMMIT_SHA" | |
| exit 1 | |
| fi | |
| echo "📝 Creating annotated tag object..." | |
| RESPONSE=$(curl -s -w "%{http_code}" -o tag_object.json \ | |
| -H "Authorization: Bearer ${{ secrets.SIV_USER_TOKEN_GH }}" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| -X POST \ | |
| https://api.github.com/repos/${{ github.repository }}/git/tags \ | |
| -d "{ | |
| \"tag\": \"${TAG_NAME}\", | |
| \"message\": \"${TAG_MESSAGE}\", | |
| \"object\": \"${COMMIT_SHA}\", | |
| \"type\": \"commit\" | |
| }") | |
| HTTP_CODE="${RESPONSE: -3}" | |
| if [ "$HTTP_CODE" -ne 201 ]; then | |
| printf "❌ Failed to create tag object!\n" | |
| printf "HTTP Code: %s\n" "$HTTP_CODE" | |
| cat tag_object.json | |
| exit 1 | |
| fi | |
| TAG_SHA=$(jq -r '.sha' tag_object.json) | |
| echo "✅ Tag object created: $TAG_SHA" | |
| echo "🔗 Creating tag reference..." | |
| RESPONSE=$(curl -s -w "%{http_code}" -o tag.json \ | |
| -H "Authorization: Bearer ${{ secrets.SIV_USER_TOKEN_GH }}" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| -H "Content-Type: application/json" \ | |
| -X POST \ | |
| https://api.github.com/repos/${{ github.repository }}/git/refs \ | |
| -d "{ | |
| \"ref\": \"refs/tags/${TAG_NAME}\", | |
| \"sha\": \"${TAG_SHA}\" | |
| }") | |
| HTTP_CODE="${RESPONSE: -3}" | |
| if [ "$HTTP_CODE" -eq 201 ]; then | |
| printf "\n" | |
| printf "✅ Weekly Build Tag Created Successfully!\n" | |
| printf "==========================================\n" | |
| printf "📌 Tag Name: %s\n" "${TAG_NAME}" | |
| printf "🔗 Commit SHA: %s\n" "${COMMIT_SHA}" | |
| printf "📁 Repository: %s\n" "${{ github.repository }}" | |
| printf "⏰ Created: %s\n" "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" | |
| printf "🌐 View Online: https://github.com/%s/releases/tag/%s\n" "${{ github.repository }}" "${TAG_NAME}" | |
| printf "\n" | |
| echo "📋 API Response:" | |
| cat tag.json | jq '.' | |
| else | |
| printf "\n" | |
| printf "❌ Failed to create tag!\n" | |
| printf "========================\n" | |
| printf "HTTP Code: %s\n" "$HTTP_CODE" | |
| printf "Response:\n" | |
| cat tag.json | |
| printf "\n" | |
| exit 1 | |
| fi |