feat: Proposal 2 - YAML anchors (native YAML feature) #8
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: Build Mobile App | ||
|
Check failure on line 1 in .github/workflows/build.yml
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| environment: | ||
| required: true | ||
| type: string | ||
| platform: | ||
| required: true | ||
| type: choice | ||
| options: [android, ios, both] | ||
| build_type: | ||
| required: true | ||
| type: choice | ||
| options: [main, flask] | ||
| default: main | ||
| workflow_dispatch: | ||
| inputs: | ||
| environment: | ||
| required: true | ||
| type: choice | ||
| options: [prod, rc, exp] | ||
| platform: | ||
| required: true | ||
| type: choice | ||
| options: [android, ios, both] | ||
| build_type: | ||
| required: true | ||
| type: choice | ||
| options: [main, flask] | ||
| default: main | ||
| jobs: | ||
| load-environment-config: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| config: ${{ steps.load-config.outputs.config }} | ||
| requires_approval: ${{ steps.load-config.outputs.requires_approval }} | ||
| github_environment: ${{ steps.load-config.outputs.github_environment }} | ||
| secrets_mapping: ${{ steps.load-config.outputs.secrets_mapping }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| - name: Install dependencies | ||
| run: yarn install --immutable | ||
| - name: Load environment configuration (YAML anchors) | ||
| id: load-config | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const { loadConfigWithAnchors } = require('./scripts/load-yaml-config.js'); | ||
| const env = '${{ inputs.environment }}'; | ||
| const config = loadConfigWithAnchors(env); | ||
| // Extract secrets mapping | ||
| const secretsMapping = JSON.stringify(config.secrets || {}); | ||
| return { | ||
| config: JSON.stringify(config), | ||
| requires_approval: config.environment.requires_approval, | ||
| github_environment: config.environment.github_environment, | ||
| secrets_mapping: secretsMapping | ||
| }; | ||
| approval: | ||
| if: needs.load-environment-config.outputs.requires_approval == 'true' | ||
| needs: load-environment-config | ||
| runs-on: ubuntu-latest | ||
| environment: ${{ needs.load-environment-config.outputs.github_environment }} | ||
| steps: | ||
| - name: Wait for approval | ||
| run: echo "Approval required for ${{ inputs.environment }} builds" | ||
| build: | ||
| needs: | ||
| - load-environment-config | ||
| - approval | ||
| if: always() && (needs.approval.result == 'success' || needs.approval.result == 'skipped') | ||
| strategy: | ||
| matrix: | ||
| platform: ${{ inputs.platform == 'both' && fromJSON('["android", "ios"]') || fromJSON(format('["{0}"]', inputs.platform)) }} | ||
| runs-on: ${{ matrix.platform == 'ios' && 'macos-latest' || 'ubuntu-latest' }} | ||
| environment: ${{ needs.load-environment-config.outputs.github_environment }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| cache: 'yarn' | ||
| - name: Install dependencies | ||
| run: yarn install --immutable | ||
| - name: Setup project | ||
| run: yarn setup:github-ci | ||
| - name: Apply environment configuration | ||
| id: apply-config | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const { loadConfigWithAnchors } = require('./scripts/load-yaml-config.js'); | ||
| const env = '${{ inputs.environment }}'; | ||
| const config = loadConfigWithAnchors(env); | ||
| // Set non-secret environment variables from merged config | ||
| const outputs = {}; | ||
| // Server URLs | ||
| Object.entries(config.servers).forEach(([key, value]) => { | ||
| const envVar = key.toUpperCase(); | ||
| outputs[envVar] = value; | ||
| core.exportVariable(envVar, value); | ||
| }); | ||
| // Feature flags | ||
| Object.entries(config.features).forEach(([key, value]) => { | ||
| const envVar = key.toUpperCase(); | ||
| outputs[envVar] = value.toString(); | ||
| core.exportVariable(envVar, value.toString()); | ||
| }); | ||
| // Build configuration | ||
| core.exportVariable('METAMASK_ENVIRONMENT', config.environment.name); | ||
| core.exportVariable('METAMASK_BUILD_TYPE', '${{ inputs.build_type }}'); | ||
| // Output for other steps | ||
| Object.entries(outputs).forEach(([key, value]) => { | ||
| core.setOutput(key.toLowerCase().replace(/_/g, '_'), value); | ||
| }); | ||
| - name: Set secrets as environment variables | ||
| env: | ||
| CONFIG_SECRETS: ${{ needs.load-environment-config.outputs.secrets_mapping }} | ||
| run: | | ||
| # Note: GitHub Actions doesn't allow dynamic secret access | ||
| # Secrets must be configured in the GitHub environment and accessed directly | ||
| echo "Secrets mapping loaded. Secrets should be configured in GitHub environment settings." | ||
| echo "$CONFIG_SECRETS" | jq -r 'to_entries[] | "export \(.key)=\"${{ secrets.\(.value) }}\""' || true | ||
| - name: Build ${{ matrix.platform }} | ||
| run: | | ||
| ./scripts/build.sh ${{ matrix.platform }} ${{ inputs.build_type }} ${{ inputs.environment }} | ||