βββββ βββββββββ ββββββ ββββββ
βββββ βββββββββββ ββββββββ ββββββββ
βββββββ ββββββββ ββββ βββ ββββββ ββββββ ββββ βββ ββββ βββ
ββββββββ βββββββββ βββββββββββ ββββββββ ββββββββ βββββββ βββββββ
ββββ ββββ ββββ ββββ βββββββββββββββ βββ βββββββ βββββββ βββββββ
ββββ ββββ ββββ ββββ βββ ββββββββ βββ ββββββββ ββββ ββββ
βββββββββ ββββ ββββββββββββββββ ββββββββ ββββββββββ βββββ βββββ
ββββββββββββ βββββ βββββββββ ββββββ ββββββββ βββββ βββββ
βββ ββββ
ββββββββ
ββββββ
Interactive CLI wizard for creating and configuring GitHub repositories. One binary, zero runtime dependencies.
- πͺ Interactive wizard β Create GitHub repos with a conversational guided flow
- β‘ Zero dependencies β Single binary, no runtime requirements
- π Encrypted vault β Tokens stored locally with XSalsa20-Poly1305, never in env vars or plain text
- π Idempotent apply mode β Configure existing repos without recreation
- π₯ Team access control β Assign repositories to organization teams with custom permissions (read, triage, write, admin)
- π·οΈ Enforced labels β 7 standard labels synced on every run (non-standard labels are removed)
- π‘οΈ Branch protection β Enforce reviews, status checks (auto-derived from CI workflows), and workflow validation
- π° Sponsor button β Enable GitHub Sponsors on new or existing repositories
- π₯ Doctor β Validate that required status checks can be satisfied
- π Language templates β Rust (v1), Python/Node.js/Java coming soon
- π Boilerplate files β README, Cargo.toml, CI/CD workflows, LICENSE
- π Template secrets β Automatically configures required GitHub Actions secrets per template
- β¬οΈ Self-update β Replaces the running binary on startup; skips binaries installed with
cargo install(usecargo install --forceinstead)
Linux / macOS:
curl -fsSL https://raw.githubusercontent.com/UniverLab/ghscaff/main/scripts/install.sh | shWindows (PowerShell):
irm https://raw.githubusercontent.com/UniverLab/ghscaff/main/scripts/install.ps1 | iexThis downloads and installs ghscaff. No Rust toolchain required.
You can customize the install:
# Pin a specific version
VERSION=0.1.0 curl -fsSL https://raw.githubusercontent.com/UniverLab/ghscaff/main/scripts/install.sh | sh
# Install to a custom directory
INSTALL_DIR=/usr/local/bin curl -fsSL https://raw.githubusercontent.com/UniverLab/ghscaff/main/scripts/install.sh | shcargo install ghscaffAvailable on crates.io.
git clone https://github.com/UniverLab/ghscaff.git
cd ghscaff
cargo build --release
# Binary at target/release/ghscaffCheck the Releases page for precompiled binaries (Linux x86_64, macOS x86_64/ARM64, Windows x86_64).
Ghscaff checks for new releases when it starts. If a newer version is available, it prompts you to update. Choose "yes" to replace the running binary with the latest version.
If you installed ghscaff with cargo install, the auto-updater will refuse to touch the binary and instead direct you to run cargo install --force ghscaff.
You can disable update checks with:
GHSCAFF_NO_UPDATE_CHECK=1 ghscaffrm -f ~/.local/bin/ghscaff # ghscaff binary
rm -rf ~/.ghscaff/ # boilerplate cache + encrypted vault# Interactive wizard β create a new repo
# (token is requested on first run and stored in the encrypted vault)
ghscaff
# Or directly with a subcommand
ghscaff new
# Configure an existing repo
ghscaff apply owner/repo
# Enable GitHub Sponsor button on an existing repo
ghscaff --sponsor owner/repo
# Validate status checks on a repo
ghscaff doctor owner/repo
# Preview changes without API calls
ghscaff --dry-run
# Reconfigure credentials
ghscaff configFull documentation lives in docs/: installation, quick start,
authentication and the encrypted vault, the wizard, apply mode, templates
& conventions, and the complete CLI reference.
ghscaff resolves the GitHub token in this order:
GITHUB_TOKENenv var β for CI/CD and backward compatibility- Encrypted vault (
~/.ghscaff/vault.enc) β for secure local usage - Interactive prompt β on first run, asks for the token and saves it to the vault
Tokens are encrypted with XSalsa20-Poly1305 and a key derived from:
| Factor | Purpose |
|---|---|
| Username | Only your OS user can decrypt |
| Hostname | Copying the vault to another machine won't work |
| Binary path | Other programs can't derive the same key |
| Passphrase (optional) | Extra protection if desired |
The vault file (~/.ghscaff/vault.enc) has 0600 permissions and the directory has 0700. Writes are atomic (temp file + rename) to prevent corruption.
ghscaff configThis wipes the vault (with confirmation) and starts fresh β new token, optional passphrase. Template secrets will be requested on the next run.
repoβ Repository accessworkflowβ GitHub Actions accessread:orgβ (Optional) Organization and team access
Note on team access: If your token lacks the read:org scope, the wizard will skip the team selection step with a warning, but the rest of the repository setup will continue normally.
The wizard guides you through 7 interactive steps:
- Repository basics β Name, description, topics
- Visibility & ownership β Public/Private, personal or org
- Team access (org only) β Select teams and assign permissions (pull, triage, push, admin)
- Language / template β Choose boilerplate (Rust, Python, etc.)
- Branches β Default branch, develop branch
- Features β LICENSE, standard labels
- Review & confirm β Verify all settings before creation
Then automatically:
- Creates the repository
- Commits all boilerplate files in a single atomic commit (
chore: init repository) - Applies branch protection to main (and develop if created), with required status checks automatically derived from the CI workflow
- Adds selected teams with their assigned permissions
- Enforces standard labels (creates missing, updates changed, removes non-standard)
- Configures required GitHub Actions secrets (from vault, env, or interactive prompt)
- Offers to enable the GitHub Sponsor button
Idempotently configure an existing repository:
ghscaff apply owner/repo
# Auto-detects from git remote if omitted
cd my-existing-project
ghscaff applyApplies:
- β Atomic single commit with all boilerplate files (no individual file commits)
- β Labels enforced (creates missing, updates changed, removes non-standard)
- β
Branch protection on
mainanddevelop(if created) - β Topics (merges with existing)
- β GitHub Actions secrets (from vault, env, or interactive prompt)
- β CI/CD workflows (included in boilerplate)
- β
developbranch (creates if absent)
Safe to run multiple times β idempotent operations only.
Preview changes without making any API calls:
ghscaff --dry-run
# Or with apply mode
ghscaff apply owner/repo --dry-runEach language template includes:
- Dependency manifest β Cargo.toml, package.json, etc.
- Entry point β src/main.rs boilerplate
- README.md β Template with placeholders for name and description
- .gitignore β Language-specific (fetched from GitHub API)
- .github/workflows/ci.yml β CI/CD workflow with basic checks
- .github/workflows/release.yml β Release workflow (published on Git tags)
- LICENSE β Placeholder (user selects license type during wizard)
All files are merged into a single atomic chore: init repository commit.
7 labels are enforced on every repo. Non-standard labels are removed.
| Label | Color | Description |
|---|---|---|
bug |
#d73a4a |
Something isn't working |
feature |
#a2eeef |
New feature or request |
documentation |
#0075ca |
Improvements to docs |
breaking-change |
#e4e669 |
Introduces breaking changes |
target:main |
#1d76db |
Targets the main branch |
target:develop |
#0e8a16 |
Targets the develop branch |
help wanted |
#008672 |
Extra attention needed |
When enabled, applies to the default branch:
- β Require 1 approval before merging
- β Require status checks to pass β automatically derived from the CI workflow ghscaff commits
- β Dismiss stale reviews
- β Disallow force-push
Branch protection normally requires you to type the exact names of CI checks that must pass, and those names must match your workflow job names exactly. A typo creates a protection rule that silently guards nothing.
Ghscaff reads the CI workflow it just wrote and derives the required check names from it. If you later rename a job in the workflow, the protection rule automatically refers to the new name on your next ghscaff apply.
To verify that your required checks can actually be satisfied, run:
ghscaff doctor owner/repoTemplates can declare required secrets in secrets.toml. ghscaff resolves them in order:
- Encrypted vault β previously saved secrets
- Environment variable β e.g.
CARGO_REGISTRY_TOKEN - Interactive prompt β with option to save to vault for future use
For the Rust template:
CARGO_REGISTRY_TOKENβ Required for publishing to crates.io (get one here)
MIT β see LICENSE for details.
An experiment of UniverLab β an open computational laboratory. Made with β€οΈ by JheisonMB
