Sync Secrets from 1Password #18
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: Sync Secrets from 1Password | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: 'Perform a dry run (no changes made)' | |
| required: false | |
| default: false | |
| type: boolean | |
| schedule: | |
| # Run weekly on Sundays at 2 AM UTC to sync secrets | |
| - cron: '0 2 * * 0' | |
| permissions: | |
| contents: read | |
| jobs: | |
| sync-secrets: | |
| name: Sync 1Password to GitHub Secrets | |
| # Use self-hosted runner for secret synchronization | |
| runs-on: self-hosted | |
| if: vars.USE_1PASSWORD == 'true' || vars.USE_1PASSWORD != 'false' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install 1Password CLI | |
| uses: 1password/install-cli-action@v1 | |
| - name: Authenticate with 1Password | |
| uses: 1password/load-secrets-action@v2 | |
| with: | |
| export-env: false | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| - name: Sync secrets to GitHub (Dry Run) | |
| if: inputs.dry_run | |
| run: | | |
| echo "π§ͺ Performing dry run - no changes will be made" | |
| ./scripts/sync-secrets-to-github.sh --dry-run | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Sync secrets to GitHub | |
| if: '!inputs.dry_run' | |
| run: | | |
| echo "π Syncing secrets from 1Password to GitHub" | |
| ./scripts/sync-secrets-to-github.sh | |
| env: | |
| OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Verify deployment after sync | |
| if: '!inputs.dry_run' | |
| run: | | |
| echo "π Testing deployment with synced secrets" | |
| # Trigger the deploy workflow to test the synced secrets | |
| gh workflow run deploy.yml --ref ${{ github.ref }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Summary | |
| run: | | |
| echo "## π Secret Sync Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Repository**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Triggered by**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Dry run**: ${{ inputs.dry_run || 'false' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Status**: β Completed successfully" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [[ "${{ inputs.dry_run }}" == "true" ]]; then | |
| echo "No changes were made during this dry run." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "Secrets have been synced from 1Password to GitHub repository secrets." >> $GITHUB_STEP_SUMMARY | |
| echo "The deployment workflow has been triggered to verify the synced secrets." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### π Next Steps" >> $GITHUB_STEP_SUMMARY | |
| echo "- Monitor the deployment workflow for any issues" >> $GITHUB_STEP_SUMMARY | |
| echo "- Check 1Password audit logs for secret access" >> $GITHUB_STEP_SUMMARY | |
| echo "- Consider rotating secrets if needed" >> $GITHUB_STEP_SUMMARY | |
| notify-on-failure: | |
| name: Notify on Sync Failure | |
| # Use self-hosted runner for failure notifications | |
| runs-on: self-hosted | |
| needs: sync-secrets | |
| if: failure() && !cancelled() | |
| steps: | |
| - name: Create issue on failure | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const title = 'π¨ Secret Sync Failed'; | |
| const body = `## Secret Sync Failure | |
| The automated sync from 1Password to GitHub secrets has failed. | |
| **Details:** | |
| - **Repository**: ${{ github.repository }} | |
| - **Workflow**: ${{ github.workflow }} | |
| - **Run ID**: ${{ github.run_id }} | |
| - **Triggered by**: ${{ github.event_name }} | |
| - **Time**: ${{ github.event.head_commit.timestamp || github.event.repository.updated_at }} | |
| **Action Required:** | |
| 1. Check the workflow logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| 2. Verify 1Password service account permissions | |
| 3. Check GitHub token permissions | |
| 4. Manually run: \`./scripts/sync-secrets-to-github.sh --dry-run\` | |
| 5. Fix any issues and re-run the sync | |
| **Monitoring:** | |
| - Deployment may fail until secrets are synced | |
| - Check 1Password audit logs for authentication issues | |
| - Verify repository secrets in Settings > Secrets and variables > Actions | |
| This issue was created automatically by the sync-secrets workflow.`; | |
| // Check if issue already exists | |
| const { data: issues } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| labels: 'automation,secrets,1password' | |
| }); | |
| const existingIssue = issues.find(issue => issue.title === title); | |
| if (!existingIssue) { | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: title, | |
| body: body, | |
| labels: ['bug', 'automation', 'secrets', '1password', 'high-priority'] | |
| }); | |
| console.log('Created new issue for secret sync failure'); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: existingIssue.number, | |
| body: `Another secret sync failure occurred at ${{ github.event.head_commit.timestamp || github.event.repository.updated_at }}.\n\nWorkflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}` | |
| }); | |
| console.log('Added comment to existing secret sync failure issue'); | |
| } |