Skip to content

feat: optionally create missing .github / .github-private repos before sync#71

Merged
joshjohanning merged 3 commits into
mainfrom
joshjohanning/auto-create-dot-github-repos
May 20, 2026
Merged

feat: optionally create missing .github / .github-private repos before sync#71
joshjohanning merged 3 commits into
mainfrom
joshjohanning/auto-create-dot-github-repos

Conversation

@joshjohanning
Copy link
Copy Markdown
Owner

Closes #60

Adds an explicit opt-in path to bootstrap missing .github / .github-private repositories before syncing files, instead of silently skipping with a warning. Defaults preserve today's non-destructive behavior.

New action inputs

Input Default Notes
create-missing-dot-github-repos false Umbrella opt-in. Only applies to repos with a configured source-dir.
dot-github-repo-visibility public Allowed: public, private, internal.
dot-github-private-repo-visibility private Same enum.

All three are also settable per-org in orgs.yml, with the same enum validation.

Behavior

  • 404 vs 403 split. Auto-create only fires on a true 404 from the repo GET. 403 keeps today's permission-warning path untouched (isPermissionLikeFetchError is unchanged; the split happens at the call site in syncDotGithubRepo).
  • Create call. POST /orgs/{org}/repos with auto_init: true so the immediate GET /git/ref/heads/{default_branch} doesn't 409 on an empty repo. After creation, the existing sync flow runs against the new repo's default_branch.
  • EMU / restricted-GHEC. A 422 from create with visibility: public is caught and surfaced as a friendly, actionable warning pointing the user at dot-github-repo-visibility: internal. No silent retry.
  • Dry-run. Logs Would create repo {org}/{repo} (visibility: {v}), records a dot-github-create "would" sub-result, and skips the rest of the sync for that repo (you can't sync against a nonexistent repo).
  • New sub-result kinds. dot-github-create and dot-github-private-create are distinct from the existing *-sync kinds, so bootstrap is obvious in the job summary.

Permissions

Creating repos requires administration: write at the org level for the GitHub App, in addition to the existing contents: write. Documented in the README.

Testing

npm run all clean: prettier, eslint, 401/401 jest tests pass, ncc bundle built.

11 new tests added covering:

  • Opt-out (default): 404 still produces existing warning; no create call.
  • Opt-in + 404: create call invoked with the right payload (POST /orgs/{org}/repos, auto_init: true, chosen visibility); sync flow proceeds; dot-github-create sub-result recorded.
  • Opt-in + 403: existing warning path; no create call.
  • EMU 422 from create with public: friendly error mentioning dot-github-repo-visibility: internal; failed sub-result.
  • Dry-run + opt-in + 404: Would create… sub-result; no API write; sync skipped.
  • .github-private path: uses dot-github-private-create kind.
  • Invalid visibility (secret): rejected at call boundary.
  • Per-org overrides from orgs.yml: visibility, create-missing-dot-github-repos propagation, invalid enum, non-boolean rejection.

Files changed

  • action.yml — 3 new inputs
  • src/index.js — input parsing, per-org config, sub-result labels, syncDotGithubRepo create flow
  • README.md — new section + administration: write callout + inputs table
  • __tests__/index.test.js — 11 new tests
  • package.json1.10.11.11.0

…e sync

Adds three new opt-in inputs (and matching per-org overrides in orgs.yml):

- create-missing-dot-github-repos (bool, default false)
- dot-github-repo-visibility (default 'public')
- dot-github-private-repo-visibility (default 'private')

When opted in, syncDotGithubRepo distinguishes a true 404 from 403 at the
repo GET, creates the missing repo via POST /orgs/{org}/repos with
auto_init: true at the chosen visibility, then continues the normal
sync flow. New 'dot-github-create' / 'dot-github-private-create'
sub-result kinds make bootstrap visible in the job summary.

Specific 422 from POST repos with public visibility (EMU / restricted
GHEC) is caught and surfaced with an actionable message pointing at
the 'internal' visibility override. Dry-run logs 'Would create repo ...'
and skips the rest of the sync for that repo.

Adds README docs (incl. administration:write requirement) and 11 new
unit tests covering opt-in / opt-out / 403 / 422 / dry-run /
per-org visibility override / invalid enum.

Fixes #60

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 19, 2026 20:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an explicit opt-in flow to bootstrap missing special org repositories (.github / .github-private) before attempting the existing file-sync PR workflow, keeping the default behavior non-destructive (still warns + skips on missing repos unless opted in).

Changes:

  • Adds new action/org-config inputs to enable repo creation on true 404 and to control visibility for newly created .github / .github-private repos.
  • Extends the .github sync flow to optionally create the repo (with auto_init: true) and records new *-create sub-result kinds for job summaries.
  • Updates README documentation and adds Jest coverage for the new behaviors (opt-in/out, 403 vs 404, dry-run, visibility validation, and EMU-style 422 handling).
Show a summary per file
File Description
src/index.js Implements new inputs/config plumbing, visibility validation, new summary kinds, and the create-on-404 flow in .github sync.
action.yml Adds the three new action inputs with defaults and descriptions.
README.md Documents the new opt-in behavior, permissions requirement, and new inputs in the inputs table.
__tests__/index.test.js Adds tests covering repo creation behavior, dry-run, error splits, and per-org overrides/validation.
package.json Bumps version to 1.11.0 for the new feature.
package-lock.json Updates lockfile version field to match the package version bump.
badges/coverage.svg Updates the generated coverage badge.

Copilot's findings

  • Files reviewed: 5/7 changed files
  • Comments generated: 4

Comment thread src/index.js
Comment thread src/index.js Outdated
Comment thread action.yml Outdated
Comment thread README.md Outdated
Normalize empty visibility values to undefined, use the correct visibility input name in the 422 guidance for .github-private, and standardize administration permission formatting in docs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 5/7 changed files
  • Comments generated: 2

Comment thread src/index.js
Comment thread README.md Outdated
Fall back to repo-specific defaults after visibility normalization so empty options never produce undefined API payloads or log messages. Clarify README guidance for repo-specific 422 visibility warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@joshjohanning joshjohanning merged commit 6d24e92 into main May 20, 2026
4 checks passed
@joshjohanning joshjohanning deleted the joshjohanning/auto-create-dot-github-repos branch May 20, 2026 14:59
@github-actions
Copy link
Copy Markdown

📦 Draft Release Created

A draft release v1.11.0 has been created for this PR.

🔗 View Draft Release

Next Steps

  • Review the release notes
  • Publish the release to make it permanent

This is an automated reminder from the publish-github-action workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: optionally create missing .github/.github-private repos during sync

2 participants