diff --git a/.github/workflows/update_fsc_evm_version.yml b/.github/workflows/update_fsc_evm_version.yml new file mode 100644 index 00000000..e7688c8e --- /dev/null +++ b/.github/workflows/update_fsc_evm_version.yml @@ -0,0 +1,260 @@ +name: Update fsc-evm Version Across Repos + +on: + workflow_dispatch: + inputs: + version: + description: 'New fsc-evm version tag (e.g., v4.5.4)' + required: true + type: string + projects: + description: 'Comma-separated github_repo names or "all" (default: all)' + required: false + type: string + default: 'all' + dry_run: + description: 'Dry run - show what would be updated without creating PRs' + required: true + type: boolean + default: true + +env: + ORG: FlipsideCrypto + +jobs: + update-packages: + runs-on: ubuntu-latest + name: Update fsc-evm to ${{ inputs.version }} + steps: + - name: Checkout fsc-evm repository + uses: actions/checkout@v4 + + - name: Process repositories + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + VERSION="${{ inputs.version }}" + PROJECTS="${{ inputs.projects }}" + DRY_RUN="${{ inputs.dry_run }}" + + echo "🚀 Starting fsc-evm version update to ${VERSION}" + echo "================================================" + + # Parse CSV to get active repos + if [ ! -f "data/admin__repos.csv" ]; then + echo "❌ Error: data/admin__repos.csv not found" + exit 1 + fi + + # Build repo list based on input + if [ "$PROJECTS" = "all" ]; then + # Get all active repos (skip header, filter is_active=true, get github_repo column) + mapfile -t REPOS < <(awk -F',' 'NR>1 && $4=="true" {print $2}' data/admin__repos.csv) + echo "📋 Found ${#REPOS[@]} active repositories" + else + # Parse comma-separated list + IFS=',' read -ra REQUESTED <<< "$PROJECTS" + REPOS=() + for req in "${REQUESTED[@]}"; do + req=$(echo "$req" | xargs) # trim + if grep -q ",${req}," data/admin__repos.csv; then + REPOS+=("$req") + else + echo "⚠️ Warning: ${req} not found in data/admin__repos.csv" + fi + done + echo "📋 Processing ${#REPOS[@]} requested repositories" + fi + + if [ ${#REPOS[@]} -eq 0 ]; then + echo "❌ No repositories to process" + exit 1 + fi + + # Initialize counters + SUCCESS_COUNT=0 + SKIP_COUNT=0 + FAIL_COUNT=0 + declare -A RESULTS + + # Process each repository + for repo in "${REPOS[@]}"; do + FULL_REPO="${ORG}/${repo}" + echo "" + echo "📦 Processing ${repo}..." + + # Create temp directory + TEMP_DIR=$(mktemp -d) + trap "rm -rf $TEMP_DIR" EXIT + + # Clone repository + if ! git clone -q "https://github.com/${FULL_REPO}.git" "${TEMP_DIR}/${repo}" 2>/dev/null; then + echo " ❌ Failed to clone repository" + RESULTS["${repo}"]="FAILED: Could not clone repository" + ((FAIL_COUNT++)) + continue + fi + + cd "${TEMP_DIR}/${repo}" + + # Check for packages.yml + if [ ! -f "packages.yml" ]; then + echo " ❌ packages.yml not found" + RESULTS["${repo}"]="FAILED: packages.yml not found" + ((FAIL_COUNT++)) + cd - > /dev/null + continue + fi + + # Get current version + CURRENT_VERSION=$(grep -E "revision:\s*" packages.yml | sed 's/.*revision:\s*//') + echo " 📌 Current version: ${CURRENT_VERSION}" + + # Check if already at target version + if [ "${CURRENT_VERSION}" = "${VERSION}" ]; then + echo " ⏭️ Already at version ${VERSION}, skipping" + RESULTS["${repo}"]="SKIPPED: Already at ${VERSION}" + ((SKIP_COUNT++)) + cd - > /dev/null + continue + fi + + if [ "$DRY_RUN" = "true" ]; then + echo " 🔍 [DRY RUN] Would update from ${CURRENT_VERSION} to ${VERSION}" + RESULTS["${repo}"]="DRY RUN: Would update ${CURRENT_VERSION} → ${VERSION}" + ((SUCCESS_COUNT++)) + cd - > /dev/null + continue + fi + + # Create branch and update + BRANCH="update-fsc-evm-${VERSION//\./-}" + git checkout -q -b "${BRANCH}" + + # Update packages.yml + sed -i "s/revision:.*/revision: ${VERSION}/" packages.yml + + # Configure git + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Commit + git add packages.yml + git commit -q -m "chore: update fsc-evm to ${VERSION}" + + # Push + if ! git push -q origin "${BRANCH}" 2>/dev/null; then + echo " ❌ Failed to push branch" + RESULTS["${repo}"]="FAILED: Could not push branch" + ((FAIL_COUNT++)) + cd - > /dev/null + continue + fi + + # Create PR + PR_BODY="## 🔄 Automated fsc-evm Update + + This PR updates the fsc-evm package version from \\\`${CURRENT_VERSION}\\\` to \\\`${VERSION}\\\`. + + ### Changes + \\\`\\\`\\\`diff + packages: + - git: https://github.com/FlipsideCrypto/fsc-evm.git + - revision: ${CURRENT_VERSION} + + revision: ${VERSION} + \\\`\\\`\\\` + + --- + *This PR was auto-generated by the fsc-evm version update workflow.*" + + # Create PR and capture output + PR_OUTPUT=$(gh pr create \ + --repo "${FULL_REPO}" \ + --title "chore: update fsc-evm to ${VERSION}" \ + --body "${PR_BODY}" \ + --base main \ + --head "${BRANCH}" 2>&1) || true + + if echo "$PR_OUTPUT" | grep -q "github.com"; then + PR_URL=$(echo "$PR_OUTPUT" | grep -o 'https://github.com/[^ ]*' | head -1) + echo " ✅ PR created: ${PR_URL}" + RESULTS["${repo}"]="SUCCESS: ${PR_URL}" + ((SUCCESS_COUNT++)) + elif echo "$PR_OUTPUT" | grep -q "already exists"; then + # Get existing PR + EXISTING_PR=$(gh pr list --repo "${FULL_REPO}" --head "${BRANCH}" --json url -q '.[0].url') + echo " ⚠️ PR already exists: ${EXISTING_PR}" + RESULTS["${repo}"]="EXISTS: ${EXISTING_PR}" + ((SUCCESS_COUNT++)) + else + echo " ❌ Failed to create PR" + RESULTS["${repo}"]="FAILED: Could not create PR" + ((FAIL_COUNT++)) + fi + + cd - > /dev/null + done + + # Final summary + echo "" + echo "================================================" + echo "📊 SUMMARY" + echo "================================================" + echo "Total repositories: ${#REPOS[@]}" + echo "✅ Successful: ${SUCCESS_COUNT}" + echo "⏭️ Skipped: ${SKIP_COUNT}" + echo "❌ Failed: ${FAIL_COUNT}" + + # Detailed results + echo "" + echo "📝 Detailed Results:" + echo "-------------------" + for repo in "${!RESULTS[@]}"; do + status="${RESULTS[$repo]}" + if [[ $status == SUCCESS* ]]; then + echo "✅ ${repo}: ${status}" + elif [[ $status == SKIPPED* ]] || [[ $status == EXISTS* ]]; then + echo "⏭️ ${repo}: ${status}" + elif [[ $status == "DRY RUN"* ]]; then + echo "🔍 ${repo}: ${status}" + else + echo "❌ ${repo}: ${status}" + fi + done | sort + + # Set job summary + { + echo "# fsc-evm Version Update Summary" + echo "" + echo "**Version:** ${VERSION}" + echo "**Total Repositories:** ${#REPOS[@]}" + echo "" + echo "| Status | Count |" + echo "|--------|-------|" + echo "| ✅ Successful | ${SUCCESS_COUNT} |" + echo "| ⏭️ Skipped | ${SKIP_COUNT} |" + echo "| ❌ Failed | ${FAIL_COUNT} |" + echo "" + echo "## Pull Requests Created" + echo "" + for repo in "${!RESULTS[@]}"; do + status="${RESULTS[$repo]}" + if [[ $status == SUCCESS* ]]; then + url="${status#SUCCESS: }" + echo "- [${repo}](${url})" + fi + done | sort + } >> $GITHUB_STEP_SUMMARY + + # Exit with error if any failed + if [ $FAIL_COUNT -gt 0 ]; then + echo "" + echo "❌ Some repositories failed to update" + exit 1 + else + echo "" + echo "✨ All repositories processed successfully!" + fi \ No newline at end of file diff --git a/.github/workflows/update_fsc_evm_version_minimal.yml b/.github/workflows/update_fsc_evm_version_minimal.yml deleted file mode 100644 index 2bf9b7c1..00000000 --- a/.github/workflows/update_fsc_evm_version_minimal.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Update fsc-evm Version Across Repos - -on: - workflow_dispatch: - inputs: - version: - description: 'New fsc-evm version tag (e.g., v4.5.4)' - required: true - type: string - projects: - description: 'Comma-separated github_repo names or "all" (default: all)' - required: false - type: string - default: 'all' - -jobs: - update-packages: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Test - run: | - echo "Version: ${{ inputs.version }}" - echo "Projects: ${{ inputs.projects }}" - echo "This is a test" \ No newline at end of file