feat: externalize packages for i18nify-go #130
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 | |
| - 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 go.mod update | |
| if: steps.check-changes.outputs.has_changes == 'true' | |
| 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" | |
| - name: Push changes | |
| 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: | | |
| # Retry push up to 3 times | |
| 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 changes" | |
| 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 |