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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and Base versions are tracked in the repo-root `VERSION` file.

## [Unreleased]

### Changed

- Expanded `basectl repo init` to seed portable project Git workflow guidance
and a standard pull request template for Base-managed repositories.

## [0.3.0] - 2026-06-06

### Added
Expand Down
67 changes: 65 additions & 2 deletions cli/bash/commands/basectl/subcommands/repo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ BASE_REPO_BASELINE_FILES=(
VERSION
CHANGELOG.md
CONTRIBUTING.md
.github/pull_request_template.md
LICENSE
.gitignore
base_manifest.yaml
Expand Down Expand Up @@ -337,8 +338,34 @@ Thank you for improving this project.
1. Create or choose a GitHub issue before starting implementation work.
2. Use one of the standard issue labels: \`bug\`, \`enhancement\`,
\`documentation\`, \`ci\`, or \`security\`.
3. Use a focused branch and pull request for each issue.
4. Run the project checks before opening or updating a pull request.
3. Create an issue-backed branch:

\`\`\`text
<category>/<issue>-<YYYYMMDD>-<slug>
\`\`\`

4. Use a dedicated Git worktree for each pull request so the main checkout can
stay on the default branch:

\`\`\`bash
git fetch origin
git worktree add -b <branch> ../$name-worktrees/<slug> origin/<default-branch>
\`\`\`

5. Keep the pull request scoped to the issue and link it with
\`Fixes #<issue>\` or \`Closes #<issue>\` when merge should close the issue.
6. Run the project checks before opening or updating a pull request.
7. Update \`CHANGELOG.md\` only for notable user-visible or release-worthy
changes.
8. After merge, sync the default branch, remove the worktree, and delete merged
local and remote branches when safe:

\`\`\`bash
git pull --ff-only origin <default-branch>
git worktree remove ../$name-worktrees/<slug>
git branch -d <branch>
git push origin --delete <branch>
\`\`\`

Useful commands:

Expand All @@ -350,6 +377,39 @@ basectl test $name
EOF
}

base_repo_write_pull_request_template() {
local dry_run="$1"
local root="$2"

base_repo_write_stream "$dry_run" "$root/.github/pull_request_template.md" <<'EOF'
## Summary

<!-- What changed and why. Focus on decisions and user impact, not just the diff. -->

## Issue

Closes #

## Validation

<!-- Commands run and relevant output. Include narrow checks and any broader suite used. -->

## Notes

<!-- Optional: tradeoffs, follow-up work, or reviewer context. -->

## Checklist

- [ ] Branch name follows `<category>/<issue>-<YYYYMMDD>-<slug>`.
- [ ] Pull request is scoped to one issue, unless a documented multi-issue exception applies.
- [ ] Pull request body explains what changed and how it was validated.
- [ ] Relevant project checks pass.
- [ ] Documentation is updated when behavior or user-facing commands change.
- [ ] CHANGELOG is updated for notable user-visible or release-worthy changes.
- [ ] Pull request includes `Fixes #<issue>` or `Closes #<issue>` when merge should close the issue.
EOF
}

