Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Repository automation

## Local CI toolchain

`.mise.toml` pins Go to `1.26.0`, the minimum version declared by `go.work` and
all module files. It sets `GOTOOLCHAIN=local` so dependency or tooling changes
cannot silently select a newer Go version. GitHub CI also selects Go from
`go.work`. Keep the mise pin aligned when intentionally changing the minimum.

Run `mise exec -- go version` to confirm the selected toolchain, then `mise ci`
for the full local checks.

## Dependency PR GitHub App

The `Update Submodule Dependencies` workflow updates the Go submodules to reference
main and opens or updates `bot/update-submodule-dependencies`. It authenticates as
**Speakeasy OpenAPI Dependencies** so the resulting PR checks run automatically.
PRs created or updated with `GITHUB_TOKEN` require manual workflow approval.

The App is an authentication identity only. The implementation lives in
[`workflows/update-submodule-dependencies.yaml`](workflows/update-submodule-dependencies.yaml);
there is no separately hosted service, webhook handler, or OAuth login flow.

### Ownership and access

- Owner: `speakeasy-api` organisation. Organisation owners manage the App.
- [App settings](https://github.com/organizations/speakeasy-api/settings/apps/speakeasy-openapi-dependencies)
- [Installation settings](https://github.com/organizations/speakeasy-api/settings/installations/168310303)
- App ID: `5203735`.
- Client ID: `Iv23lix0zkHJ35Cthk16` (public identifier, not a secret).
- Private App, installable only in `speakeasy-api`.
- Installation access: only `speakeasy-api/openapi`.
- Repository permissions: Contents and Pull requests read/write, plus mandatory
Metadata read-only. No organisation permissions, Actions administration, or
permission to modify workflow files.
- Webhooks and user authorisation are disabled.

### Repository configuration

Configure these under the repository's **Settings > Secrets and variables > Actions**:

| Type | Name | Value |
| -------- | --------------------- | ----------------------------------- |
| Variable | `BOT_APP_CLIENT_ID` | `Iv23lix0zkHJ35Cthk16` |
| Secret | `BOT_APP_PRIVATE_KEY` | The App's generated PEM private key |

The workflow generates an installation token only when dependencies change. It
explicitly restricts the token to this repository and requests only Contents and
Pull requests write access. `actions/create-github-app-token` revokes the token at
job completion; installation tokens also expire after one hour. The normal
`GITHUB_TOKEN` has read-only Contents access.

Do not put the private key in Git, documentation, logs, or PR comments. It is stored
as an encrypted repository Actions secret. No local copy is retained after setup.
Do not expose it to workflows that execute untrusted PR code.

### Rotate the private key

1. Generate a new private key under **App settings > General > Private keys**.
2. Replace the `BOT_APP_PRIVATE_KEY` repository Actions secret. For example:
`gh secret set BOT_APP_PRIVATE_KEY --repo speakeasy-api/openapi < /secure/path/new-key.pem`.
3. Confirm the next dependency-update run can generate its token and create or
update a PR whose checks start without approval.
4. Delete the old key from the App settings, then remove the downloaded new key
from local storage. GitHub cannot show the stored Actions secret again; generate
another key if it needs replacing.

### Disable or remove

Suspend or uninstall the App through its installation settings to revoke access.
For permanent removal, also remove `BOT_APP_CLIENT_ID` and `BOT_APP_PRIVATE_KEY`
and update or disable the dependency-update workflow. Reverting to `GITHUB_TOKEN`
restores manual approval for the generated PR workflows.

Fork workflow-approval settings are unchanged. This App does not bypass branch
protection, required checks, review requirements, or merge queues.
17 changes: 14 additions & 3 deletions .github/workflows/update-submodule-dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ on:
- ".github/workflows/update-submodule-dependencies.yaml"

permissions:
contents: write
pull-requests: write
contents: read

jobs:
update-dependencies:
Expand Down Expand Up @@ -89,11 +88,23 @@ jobs:
echo "Updated to version: ${NEW_VERSION}"
fi

- name: Generate automation token
id: app-token
if: steps.changes.outputs.changed == 'true'
uses: actions/create-github-app-token@v3
with:
client-id: ${{ vars.BOT_APP_CLIENT_ID }}
private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: ${{ github.event.repository.name }}
permission-contents: write
permission-pull-requests: write

- name: Create Pull Request
if: steps.changes.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ steps.app-token.outputs.token }}
commit-message: |
chore: update submodule dependencies to latest main

Expand Down
4 changes: 4 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[tools]
go = "1.26.0"
golangci-lint = "2.12.2"
gotestsum = "latest"

[env]
GOTOOLCHAIN = "local"

[tasks.setup-vscode-symlinks]
description = "Create VSCode symlinks for tools not automatically handled by mise-vscode"
run = [
Expand Down
Loading