Skip to content

feat: externalize packages for i18nify-go #130

feat: externalize packages for i18nify-go

feat: externalize packages for i18nify-go #130

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