base_repo_write_license() {
local copyright_holder="$2"
local dry_run="$1"
Expand Down Expand Up @@ -426,8 +486,10 @@ required_files=(
VERSION
CHANGELOG.md
CONTRIBUTING.md
.github/pull_request_template.md
LICENSE
base_manifest.yaml
.github/workflows/tests.yml
)

for file in "${required_files[@]}"; do
Expand Down Expand Up @@ -478,6 +540,7 @@ base_repo_write_baseline() {
base_repo_write_version "$dry_run" "$root" || status=1
base_repo_write_changelog "$dry_run" "$name" "$root" || status=1
base_repo_write_contributing "$dry_run" "$name" "$root" || status=1
base_repo_write_pull_request_template "$dry_run" "$root" || status=1
base_repo_write_license "$dry_run" "$copyright_holder" "$root" || status=1
base_repo_write_gitignore "$dry_run" "$root" || status=1
base_repo_write_manifest "$dry_run" "$name" "$root" || status=1
Expand Down
12 changes: 12 additions & 0 deletions cli/bash/commands/basectl/tests/repo.bats
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ load ./basectl_helpers.bash

[ "$status" -eq 0 ]
[[ "$output" == *"[DRY-RUN] Would create '$repo_dir/README.md'."* ]]
[[ "$output" == *"[DRY-RUN] Would create '$repo_dir/.github/pull_request_template.md'."* ]]
[[ "$output" == *"[DRY-RUN] Would create executable '$repo_dir/tests/validate.sh'."* ]]
[[ "$output" == *"[DRY-RUN] Would create private GitHub repository 'codeforester/base-demo' if it does not already exist."* ]]
[[ "$output" == *"gh repo edit codeforester/base-demo"* ]]
Expand Down Expand Up @@ -76,6 +77,7 @@ load ./basectl_helpers.bash
[ -f "$repo_dir/VERSION" ]
[ -f "$repo_dir/CHANGELOG.md" ]
[ -f "$repo_dir/CONTRIBUTING.md" ]
[ -f "$repo_dir/.github/pull_request_template.md" ]
[ -f "$repo_dir/LICENSE" ]
[ -f "$repo_dir/.gitignore" ]
[ -f "$repo_dir/base_manifest.yaml" ]
Expand All @@ -84,6 +86,16 @@ load ./basectl_helpers.bash
grep -Fqx "0.1.0" "$repo_dir/VERSION"
grep -Fq "name: base-demo" "$repo_dir/base_manifest.yaml"
grep -Fq "command: ./tests/validate.sh" "$repo_dir/base_manifest.yaml"
grep -Fq "<category>/<issue>-<YYYYMMDD>-<slug>" "$repo_dir/CONTRIBUTING.md"
grep -Fq "git worktree add -b <branch> ../base-demo-worktrees/<slug> origin/<default-branch>" "$repo_dir/CONTRIBUTING.md"
grep -Fq 'Update `CHANGELOG.md` only for notable user-visible or release-worthy' "$repo_dir/CONTRIBUTING.md"
grep -Fq "## Checklist" "$repo_dir/.github/pull_request_template.md"
grep -Fq "CHANGELOG is updated for notable user-visible or release-worthy changes." "$repo_dir/.github/pull_request_template.md"
! grep -Fq "Demo Impact" "$repo_dir/.github/pull_request_template.md"

run bash -c 'cd "$1" && ./tests/validate.sh' _ "$repo_dir"
[ "$status" -eq 0 ]
[[ "$output" == *"Repository baseline is present."* ]]
}

@test "basectl repo init defaults copyright holder to git user name" {
Expand Down
30 changes: 27 additions & 3 deletions docs/repo-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ being skipped.
- `VERSION`
- `CHANGELOG.md`
- `CONTRIBUTING.md`
- `.github/pull_request_template.md`
- `LICENSE`
- `.gitignore`
- `base_manifest.yaml`
Expand All @@ -84,6 +85,28 @@ The generated validation script checks for the required baseline files. It is
not a replacement for project tests; it is the seed contract that lets
`basectl test <project>` work immediately.

## Git Workflow

The generated `CONTRIBUTING.md` and pull request template seed a portable
Base-managed project workflow:

- create or choose a GitHub issue before implementation work
- use one standard category label: `bug`, `enhancement`, `documentation`, `ci`,
or `security`
- branch from the issue with `<category>/<issue>-<YYYYMMDD>-<slug>`
- use a dedicated Git worktree for each pull request
- keep each pull request scoped to the issue and link it with `Fixes #<issue>`
or `Closes #<issue>` when the merge should close the issue
- run project checks before opening or updating the pull request
- update `CHANGELOG.md` only for notable user-visible or release-worthy changes
- after merge, sync the default branch, remove the worktree, and delete merged
local and remote branches when safe

The generated pull request template keeps the project baseline intentionally
portable: `Summary`, `Issue`, `Validation`, `Notes`, and a short checklist.
Base-specific sections such as `Demo Impact` belong only in projects that
choose that policy.

## GitHub Configuration

`repo init` creates the GitHub repository when needed, using private visibility
Expand Down Expand Up @@ -120,6 +143,7 @@ Dry-run mode does not require authentication because it only prints the planned
## Boundaries

The MVP does not configure branch protection, manage repository secrets, create
teams, or add CODEOWNERS. Those are separate workflow and policy decisions.
Base can grow those capabilities once the baseline command has proven useful
for real repos such as the Base demo project.
teams, add CODEOWNERS, or force Base-specific PR sections such as `Demo Impact`.
Those are separate workflow and policy decisions. Base can grow those
capabilities once the baseline command has proven useful for real repos such as
the Base demo project.
Loading