Skip to content

Commit d5791c9

Browse files
committed
refactor(apply-repo-settings): remove all templating; action is now pure merge
The action no longer takes app-id or private-key — it requires only a pre-generated token (with administration:write). It applies the settings file verbatim, with no placeholder substitution. Templating moved upstream to nsheaps/.github, where repo-settings.template.yaml is rendered (envsubst) into repo-settings.yaml at the source. https://claude.ai/code/session_01XUJx6sKWxyKyoWdxNEsET1
1 parent 9138eed commit d5791c9

3 files changed

Lines changed: 20 additions & 53 deletions

File tree

‎.github/actions/apply-repo-settings/README.md‎

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ The upstream app is a Probot webhook server — it's designed to listen for `pus
1010

1111
## Inputs
1212

13-
| Input | Required | Default | Description |
14-
| --------------- | -------- | ---------------------- | ------------------------------------------------------------------ |
15-
| `app-id` | yes | — | GitHub App ID. Needs `Administration: write` and `Contents: read`. |
16-
| `private-key` | yes | — | The App's PEM private key. |
17-
| `owner` | no | current owner | Target repo owner. |
18-
| `repo` | no | current repo | Target repo name. |
19-
| `settings-file` | no | `.github/settings.yml` | Path to the YAML to apply. |
20-
| `dry-run` | no | `false` | Print what would change without applying. |
21-
| `sections` | no | `repository,rulesets` | Comma-separated section names to apply. |
13+
| Input | Required | Default | Description |
14+
| --------------- | -------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- |
15+
| `token` | yes | — | GitHub token with `Administration: write` on the target repo (typically from `checkout-as-app` or `github-app-auth`). |
16+
| `owner` | no | current owner | Target repo owner. |
17+
| `repo` | no | current repo | Target repo name. |
18+
| `settings-file` | no | `.github/settings.yml` | Path to the YAML to apply. |
19+
| `dry-run` | no | `false` | Print what would change without applying. |
20+
| `sections` | no | `repository,rulesets` | Comma-separated section names to apply. |
21+
22+
The action does **not** do any templating or placeholder substitution on `settings-file` — it applies the YAML as-is. If you need env-var-based substitution (e.g. resolving a GitHub App ID into `bypass_actors[].actor_id`), render the file upstream (e.g. with `envsubst`) before invoking this action.
2223

2324
## Outputs
2425

