You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 01891ec
Browse filesBrowse the repository at this point in the historyBrowse files
authored
chore: tighten agent environment and test suite (#65)
- stub sleep in bats tests (suite ~44s -> ~14s)
- add tests/test_repo_structure.bats enforcing the new-script checklist
- add preToolUse hook blocking heredoc file writes (with bats tests)
- move per-script behaviors to docs/script-behaviors.md; slim AGENTS.md
- prune instruction files irrelevant to a bash-only repo
- document mkdir-before-create step for new scripts
Co-authored-by: Patrick Lewis <plewis@ontinue.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+4-78Lines changed: 4 additions & 78 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -145,87 +145,13 @@ Scripts follow this validation sequence:
145
145
146
146
## Script-Specific Behaviors
147
147
148
-
### `github-add-enterprise-team-read-permissions`
149
-
150
-
Uses GraphQL cursor-based pagination to enumerate all enterprise orgs, then assigns the `all_repo_read` org role (configurable via `ALL_REPO_READ_ROLE_NAME`) to the enterprise team in each org. Requires Bearer token authentication with `admin:enterprise` scope. The `ENTERPRISE_TEAM_SLUG` is the slug without the `"ent:"` prefix.
151
-
152
-
### `github-add-repo-collaborators-by-pattern`
153
-
154
-
Adds individual collaborators to org repos whose names match `REPO_NAME_REGEX` (ERE). Accepts a comma-separated `COLLABORATORS` list and an optional `REPO_EXCLUDE_REGEX` to skip matching repos. Uses `token` auth for all REST calls. Iterates all org repos paginated at 100 per page.
155
-
156
-
### `github-add-repo-permissions`
157
-
158
-
Grants team permissions across all repos in an org. Reads five space-separated team-slug lists (`REPO_ADMIN`, `REPO_MAINTAIN`, `REPO_PUSH`, `REPO_TRIAGE`, `REPO_PULL`). Optionally filters repos by name prefix via `REPO_NAME_FILTER`. Sleeps 5 s between each repo to stay within rate limits. Uses legacy `Accept: application/vnd.github.v3+json` and `token` auth.
159
-
160
-
### `github-archive-old-repos`
161
-
162
-
Calculates a cutoff date based on `YEARS_THRESHOLD` (default 5). Generates a timestamped CSV report under `reports/`, shows the top 10 oldest repos, and prompts for confirmation before archiving. Handles both BSD (`date -v`, macOS) and GNU (`date -d`, Linux) date syntax for cross-platform compatibility.
163
-
164
-
### `github-auto-repo-creation`
165
-
166
-
Creates private repos from a comma-separated `REPO_NAMES` list. Configures branch protection on the default branch, creates a CODEOWNERS file (Base64-encoded via API), and grants admin access to comma-separated `ADMIN_TEAMS`. All slug values in `REPO_NAMES`, `ADMIN_TEAMS`, and `REPO_OWNERS` are validated before use. Requires `base64` in addition to `curl` and `jq`.
167
-
168
-
### `github-close-archived-repo-security-alerts`
169
-
170
-
Dismisses open Dependabot, code-scanning, and secret-scanning alerts on all archived repos. Supports `--type` to target a single alert type and `--dry-run` to preview without changes. Generates a timestamped CSV report under `reports/`. Requires a token with `security_events` and `repo` scopes.
171
-
172
-
### `github-dockerfile-discovery`
173
-
174
-
Uses GitHub code-search API to find Dockerfiles across all enterprise orgs, then fetches and parses each file to extract `FROM` instructions (including multi-stage builds). Produces three timestamped reports in `REPORT_DIR`: a detail CSV, a summary CSV, and a plain-text summary. Supports `ORGS` override, `ORG_FILTER`/`ORG_EXCLUDE` regex filters (validated as syntactically correct ERE before use), and configurable sleep intervals (`SEARCH_SLEEP`, `CONTENT_SLEEP`). Both `gh_api` call sites handle sentinels: `__422__` or `__404__` on the code-search endpoint skips that org with a warning; `__404__` or `__422__` on the file-contents endpoint skips that individual file.
175
-
176
-
### `github-enable-issues`
177
-
178
-
Iterates all non-archived repos in an org and enables the Issues feature on any repo where it is disabled. Supports `--dry-run` to list affected repos without making changes.
179
-
180
-
### `github-get-consumed-licenses`
181
-
182
-
Calls the enterprise consumed-licenses endpoint using Bearer authentication. Requires `read:enterprise` scope. Returns seat consumption and purchase counts. Token-only script; no pagination or retry logic beyond what the single API call provides.
183
-
184
-
### `github-get-public-repos`
185
-
186
-
Discovers all enterprise orgs (three-tier fallback via `get_enterprise_orgs`), fetches all repos in each, and filters to public visibility in `jq` (does not rely on `?type=public` query param, which is unreliable for enterprise-managed orgs). Writes a timestamped CSV to `REPORT_DIR`. Supports `ORGS` override and `ORG_FILTER`/`ORG_EXCLUDE` ERE regex filters.
187
-
188
-
### `github-get-repo-list`
189
-
190
-
Outputs a CSV row per repository (full name, owner, visibility, URL, description, fork flag, pushed/created/updated timestamps) to stdout. Pagination handled at 100 repos per page via `get_repo_page_count`.
191
-
192
-
### `github-import-repo`
193
-
194
-
Performs a full bare clone (`git clone --mirror`) of a source repo and pushes all branches, tags, and history to a new private destination repo. Validates `GIT_URL_PREFIX` against a GitHub-host allowlist before running any git operations to prevent credential leakage. Repo names and `OWNER_USERNAME` are validated as slugs.
195
-
196
-
### `github-migrate-internal-repos-to-private`
197
-
198
-
Fetches all repos with internal visibility (paginated) and converts each to private via PATCH. Logs success or failure per repo. This operation cannot be undone via the API — converting internal to private removes access from members of other enterprise orgs.
199
-
200
-
### `github-monthly-issues-report`
201
-
202
-
Generates an HTML report of issues created in a date range (`MONTH_START`/`MONTH_END`), filtered by a hardcoded label (`Linked [AC]` — edit the script to change). Uses the timeline API to track who applied labels. URL-encodes labels for API calls (e.g., `Linked [AC]` → `Linked%20[AC]`). Outputs to `output.txt`.
203
-
204
-
### `github-organize-stars`
205
-
206
-
Uses `gh` CLI GraphQL (not `curl`) to fetch all starred repos. Accepts `GITHUB_TOKEN` env var or an active `gh` auth session for authentication. Categorizes by primary language, GitHub topics, and name keywords using a `RULES` array (pipe-delimited: `List Name|LANGUAGES|TOPICS|NAME_KEYWORDS`; first matching rule wins). Caches stars at `~/.cache/gh-star-organizer/stars.json`. Supports `--dry-run`, `-y` (skip confirm), `--show-repos`, and `--no-cache`. Adds repos to Lists in batches of 25.
207
-
208
-
### `github-repo-from-template`
209
-
210
-
Creates a private repo from `TEMPLATE_REPO` (including all branches), assigns admin permissions to space-separated `REPO_ADMIN` teams, write permissions to `REPO_WRITE` teams, then invites `CD_USERNAME` as a collaborator using `CD_GITHUB_TOKEN` and auto-accepts the invitation. All slug values are validated before use.
211
-
212
-
### `github-repo-permissions-report`
213
-
214
-
Uses `curl` for all API calls. Accepts `GITHUB_TOKEN` env var or an active `gh` auth session (token auto-resolved at lib source time) for authentication. Accepts `-r OWNER/REPO`, `-b BRANCH`, and `-o FILE` flags. Outputs a CSV with two record types: `permission` (all users/teams) and `bypass_actor` (explicit PR approval bypass entries). Reports both branch protection rules and repository rulesets.
215
-
216
-
### `github-copilot-report`
217
-
218
-
Uses `curl` for all GitHub API calls. Accepts `GITHUB_TOKEN` env var (PAT with `read:enterprise` and `manage_billing:enterprise` scopes) or an active `gh` auth session (token auto-resolved at lib source time) for authentication. Also requires `az` to be **installed** when Entra ID enrichment is needed — `az` is checked at runtime only if `--no-entra` is not set and `az` is not already skipped. If `az` is not installed or not logged in, Entra lookup is silently skipped. When `az` is logged in, enriches each user with Entra ID department and job title via `az rest`.
219
-
220
-
Auto-detects credits per seat from a promo/standard table keyed on plan type and today's date (promo period Jun 1 – Sep 1, 2026); override with `--credits N` or `$CREDITS_PER_SEAT_OVERRIDE`. Credits are pooled enterprise-wide, not per-user buckets. Code completions are not billed in AI credits.
221
-
222
-
Uses API version `2026-03-10` and the new usage-metrics NDJSON endpoints (signed download links). The legacy `/copilot/metrics` and `/copilot/usage` endpoints were closed Apr 2, 2026.
148
+
Per-script quirks (auth style, pagination, sentinels, reports) live in [`docs/script-behaviors.md`](../docs/script-behaviors.md). Read the matching section before changing an existing script.
1. Create directory`<domain>/github-<action-verb-object>/` with `mkdir -p` in its own bash call, before any `create` call (the `create` tool needs an existing parent)
154
+
2. Create script: `github-<action-verb-object>.sh` (match directory name); add a section to `docs/script-behaviors.md`. `tests/test_repo_structure.bats` fails until every checklist item below exists
229
155
3. Source `lib/github-common.sh` for validation and output helpers
230
156
4. Start with the standard boilerplate (see Script Anatomy above)
231
157
5. Create `action.yml` in the same directory — expose every env var as a named input (required inputs without defaults, optional inputs with sensible defaults); map CLI flags such as `--dry-run` and `--type` to boolean/string inputs and build an `ARGS` array in the `run:` step. Mirror the pattern of any existing `action.yml`.
@@ -305,7 +231,7 @@ When you change one of these files, you must also update the files in the "Also
305
231
|`README.md` — script documentation | Verify the script's `# ===` header comment still matches (env vars, options, requirements) |
306
232
|`.githooks/pre-commit`|`install-hooks.sh` if hook path or installation instructions change; README.md Best Practices section |
| Add a new script |`tests/test_script_validation.bats` (add a test section for the new script); `action.yml` in the same directory; `README.md` (add use case, env var table, usage example, Available Actions table row) |
234
+
| Add a new script |`tests/test_script_validation.bats`; `action.yml` in the same directory; `README.md` (use case, env var table, usage example, Available Actions row); `docs/script-behaviors.md`. `tests/test_repo_structure.bats` enforces the first four|
309
235
| Add a new domain folder |`README.md` top-level structure description; `AGENTS.md` Repository Structure section |
310
236
|`.github/workflows/ci.yml` — shellcheck flags |`.githooks/pre-commit` shellcheck invocation (keep them in sync) |
0 commit comments