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
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
default: "manual"

permissions:
contents: write
contents: read

concurrency:
group: release-${{ github.ref }}
Expand Down Expand Up @@ -98,6 +98,8 @@ jobs:
runs-on: ubuntu-latest
needs:
- package
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ This is useful for:
- [Usage guide](docs/usage.md)
- [Examples](examples/README.md)
- [Contributing](CONTRIBUTING.md)
- [Permission posture](docs/permissions.md)
- [Testing](docs/testing.md)
- [CI/CD](docs/ci.md)
- [Release process](docs/release.md)
Expand Down
4 changes: 4 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ The tag version is embedded in the CLI through:
prmaven version
```

The workflow defaults to `contents: read`. Only the release publishing job receives `contents: write`.

Repository permission posture is documented in [permissions.md](permissions.md).

## Local Parity

Before opening a PR, contributors should run:
Expand Down
68 changes: 68 additions & 0 deletions docs/permissions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Permission Posture

This document records the intended repository permission model for PR Maven CLI.

## Current Stabilization Mode

The repository is public during the initial stabilization phase.

This keeps GitHub branch protection available without requiring a paid plan.

Do not switch it to private if that would disable branch protection or repository rules. A private stabilization phase should only be used when the account or organization plan supports the same branch protection controls used in public OSS mode.

Current maintainer policy:

- William Thomaz, GitHub: `@Will-thom`, is the founder and principal maintainer.
- No external collaborator should receive write, maintain, or admin access during stabilization unless intentionally promoted.
- External contributors can open issues and pull requests, but merge rights should stay limited to maintainers.

## Public OSS Mode

The public repository must keep `main` protected before accepting outside contributions.

Required public-mode controls:

- Require the `All CI checks` status before merge.
- Enforce the rule for administrators.
- Require conversation resolution before merge.
- Disable force pushes.
- Disable branch deletion.
- Keep merge rights limited to users with write, maintain, or admin access.
- Keep `@Will-thom` as the repository-wide code owner through `.github/CODEOWNERS`.

## GitHub Actions Permissions

Repository-level workflow token default:

- `contents: read`.
- Workflows cannot approve pull request reviews.

Workflow-specific policy:

- `CI` uses `contents: read`.
- `Security` uses `contents: read`, `security-events: write`, and `pull-requests: read`.
- `Release` defaults to `contents: read`; only the release publishing job receives `contents: write`.
- `Thank Contributor` uses `pull_request_target` only to read the base repository template and write a comment. It must not check out or execute contributor code.

## Secrets And External Integrations

The project should avoid repository secrets for the Stage 1 local-first MVP.

Expected empty surfaces during stabilization:

- GitHub Actions secrets.
- GitHub Actions variables.
- Webhooks.
- Environments.
- Deployments.
- GitHub Pages.

## OSS Contributor Readiness

Before actively inviting OSS contributors:

1. Validate branch protection for `main`.
2. Confirm `All CI checks` is the required status gate.
3. Confirm `CODEOWNERS` still routes ownership to `@Will-thom`.
4. Confirm no unintended collaborators, secrets, variables, webhooks, environments, deployments, releases, or pages were added.
5. Re-run CI and Security on `main`.
4 changes: 4 additions & 0 deletions docs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ func TestDocumentationCoversInstallationUsageAndExamples(t *testing.T) {
files := map[string]string{
"README.md": mustReadFile(t, "README.md"),
"docs/installation.md": mustReadFile(t, "docs/installation.md"),
"docs/permissions.md": mustReadFile(t, "docs/permissions.md"),
"docs/usage.md": mustReadFile(t, "docs/usage.md"),
"examples/README.md": mustReadFile(t, "examples/README.md"),
"examples/library/main.go": mustReadFile(t, "examples/library/main.go"),
Expand All @@ -18,7 +19,10 @@ func TestDocumentationCoversInstallationUsageAndExamples(t *testing.T) {
assertContains(t, files["README.md"], "[Installation](docs/installation.md)")
assertContains(t, files["README.md"], "[Usage guide](docs/usage.md)")
assertContains(t, files["README.md"], "[Examples](examples/README.md)")
assertContains(t, files["README.md"], "[Permission posture](docs/permissions.md)")
assertContains(t, files["docs/installation.md"], "go install ./cmd/prmaven")
assertContains(t, files["docs/permissions.md"], "Do not switch it to private if that would disable branch protection or repository rules.")
assertContains(t, files["docs/permissions.md"], "All CI checks")
assertContains(t, files["docs/installation.md"], "prmaven version")
assertContains(t, files["docs/usage.md"], "prmaven fails -project .")
assertContains(t, files["docs/usage.md"], "demo/multi-module-failure")
Expand Down
Loading