feat: externalize packages for i18nify-go #136
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: Auto-Generate Go Packages | |
| on: | |
| pull_request: | |
| types: [opened, synchronize] | |
| branches: | |
| - master | |
| paths: | |
| - 'i18nify-data/country/subdivisions/**' | |
| - 'i18nify-data/currency/**' | |
| - 'i18nify-data/bankcodes/**' | |
| - 'i18nify-data/country/metadata/**' | |
| - '!i18nify-data/go/**' # Ignore generated files | |
| push: | |
| branches: | |
| - master | |
| paths: | |
| - 'i18nify-data/country/subdivisions/**' | |
| - 'i18nify-data/currency/**' | |
| - 'i18nify-data/bankcodes/**' | |
| - 'i18nify-data/country/metadata/**' | |
| - '!i18nify-data/go/**' | |
| # Manual trigger via PR comment (only works from default branch) | |
| # Comment "generate-package-go" to regenerate all packages with proto | |
| # Comment "generate-package-go country/subdivisions" to regenerate specific package | |
| issue_comment: | |
| types: [created] | |
| # Manual trigger via GitHub Actions UI | |
| workflow_dispatch: | |
| inputs: | |
| package: | |
| description: 'Package to generate (e.g., country/subdivisions). Leave empty for all.' | |
| required: false | |
| default: '' | |
| branch: | |
| description: 'Branch to run on' | |
| required: true | |
| default: 'master' | |
| concurrency: | |
| group: auto-generate-go-${{ github.event_name }}-${{ github.event.issue.number || github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| # Check if comment trigger is valid | |
| check-comment: | |
| name: Check Comment Trigger | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'issue_comment' | |
| outputs: | |
| should_run: ${{ steps.check.outputs.should_run }} | |
| packages: ${{ steps.check.outputs.packages }} | |
| pr_number: ${{ steps.check.outputs.pr_number }} | |
| pr_head_ref: ${{ steps.pr-info.outputs.pr_head_ref }} | |
| steps: | |
| - name: Check if comment triggers workflow | |
| id: check | |
| env: | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| IS_PR: ${{ github.event.issue.pull_request != null }} | |
| run: | | |
| # Only run on PR comments | |
| if [ "$IS_PR" != "true" ]; then | |
| echo "Not a PR comment, skipping" | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Check if comment starts with "generate-package-go" | |
| if [[ "$COMMENT_BODY" != generate-package-go* ]]; then | |
| echo "Comment doesn't match trigger, skipping" | |
| echo "should_run=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "should_run=true" >> $GITHUB_OUTPUT | |
| echo "pr_number=${{ github.event.issue.number }}" >> $GITHUB_OUTPUT | |
| # Extract package name if specified (e.g., "generate-package-go country/subdivisions") | |
| PACKAGE=$(echo "$COMMENT_BODY" | sed 's/generate-package-go//' | xargs) | |
| if [ -n "$PACKAGE" ]; then | |
| # Specific package requested | |
| echo "packages=[\"$PACKAGE\"]" >> $GITHUB_OUTPUT | |
| echo "Specific package requested: $PACKAGE" | |
| else | |
| # All packages with proto | |
| echo 'packages=["country/subdivisions","currency","bankcodes","country/metadata"]' >> $GITHUB_OUTPUT | |
| echo "All packages will be checked" | |
| fi | |
| - name: Get PR head ref | |
| if: steps.check.outputs.should_run == 'true' | |
| id: pr-info | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }}) | |
| HEAD_REF=$(echo "$PR_DATA" | jq -r '.head.ref') | |
| echo "pr_head_ref=$HEAD_REF" >> $GITHUB_OUTPUT | |
| - name: React to comment | |
| if: steps.check.outputs.should_run == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions -f content='+1' | |
| # Handle workflow_dispatch (manual UI trigger) | |
| check-dispatch: | |
| name: Check Manual Dispatch | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' | |
| outputs: | |
| packages: ${{ steps.setup.outputs.packages }} | |
| branch: ${{ steps.setup.outputs.branch }} | |
| steps: | |
| - name: Setup dispatch parameters | |
| id: setup | |
| env: | |
| PACKAGE: ${{ github.event.inputs.package }} | |
| BRANCH: ${{ github.event.inputs.branch }} | |
| run: | | |
| echo "branch=$BRANCH" >> $GITHUB_OUTPUT | |
| if [ -n "$PACKAGE" ]; then | |
| echo "packages=[\"$PACKAGE\"]" >> $GITHUB_OUTPUT | |
| echo "Specific package: $PACKAGE" | |
| else | |
| echo 'packages=["country/subdivisions","currency","bankcodes","country/metadata"]' >> $GITHUB_OUTPUT | |
| echo "All packages will be checked" | |
| fi | |
| detect-changes: | |
| name: Detect Package Changes | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request' || github.event_name == 'push' | |
| outputs: | |
| packages: ${{ steps.filter.outputs.changes }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| base: ${{ github.event.pull_request.base.ref || github.event.before || 'HEAD~1' }} | |
| filters: | | |
| country/subdivisions: | |
| - 'i18nify-data/country/subdivisions/**' | |
| - '!i18nify-data/country/subdivisions/README.md' | |
| currency: | |
| - 'i18nify-data/currency/**' | |
| - '!i18nify-data/currency/README.md' | |
| bankcodes: | |
| - 'i18nify-data/bankcodes/**' | |
| - '!i18nify-data/bankcodes/README.md' | |
| country/metadata: | |
| - 'i18nify-data/country/metadata/**' | |
| - '!i18nify-data/country/metadata/README.md' | |
| generate-packages: | |
| name: Generate Go Package | |
| runs-on: ubuntu-latest | |
| needs: [detect-changes, check-comment, check-dispatch] | |
| # Run if: (auto-trigger with changes) OR (comment trigger) OR (manual dispatch) | |
| if: | | |
| always() && ( | |
| (needs.detect-changes.result == 'success' && needs.detect-changes.outputs.packages != '[]' && needs.detect-changes.outputs.packages != '') || | |
| (needs.check-comment.result == 'success' && needs.check-comment.outputs.should_run == 'true') || | |
| (needs.check-dispatch.result == 'success') | |
| ) | |
| strategy: | |
| matrix: | |
| package: ${{ fromJson(needs.check-dispatch.outputs.packages || needs.check-comment.outputs.packages || needs.detect-changes.outputs.packages || '[]') }} | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| ref: ${{ needs.check-dispatch.outputs.branch || needs.check-comment.outputs.pr_head_ref || github.event.pull_request.head.ref || github.ref_name }} | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.20' | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler jq | |
| - name: Install protoc-gen-go | |
| run: go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 | |
| - name: Add Go bin to PATH | |
| run: echo "$HOME/go/bin" >> $GITHUB_PATH | |
| - name: Check if proto exists for package | |
| id: check-proto | |
| run: | | |
| PACKAGE_PATH="${{ matrix.package }}" | |
| PROTO_DIR="i18nify-data/$PACKAGE_PATH/proto" | |
| if [ -d "$PROTO_DIR" ] && ls "$PROTO_DIR"/*.proto 1> /dev/null 2>&1; then | |
| echo "has_proto=true" >> $GITHUB_OUTPUT | |
| echo "Proto found for $PACKAGE_PATH" | |
| else | |
| echo "has_proto=false" >> $GITHUB_OUTPUT | |
| echo "No proto found for $PACKAGE_PATH - skipping generation" | |
| fi | |
| - name: Generate Go package | |
| if: steps.check-proto.outputs.has_proto == 'true' | |
| id: generate | |
| run: | | |
| chmod +x .github/scripts/go/generate-package.sh | |
| OUTPUT_DIR=$(.github/scripts/go/generate-package.sh "${{ matrix.package }}" | tail -1) | |
| echo "output_dir=$OUTPUT_DIR" >> $GITHUB_OUTPUT | |
| - name: Check for changes | |
| if: steps.check-proto.outputs.has_proto == 'true' | |
| id: check-changes | |
| run: | | |
| PACKAGE_PATH="${{ matrix.package }}" | |
| DEST_DIR="i18nify-data/go/$PACKAGE_PATH" | |
| if [ ! -d "$DEST_DIR" ]; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| CHANGES=$(git status --porcelain "$DEST_DIR" 2>&1 || echo "") | |
| if [ -n "$CHANGES" ]; then | |
| echo "Changes detected:" | |
| echo "$CHANGES" | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "No changes detected" | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Commit generated package | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| PACKAGE_PATH="${{ matrix.package }}" | |
| PACKAGE_NAME=$(echo "$PACKAGE_PATH" | tr '/' '-') | |
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
| git config --local user.name "github-actions[bot]" | |
| git add "i18nify-data/go/$PACKAGE_PATH" | |
| git commit -m "chore: auto-regenerate $PACKAGE_NAME Go package" | |
| - name: Generate pseudo-version | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| id: version | |
| run: | | |
| COMMIT_SHA=$(git rev-parse HEAD) | |
| SHORT_SHA=$(echo "$COMMIT_SHA" | cut -c1-12) | |
| TIMESTAMP=$(TZ=UTC git show -s --format=%cd --date=format-local:%Y%m%d%H%M%S "$COMMIT_SHA") | |
| VERSION="v0.0.0-${TIMESTAMP}-${SHORT_SHA}" | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "commit_sha=$COMMIT_SHA" >> $GITHUB_OUTPUT | |
| # Push generated package FIRST so go mod tidy can resolve the module | |
| - name: Push generated package | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| env: | |
| BRANCH: ${{ needs.check-dispatch.outputs.branch || needs.check-comment.outputs.pr_head_ref || github.event.pull_request.head.ref || github.ref_name }} | |
| run: | | |
| MAX_RETRIES=3 | |
| RETRY_COUNT=0 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| git pull --rebase origin "$BRANCH" || true | |
| if git push origin HEAD:"$BRANCH"; then | |
| echo "Successfully pushed generated package" | |
| exit 0 | |
| else | |
| echo "Push failed, attempt $((RETRY_COUNT + 1))/$MAX_RETRIES" | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| sleep 2 | |
| fi | |
| done | |
| echo "Failed to push after $MAX_RETRIES attempts" | |
| exit 1 | |
| # Now that module is on GitHub, update go.mod with proper go.sum | |
| - name: Update i18nify-go dependencies | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| run: | | |
| chmod +x .github/scripts/go/update-dependencies.sh | |
| .github/scripts/go/update-dependencies.sh "${{ matrix.package }}" "${{ steps.version.outputs.version }}" | |
| - name: Commit and push go.mod update | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| env: | |
| BRANCH: ${{ needs.check-dispatch.outputs.branch || needs.check-comment.outputs.pr_head_ref || github.event.pull_request.head.ref || github.ref_name }} | |
| run: | | |
| git add packages/i18nify-go/go.mod packages/i18nify-go/go.sum | |
| git commit -m "chore(go): update ${{ matrix.package }} dependency to ${{ steps.version.outputs.version }}" || { | |
| echo "No go.mod changes to commit" | |
| exit 0 | |
| } | |
| MAX_RETRIES=3 | |
| RETRY_COUNT=0 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| git pull --rebase origin "$BRANCH" || true | |
| if git push origin HEAD:"$BRANCH"; then | |
| echo "Successfully pushed go.mod update" | |
| exit 0 | |
| else | |
| echo "Push failed, attempt $((RETRY_COUNT + 1))/$MAX_RETRIES" | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| sleep 2 | |
| fi | |
| done | |
| echo "Failed to push after $MAX_RETRIES attempts" | |
| exit 1 | |
| - name: Comment on PR | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PACKAGE_PATH="${{ matrix.package }}" | |
| PACKAGE_NAME=$(echo "$PACKAGE_PATH" | tr '/' '-') | |
| VERSION="${{ steps.version.outputs.version }}" | |
| MODULE_PATH="github.com/razorpay/i18nify/i18nify-data/go/$PACKAGE_PATH" | |
| PR_NUMBER="${{ needs.check-comment.outputs.pr_number || github.event.pull_request.number }}" | |
| # Skip if no PR number (push to master) | |
| if [ -z "$PR_NUMBER" ]; then | |
| echo "No PR number, skipping comment" | |
| exit 0 | |
| fi | |
| cat <<EOF > /tmp/pr-comment.md | |
| ## 📦 Data Package Update | |
| **Package:** \`$PACKAGE_NAME\` | |
| **Version:** \`$VERSION\` | |
| **Module:** \`$MODULE_PATH\` | |
| ### To manually update to this version: | |
| \`\`\`bash | |
| cd packages/i18nify-go | |
| go get ${MODULE_PATH}@${VERSION} | |
| go mod tidy | |
| \`\`\` | |
| Or use the update script: | |
| \`\`\`bash | |
| .github/scripts/go/update-dependencies.sh $PACKAGE_PATH $VERSION | |
| \`\`\` | |
| --- | |
| *Auto-generated by GitHub Actions* | |
| EOF | |
| gh pr comment "$PR_NUMBER" --body-file /tmp/pr-comment.md |