diff --git a/.github/workflows/apply.yaml b/.github/workflows/apply.yaml index e1b5be9..22ec489 100644 --- a/.github/workflows/apply.yaml +++ b/.github/workflows/apply.yaml @@ -19,6 +19,10 @@ on: description: "One-time: comma-separated Terraform resource addresses to exclude from this apply (e.g. a resource that's known-broken and blocking every other pending change atomically, while a permanent fix is prepared). Leave empty for a normal apply." required: false default: "" + list_org_fine_grained_permissions: + description: "One-time: set to 'true' to print the org's live custom-role fine-grained permission names to the job summary (e.g. to find the exact permission string for a github_organization_role, since GitHub's docs only show UI labels, not identifiers). Read-only: skips TF Import/TF State Remove/TF Apply for this run. Leave empty for a normal apply." + required: false + default: "" schedule: - cron: "17 */4 * * *" push: @@ -65,6 +69,32 @@ jobs: client-id: Iv23lipEOAvwk5QqNUie private-key: ${{ secrets.CONFIG_APP_SECRET }} owner: ${{ github.repository_owner }} + # Read-only lookup, no Terraform involved -- GitHub's docs only show + # the UI label for custom-org-role permissions (e.g. "Manage + # organization runners and runner groups"), not the identifier string + # a github_organization_role resource actually needs. This queries + # the live API via the same app token Terraform itself uses, instead + # of guessing. Manual, one-time use via workflow_dispatch input; a + # no-op (skipped entirely) for the normal scheduled/push triggers, + # which never set this input. + - name: List org fine-grained permissions (one-time, manual only) + if: inputs.list_org_fine_grained_permissions == 'true' + env: + # Only gh + GITHUB_TOKEN are needed here -- explicitly clear the + # job-level AWS backend credentials rather than let this step + # inherit them unnecessarily. + AWS_ACCESS_KEY_ID: "" + AWS_SECRET_ACCESS_KEY: "" + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + gh api "orgs/${{ github.repository_owner }}/organization-fine-grained-permissions" > /tmp/org-perms.json + { + echo "### All org fine-grained permissions" + jq -r '.[] | "- `\(.name)`: \(.description)"' /tmp/org-perms.json + echo + echo "### Runner-related" + jq -r '.[] | select(.description | test("runner"; "i")) | "- `\(.name)`: \(.description)"' /tmp/org-perms.json + } >> "$GITHUB_STEP_SUMMARY" - name: Setup OpenTofu uses: opentofu/setup-opentofu@v2 with: @@ -83,7 +113,7 @@ jobs: # inputs; a no-op (skipped entirely) for the normal scheduled/push # triggers, which never set these inputs. - name: TF Import (one-time, manual only) - if: inputs.import_address != '' + if: inputs.import_address != '' && inputs.list_org_fine_grained_permissions != 'true' run: | tofu import "${{ inputs.import_address }}" "${{ inputs.import_id }}" env: @@ -97,7 +127,7 @@ jobs: # no-op (skipped entirely) for the normal scheduled/push triggers, # which never set this input. - name: TF State Remove (one-time, manual only) - if: inputs.state_rm_addresses != '' + if: inputs.state_rm_addresses != '' && inputs.list_org_fine_grained_permissions != 'true' run: | if [[ "${STATE_RM_ADDRESSES}" == *$'\n'* ]]; then echo "::error::state_rm_addresses must be comma-separated on a single line, not newline-separated." >&2 @@ -142,6 +172,7 @@ jobs: # *not* downstream of the broken one, not literally everything else. - name: TF Apply id: tofu_apply + if: inputs.list_org_fine_grained_permissions != 'true' run: | EXCLUDE_ARGS=() if [[ -n "${EXCLUDE_ADDRESSES}" ]]; then