@@ -37,7 +38,7 @@ Source: [`pages/index.html`](../../../pages/index.html). Deployed by [`.github/w
3738
After creating the app:
3839

3940
1. Install it on every repo you want to manage.
40-
2. Add `APPLY_REPO_SETTINGS_APP_ID` and `APPLY_REPO_SETTINGS_PRIVATE_KEY` as secrets.
41+
2. Add `APPLY_REPO_SETTINGS_APP_ID` and `APPLY_REPO_SETTINGS_PRIVATE_KEY` as secrets (consumed by `checkout-as-app` / `github-app-auth` — this action only takes the resulting token).
4142

4243
## Example workflow
4344

@@ -65,11 +66,15 @@ jobs:
6566
apply:
6667
runs-on: ubuntu-latest
6768
steps:
68-
- uses: actions/checkout@v6
69-
- uses: nsheaps/github-actions/.github/actions/apply-repo-settings@main
69+
- name: Checkout as GitHub App
70+
id: checkout
71+
uses: nsheaps/github-actions/.github/actions/checkout-as-app@main
7072
with:
7173
app-id: ${{ secrets.APPLY_REPO_SETTINGS_APP_ID }}
7274
private-key: ${{ secrets.APPLY_REPO_SETTINGS_PRIVATE_KEY }}
75+
- uses: nsheaps/github-actions/.github/actions/apply-repo-settings@main
76+
with:
77+
token: ${{ steps.checkout.outputs.token }}
7378
dry-run: ${{ inputs.dry-run || false }}
7479
```
7580

‎.github/actions/apply-repo-settings/action.sh‎

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ set -euo pipefail
1717
: "${SETTINGS_FILE:=.github/settings.yml}"
1818
: "${DRY_RUN:=false}"
1919
: "${SECTIONS:=repository,rulesets}"
20-
: "${APP_ID:=}"
21-
# APP_ID is only needed if the settings file still contains actor_id: -1 placeholders.
22-
# Normally the .github sync workflow resolves placeholders before distributing settings.yml.
2320

2421
if [[ ! -f "$SETTINGS_FILE" ]]; then
2522
echo "::error file=$SETTINGS_FILE::settings file not found"
@@ -132,19 +129,6 @@ apply_rulesets() {
132129
name="$(yq -r ".rulesets[$i].name" "$SETTINGS_FILE")"
133130
body="$(yq -o=json ".rulesets[$i]" "$SETTINGS_FILE")"
134131

135-
# Substitute actor_id -1 placeholder for Integration bypass actors with the real App ID.
136-
# actor_id must be the GitHub App ID (integer), not the installation ID.
137-
# Gracefully skip Integration bypass actors if APP_ID is not configured.
138-
if [[ -n "$APP_ID" ]]; then
139-
body="$(echo "$body" | jq \
140-
--argjson app_id "$APP_ID" \
141-
'.bypass_actors //= [] | .bypass_actors |= map(if .actor_type == "Integration" and .actor_id == -1 then .actor_id = $app_id else . end)')"
142-
else
143-
body="$(echo "$body" | jq \
144-
'if .bypass_actors then .bypass_actors |= map(select(not (.actor_type == "Integration" and .actor_id == -1))) else . end')"
145-
info "APP_ID not set — skipping placeholder Integration bypass actors for: $name"
146-
fi
147-
148132
existing_id="$(echo "$existing" | jq -r --arg n "$name" '.[] | select(.name == $n) | .id // empty')"
149133

150134
if [[ -z "$existing_id" ]]; then

‎.github/actions/apply-repo-settings/action.yml‎

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,8 @@ branding:
77

88
inputs:
99
token:
10-
description: 'Pre-generated GitHub App installation token. When provided, app-id/private-key are not used for authentication. app-id is still required for substituting the actor_id: -1 placeholder in Integration bypass actors.'
11-
required: false
12-
default: ''
13-
14-
app-id:
15-
description: 'GitHub App ID. Used to substitute the actor_id: -1 placeholder in Integration bypass actors. Also used for authentication when token is not provided. When token is provided and app-id is omitted, the app ID is derived from the installation token at runtime via GET /app.'
16-
required: false
17-
default: ''
18-
19-
private-key:
20-
description: 'GitHub App private key (PEM). Required when token is not provided.'
21-
required: false
22-
default: ''
10+
description: 'GitHub token with administration:write on the target repo (typically a GitHub App installation token from checkout-as-app or github-app-auth).'
11+
required: true
2312

2413
owner:
2514
description: 'Target repo owner. Defaults to the current repo owner.'
@@ -54,16 +43,6 @@ outputs:
5443
runs:
5544
using: 'composite'
5645
steps:
57-
- name: Authenticate as GitHub App
58-
id: app-token
59-
if: ${{ inputs.token == '' }}
60-
uses: nsheaps/github-actions/.github/actions/github-app-auth@603052841cd49b9fdc99bc32979ff9c45c9b669e # 2026-05-22
61-
with:
62-
app-id: ${{ inputs.app-id }}
63-
private-key: ${{ inputs.private-key }}
64-
owner: ${{ inputs.owner }}
65-
skip-checkout: 'true'
66-
6746
- name: Ensure yq is available
6847
shell: bash
6948
run: |
@@ -78,8 +57,7 @@ runs:
7857
id: apply
7958
shell: bash
8059
env:
81-
GH_TOKEN: ${{ inputs.token || steps.app-token.outputs.token }}
82-
APP_ID: ${{ inputs.app-id }}
60+
GH_TOKEN: ${{ inputs.token }}
8361
OWNER: ${{ inputs.owner }}
8462
REPO: ${{ inputs.repo }}
8563
SETTINGS_FILE: ${{ inputs.settings-file }}

0 commit comments

Comments
 (0)