Create repo manager workflow to apply repo settings #9
Workflow file for this run
This file contains 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: Repo Manager | |
on: | |
workflow_call: | |
secrets: | |
REPO_MGR_PRIVATE_KEY: | |
description: "GitHub App to generate ephemeral access tokens" | |
required: false | |
inputs: | |
org: | |
description: "Organization to manage, uses the organization of the triggering workflow by default" | |
type: string | |
required: false | |
action: | |
description: "Action to run (validate, check, or apply)" | |
type: string | |
required: false | |
default: "check" | |
workflow_dispatch: | |
inputs: | |
org: | |
description: "Organization to manage, uses the organization of the triggering workflow by default" | |
type: string | |
required: false | |
action: | |
description: "Action to run (validate, check, or apply)" | |
type: choice | |
required: false | |
options: | |
- validate | |
- check | |
- apply | |
schedule: | |
# at 20:00 every day | |
- cron: "20 * * * *" | |
pull_request: | |
branches: | |
- main | |
- master | |
# https://docs.github.com/en/actions/using-jobs/using-concurrency | |
concurrency: | |
group: ${{ github.workflow }} | |
# cancel jobs in progress for updated PRs, but not merge or tag events | |
cancel-in-progress: ${{ github.event.action == 'synchronize' }} | |
jobs: | |
prepare: | |
runs-on: ubuntu-latest | |
outputs: | |
repos: ${{ steps.get-repos.outputs.repos }} | |
action: ${{ inputs.action || steps.set-action.outputs.action || 'check' }} | |
steps: | |
# https://github.com/marketplace/actions/github-app-token | |
- name: Generate GitHub App installation token | |
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 | |
id: github-app-token | |
with: | |
app_id: ${{ vars.REPO_MGR_APP_ID }} | |
installation_retrieval_mode: organization | |
installation_retrieval_payload: ${{ inputs.org || github.event.organization.login }} | |
private_key: ${{ secrets.REPO_MGR_PRIVATE_KEY }} | |
permissions: >- | |
{ | |
"organization_administration": "read", | |
"metadata": "read" | |
} | |
# https://github.com/raven-actions/get-repos | |
- name: Get organization repositories | |
id: get-repos | |
uses: raven-actions/get-repos@v1.0.2 | |
with: | |
github-token: ${{ steps.github-app-token.outputs.token }} | |
owner: ${{ inputs.org || github.event.organization.login }} | |
# topics: "sync,docs,managed" | |
format: json | |
matrix-use: true | |
- name: Set action to "apply" | |
id: set-action | |
if: inputs.action == '' && github.event_name == 'schedule' | |
run: echo 'action=apply' >> $GITHUB_OUTPUT | |
repo-manager: | |
runs-on: ubuntu-latest | |
needs: [prepare] | |
if: ${{ needs.prepare.outputs.repos != '[]' }} | |
defaults: | |
run: | |
shell: bash | |
working-directory: . | |
strategy: | |
fail-fast: false | |
max-parallel: 8 | |
matrix: | |
repo: ${{ fromJson(needs.prepare.outputs.repos) }} | |
steps: | |
# https://github.com/marketplace/actions/github-app-token | |
- name: Generate GitHub App installation token | |
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 | |
id: github-app-token | |
with: | |
app_id: ${{ vars.REPO_MGR_APP_ID }} | |
installation_retrieval_mode: organization | |
installation_retrieval_payload: ${{ inputs.org || github.event.organization.login }} | |
private_key: ${{ secrets.REPO_MGR_PRIVATE_KEY }} | |
repositories: >- | |
[ | |
"${{ matrix.repo.name }}" | |
] | |
permissions: >- | |
{ | |
"administration": "write", | |
"contents": "read", | |
"metadata": "read" | |
} | |
# Checkout the repo that triggered the workflow. This may be the .github repo | |
# at the root of an organization, or some other repo being used for testing. | |
# Either way, we need to checkout the repo that triggered the workflow so we | |
# have a default settings.yml file to apply. | |
# https://github.com/actions/checkout | |
- name: Checkout trigger repo | |
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 | |
with: | |
repository: ${{ github.event.repository.full_name }} | |
path: ${{ github.event.repository.name }} | |
token: ${{ secrets.GITHUB_TOKEN }} | |
# Checkout the target repo. This is the repo that we are managing. | |
# If it has a .github/settings.yml, we will use that instead of the default | |
# from the triggering repo. | |
# https://github.com/actions/checkout | |
- name: Checkout target repo | |
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 | |
with: | |
repository: ${{ matrix.repo.full_name }} | |
ref: ${{ matrix.repo.default_branch }} | |
path: ${{ matrix.repo.name }} | |
token: ${{ steps.github-app-token.outputs.token }} | |
# Create a symlink to the preferred settings file. | |
- name: Link to settings file | |
env: | |
FILES: >- | |
${{ matrix.repo.name }}/.github/settings.yml | |
${{ github.event.repository.name }}/repo-settings.yml | |
${{ github.event.repository.name }}/.github/settings.yml | |
run: | | |
for file in $FILES; do | |
if [ -f "$file" ]; then | |
echo "Found settings file: $file" | |
ln -sv $file settings.yml | |
break | |
fi | |
done | |
- name: Substitute env vars | |
env: | |
DEFAULT_BRANCH: ${{ matrix.repo.default_branch }} | |
run: | | |
envsubst < settings.yml > settings.yml.tmp | |
mv settings.yml.tmp settings.yml | |
yq . settings.yml | |
- name: Save default branch required checks | |
continue-on-error: true | |
id: get-branch-protection | |
env: | |
GH_DEBUG: "true" | |
GH_PAGER: "cat" | |
GH_PROMPT_DISABLED: "true" | |
GH_TOKEN: ${{ steps.github-app-token.outputs.token }} | |
run: | | |
gh api repos/${{ matrix.repo.full_name }}/branches/${{ matrix.repo.default_branch }}/protection --jq '.required_status_checks.contexts' | yq eval -P > response.yml | |
- name: Remove any ResinCI checks | |
if: steps.get-branch-protection.outcome == 'success' | |
run: | | |
yq e 'del(.[] | select(. == "ResinCI*")))' response.yml > response.yml.tmp | |
mv response.yml.tmp response.yml | |
- name: Merge default branch required checks | |
if: steps.get-branch-protection.outcome == 'success' | |
run: | | |
yq eval-all '.branch_protections[0].protection.required_status_checks.checks += load("response.yml") | | |
.branch_protections[0].protection.required_status_checks.checks |= unique' settings.yml > settings.yml.tmp | |
mv settings.yml.tmp settings.yml | |
yq . settings.yml | |
# https://github.com/andrewthetechie/gha-repo-manager | |
- name: Run repo manager | |
uses: andrewthetechie/gha-repo-manager@v1.7.1 | |
with: | |
action: ${{ needs.prepare.outputs.action }} | |
token: ${{ steps.github-app-token.outputs.token }} | |
settings_file: settings.yml |