The goal of repository management is not to click through every Settings page. It is to make “who can change what, how changes are merged, how releases are published, and who to contact when something goes wrong” explainable, auditable, and recoverable.
This article covers repository files and metadata, permissions, issue planning, the default branch, Branch Protection, Rulesets, Required Checks, Releases, archiving, transfers, and security maintenance. GitHub Actions appears only where it concerns “which checks must pass and how to connect them to rules.” Workflow YAML, runners, matrices, caches, and credential injection are left to articles 04–06 in this series.
1. A repository’s two layers: Contracts in code and platform governance#
A GitHub repository has two kinds of state at the same time:
- Contracts within the repository (repository-as-code): README, LICENSE, CHANGELOG, contribution guidelines, issue/PR templates, CODEOWNERS, workflows, and configuration files, all of which can be reviewed, copied, and rolled back through Git history.
- Governance state on the GitHub platform (repository settings): Visibility, roles, the default branch, branch rules, merge buttons, Issues/Projects toggles, Actions permissions, and security features, usually maintained through Settings or the API.
The two should corroborate each other. A README saying “Pull Requests required” does not mean the platform already blocks direct pushes; the existence of a workflow file does not mean its check is a Required Check; and the existence of a LICENSE file does not mean GitHub has recognized the repository’s license metadata.
flowchart LR
A[仓库文件与 Git 历史] --> B[平台元数据]
B --> C[权限与规则]
A --> D[Issue / PR / Release]
C --> E[Required Checks]
D --> E
E --> F[可审计的合并与发布]1.1 Responsibilities of the foundational files
| File or setting | Problem it addresses | Maintenance considerations |
|---|---|---|
README.md |
What the project is and how to install and use it | Give first-time visitors a path they can run; do not cram the entire design history into the README |
README_EN.md or a README in another language |
An entry point for different readers | Keep at least installation, compatibility, and limitations synchronized in both languages; link to the same changelog |
LICENSE |
Legal boundaries for use, modification, and redistribution | Use SPDX names; the license text should match the repository metadata |
CHANGELOG.md |
Human-readable changes in behavior | Record breaking changes, fixes, migrations, and known limitations by version |
CONTRIBUTING.md |
How outside contributors can get started | Clearly describe local checks, branches, PRs, reviews, and the code of conduct |
SECURITY.md |
A private path for reporting vulnerabilities | Specify supported versions, reporting channels, and what must not be disclosed publicly |
CODEOWNERS |
Which paths need review by whom | Rules should cover critical code, workflows, and security configuration; review path changes along with the code |
.github/ISSUE_TEMPLATE/ |
Give issues actionable information | Bug, Feature, Security, and other issue types should request the relevant reproduction steps, goals, and impact |
.github/PULL_REQUEST_TEMPLATE.md |
Include a checklist with each PR | Describe changes, tests, risks, documentation, and related issues |
.github/workflows/ |
Run quality checks automatically | This article is concerned only with whether the checks it provides are stable and connected to merge rules |
README covers “how to use it,” CONTRIBUTING covers “how to change it,” SECURITY covers “how to report risks privately,” and CODEOWNERS covers “who must review it.” Mixing these into one README makes the shortest path hard to find for ordinary users, contributors, and security reporters alike.
1.2 Repository metadata is more than decoration
Maintain at least the following metadata:
- A one-sentence description: Explain what the project is for rather than writing a marketing slogan.
- Topics: Use stable technology, language, and ecosystem names to aid discovery; do not make every version number a Topic.
- License: Choose a license that matches the contents of
LICENSE. - Default branch: Usually
main, but it must align with the documentation, CI triggers, and release process.
For read-only inspection, use the GitHub CLI:
gh repo view OWNER/REPO \
--json nameWithOwner,visibility,defaultBranchRef,isArchived,licenseInfo,urlOfficial documentation: About repositories, About repository topics, and GitHub CLI gh repo view.
1.3 Example: Recording a repository governance snapshot
The following is an anonymized teaching scenario, not a verification of any real repository’s current state. Suppose a public theme project uses main as its default branch, maintains Chinese and English READMEs and a CHANGELOG, uses the BSD 2-Clause license, has published v0.1.0 and v0.2.0, and already contains .github/workflows/nix.yml. Verify these files and version identities separately; do not infer platform settings from the README.
A governance audit should record the following under the same verification date:
- Use
gh repo view OWNER/REPO --json visibility,defaultBranchRef,isArchived,licenseInfoto inspect visibility, the default branch, archive status, and license metadata. - Check that LICENSE, both language versions of the README, CHANGELOG, and release notes are consistent.
- Use
gh release list --repo OWNER/REPOto inspect the release history; “Latest” describes only the platform label at the time of the query. - Look for
CONTRIBUTING.md,SECURITY.md,CODEOWNERS, and issue/PR templates, and identify which contracts exist and which still need to be added. - Use
gh ruleset list --repo OWNER/REPOand the protection API to verify merge rules. A 404 from the protection API may depend on configuration, permissions, or the target path; interpret it alongside other evidence.
An example with “CI present, contribution documentation missing, and no protection rules found” shows only that governance needs work. It is not a promise about the future state, nor does it establish whether contributors are active.
2. Visibility, permissions, and roles#
2.1 Choose the boundary before granting permissions
Repository visibility answers “who can see it,” while roles answer “what they can do once they can see it”:
| Concept | Core meaning | Common misunderstanding |
|---|---|---|
| Public | Anyone can access public content; writing still requires permission | Public does not mean anyone can push |
| Private | Only explicitly authorized users, teams, or organization members can access it | Private forks, Actions logs, and dependency features may be affected by platform rules |
| Internal | For content visible within an organization/enterprise | Personal repositories may not offer this visibility level; it is not a universal middle ground between Public and Private |
| Fork | A derived repository sharing an upstream relationship | Changing visibility or transferring the repository may affect the fork network and permissions |
The GitHub plan, repository owner type, and organization policies affect feature availability. Do not treat the buttons, counts, or free quotas currently shown on a Settings page as permanent rules. When behavior differs, consult the current GitHub plans and repository visibility documentation.
2.2 Least privilege for roles
UI labels may vary slightly between repository types, but for governance, think in terms of these levels:
- Read: View code, issues, PRs, and public metadata; suitable for observers and read-only integrations.
- Triage: Categorize issues and PRs, manage labels and project queues, without directly changing code.
- Write: Push to permitted branches, create PRs, and perform routine collaboration workflows.
- Maintain: Maintain repository configuration and day-to-day administration, generally without every sensitive or destructive administrative privilege.
- Admin: Change repository governance, security, and permissions, and perform high-impact operations; grant it only to actual repository administrators.
For organization repositories, prefer granting access to teams rather than individual users. Use CODEOWNERS to assign review responsibility for critical paths, and schedule an expiry review for temporary collaborators. Do not grant Write merely so someone “can close issues,” and certainly do not use Admin to solve a narrow permissions problem. See Repository roles for an organization.
2.3 Checks before changing visibility
Switching between Public and Private is more than changing a label. First check:
- Whether history contains credentials, personal information, internal links, or build logs that should not be public.
- Whether public forks, clones, caches, and releases will change what is exposed.
- Whether dependent Actions, Packages, Pages, webhooks, and deployment environments support the new visibility.
- Whether collaborators have been informed and an observation window with a rollback option has been arranged.
- Whether secrets need to be migrated, history rewritten, or exposed credentials rotated first.
The CLI can express the intended change, but does not replace a risk assessment:
gh repo edit OWNER/REPO \
--visibility private \
--accept-visibility-change-consequencesRun this only after understanding the consequences and confirming that you have sufficient permissions. Official CLI documentation: gh repo edit.
3. Issues, Labels, Milestones, and Projects#
3.1 An issue is a trackable record of a decision
A good issue includes at least the problem or goal, scope of impact, reproduction/acceptance criteria, relevant versions, and current blockers. Discussion can be open-ended, but should ultimately produce a record that can be closed, referenced, and reviewed later.
Organize labels along a small number of stable dimensions:
| Dimension | Example | Purpose |
|---|---|---|
| Type | bug、enhancement、documentation、security |
Explains what the issue is |
| Status | triage、blocked、needs-info |
Explains where progress is currently blocked |
| Scope | nix、theme、ci、docs |
Identifies the responsible person or component |
| Contribution difficulty | good first issue、help wanted |
Helps new contributors select tasks |
Label names should be composable, but do not create a new label for every combination; “type + scope + status” is usually enough. For security issues, do not put sensitive details into public issues. Use the private channel specified in SECURITY.md.
Issue templates should request useful information without adding form-filling overhead. Bug templates should collect the environment, reproduction steps, expected/actual results, and sanitized logs; Feature templates should collect motivation, alternatives, and acceptance criteria. Problem-report templates must not ask users to paste credentials. The official template guide is About issue and pull request templates.
Common CLI queries and creation commands:
gh issue list --repo OWNER/REPO --state open --label bug
gh issue view 123 --repo OWNER/REPO
gh issue create --repo OWNER/REPO --title "简短标题" --body-file issue.md3.2 Milestones connect issues with release goals
A Milestone expresses a bounded delivery goal, such as v0.3.0, Nix CI hardening, or Documentation refresh:
- State the goal, deadline, or release window, but treat dates as plans rather than assumed commitments.
- Associate the issues and PRs that must be completed with it.
- Use the completion percentage to detect scope growth, not as a substitute for detailed project planning.
- After the release, close or archive the corresponding goal and record where unfinished items went.
GitHub summarizes open/closed issues, PRs, and the completion percentage on the Milestone page. Specific limits and the UI may change; see About milestones.
3.3 Projects provide views across issues and PRs
Projects work well as queues, boards, tables, or roadmaps:
- Issues/PRs are the factual records of work; a Project is a view for organizing and inspecting them.
- Use custom fields for priority, status, assignee, target version, and similar information; keep fields few and stable.
- A work item can appear in multiple views; do not duplicate it into several conflicting issues.
- Regularly close obsolete items so the board does not become “a graveyard of every idea.”
Personal repositories, organization repositories, and different plans may offer different Projects capabilities. Consult About Projects and the current interface.
4. The default branch, protection rules, and Required Checks#
4.1 The default branch is the entry point for collaboration
The default branch determines the default target for new PRs, content displayed on the repository homepage, some Actions trigger behavior, and the default baseline for releases. Before changing it:
- Confirm that the target branch already contains the code and documentation you want to display.
- Check for the old branch name in the README, contribution guidelines, workflows, scripts, and external links.
- Tell collaborators to update their local upstream and PR targets.
- Migrate protection rules, Rulesets, CODEOWNERS-related paths, and release automation.
- Check whether the old branch still has open PRs before deciding whether to delete it.
gh repo view OWNER/REPO --json defaultBranchRef
gh repo edit OWNER/REPO --default-branch mainRun write operations with gh repo edit only after review; for inspection alone, prefer the first read-only command. See Changing the default branch.
4.2 Choosing between Branch Protection and Rulesets
Both protect branches or tags, but their management models differ:
| Mechanism | How to understand its use | Considerations |
|---|---|---|
| Branch protection rule | Applies a set of common protections to matching branches | Straightforward rules suited to simple repositories; verify matching and overlap behavior in the current documentation |
| Ruleset | A named, viewable set of rules with a configurable enforcement state | Can target branches or tags, with several Rulesets active at once; suited to gradual rollout and auditing |
Turning one on does not “completely replace the other.” Applicable rules jointly affect merges and pushes; administrators should avoid duplicated or contradictory rules. A Ruleset can first use a non-enforcing state such as Evaluate to observe matches, then switch to Active. Available states and rules evolve with the product; see About rulesets and Available rules for rulesets.
4.3 An explainable baseline for main
For an actively maintained repository, choose from the following protections according to risk:
- Require Pull Requests and prohibit direct merges without review.
- Require a review from at least one appropriate reviewer; use CODEOWNERS to designate reviewers for critical paths.
- Dismiss stale approvals after new commits so approval does not refer to old code.
- Require conversations to be resolved so blocking review comments reach a conclusion.
- Allow merging only after Required Checks succeed, are skipped, or return neutral; keep check names stable.
- Enable strict checks when branches must be up to date with the base before merging; repositories with infrequent changes can weigh the extra build cost.
- As the project requires, enforce linear history, signed commits, successful deployments, and prohibitions on force pushes and deletion.
- Define clear bypass roles and audit the use of rule bypasses.
More rules do not automatically mean more security. Each rule should answer “what risk does this prevent, who may have an exception, and how do we recover from failure?”
4.4 The actual boundary of Required Checks
A Required Check is a merge gate, not the CI design itself. Before configuring one, confirm:
- The check is guaranteed to run for the target PR types and will not unexpectedly be absent because of path filters, permissions, or event differences.
- The check name is stable and uniquely identifies the intended work; matrix checks especially need to avoid name collisions.
- The check’s source is trusted; if necessary, restrict it to the expected GitHub App or service.
- The meanings of
skipped,neutral, failure, and cancellation align with the project’s risk tolerance; do not mistake “did not run” for “has been tested.” - The choice between strict and loose fits the repository’s scale: strict more closely reflects the latest base at merge time, at the cost of possible repeat builds.
- Branch rules require only existing, stable checks; observe a check for a while before making it Required.
This article does not cover Actions workflow syntax. Treat Actions here as the executor that produces checks; articles 04–06 explain how to design, configure, and secure it. For the official semantics, see About protected branches, including the strict/loose trade-off for Required Status Checks.
If the sample project’s .github/workflows/nix.yml and CHANGELOG indicate that Nix CI already exists, “having a workflow” and “protecting main with Required Checks” are still two different things. Before connecting checks to rules, verify their names, triggers, and failure-recovery paths in real PRs.
For a read-only audit, use:
gh ruleset list --repo OWNER/REPO
gh ruleset check main --repo OWNER/REPO
gh api repos/OWNER/REPO/branches/main/protectionThe last command may return 404 when protection is not configured. Interpret it alongside repository settings, the Rulesets list, and the permissions context; a network error alone is not a configuration finding. See gh ruleset and gh api.
5. Tags, Releases, Archive, and Transfer#
5.1 Tags and Releases are two different layers
- A Git tag points to a commit and is part of a version’s identity. Before publishing, confirm that it points to a reproducible, reviewed commit.
- A GitHub Release is a distribution page built around a tag. It can include change notes, assets, installation tips, and prerelease/draft status.
- CHANGELOG is the repository’s long-term history; release notes are delivery notes for users of a particular version. They can link to each other, but you should not maintain only one of the two.
Recommended release order:
- First merge the code, documentation, and
CHANGELOG, stating compatibility, migration steps, and known limitations. - Create and review the version tag, checking its commit and source archive.
- Create the Release and clearly describe user-visible changes, verification methods, and unsupported cases.
- If there are build assets, record their provenance, verification method, and platform differences; do not mark unverified build artifacts as stable.
- After publishing, verify the installation/upgrade path and link problems back to an issue or the next Milestone.
Example CLI queries:
gh release list --repo OWNER/REPO
gh release view v0.2.0 --repo OWNER/REPOSee About releases, Managing releases, and gh release.
An example release plan might use v0.1.0 for the initial theme and installation path, then add compositor-native blur variants, a Home Manager module, output-contract checks, and Nix CI in v0.2.0. This version schedule only illustrates the different roles of release records. Version numbers on the Release page and in the repository’s CHANGELOG.md should remain mutually verifiable.
5.2 Archive and Transfer are high-impact operations
Archive indicates that a project is no longer actively maintained. Content usually remains as a read-only reference, while issues/PRs and some collaboration entry points are restricted. Before archiving, publish the maintenance status, alternatives, and security-reporting path. Archiving is not deletion and does not replace a backup.
Transfer changes the owner or repository namespace and may affect:
- Clone URLs, remote configuration, and external links;
- Issues, PRs, projects, Actions, Secrets, Webhooks, Packages, and deployments;
- The fork network, team permissions, and CODEOWNERS;
- Licensing, branding, maintenance responsibilities, and security-reporting channels.
Before transferring, list dependents, notify collaborators, and confirm the destination namespace and administrators. Afterward, verify redirects, the default branch, rules, releases, and CI. See Transferring a repository and Archiving a GitHub repository.
6. Repository security baseline and maintenance checklist#
6.1 A minimum security baseline
For a public repository, the minimum baseline should include:
- Do not commit tokens, passwords, private keys,
.env, or build logs containing credentials. If a leak is discovered, revoke/rotate first, then address the history. - Use
SECURITY.mdto specify private reporting channels, supported versions, and the scope of the response. Do not put vulnerability details in public issues. - Use CODEOWNERS for critical paths; workflows, release configuration, and dependency updates should not go unreviewed.
- Enable available secret scanning and push protection, and understand their coverage, false positives, and bypass processes.
- Evaluate Dependabot alerts, Dependabot security updates, dependency review, and code scanning; availability depends on repository type, organization policies, and plan.
- Grant Actions only the permissions they need; pin third-party Actions to reviewed versions or commits and update them regularly.
- Use Branch Protection/Rulesets to enforce critical checks, reviews, and prohibitions on destructive pushes as platform rules.
GitHub’s security features continually change; do not assume a button available on one plan represents a capability every repository has. Official starting points: Quickstart for securing your repository, Secret scanning, Adding a security policy, and About code owners.
6.2 An actionable maintenance checklist
| When | Check | Evidence |
|---|---|---|
| Every change | PR description, linked issues, Required Checks, and review responsibility | PR, check run, and review records |
| Weekly or during each focused maintenance session | Close obsolete issues, add labels, and update Milestone/Project status | Issue history and project views |
| Every release | Version number, CHANGELOG, tag, release notes, and installation verification | Tag, Release, and verification commands/logs |
| Dependency updates | Dependency alerts, scope of changes, compatibility, and rollback plan | Dependabot/PR/Release records |
| Monthly or quarterly | Permissions, team members, bypasses, Secrets, webhooks, and rules | Settings audit, organization logs, and rule snapshots |
| After a security incident | Revoke credentials, assess historical exposure, notify affected people, and review gaps in protection | Private report records and remediation PRs |
6.3 Governance priorities for the example project
For the teaching scenario above, governance work can be prioritized as follows:
- Add
CONTRIBUTING.mddescribing local Nix checks, evidence required for PRs, documentation synchronization, and compatibility statements. - Add
SECURITY.mddefining the security-reporting channel and warning against pasting credentials or vulnerability details into public issues. - Add minimal Bug/Feature/PR templates so issues and contribution requests can be reproduced and checked against acceptance criteria.
- If maintainers want mandatory review for critical paths, add CODEOWNERS and check the file paths and permissions.
- Observe the actual check names and failure rate produced by
.github/workflows/nix.yml, then design Ruleset/Branch Protection and Required Checks formain. - Once the rules are stable, document them along with the release process and security checks, completing the loop of “repository files + platform settings + verification commands.”
This ordering avoids setting up a Required Check that nobody understands or treating community files as decorative templates. Every item should serve actual contribution and release workflows.
7. Official resources and further reading#
- GitHub Docs
- GitHub CLI Manual
- About repositories
- Repository roles
- About issues
- About protected branches
- About rulesets
- About releases
- Quickstart for securing a repository
- GitHub CLI
gh repo edit - GitHub CLI
gh ruleset - GitHub CLI
gh release
GitHub’s UI, plans, permissions, and product limits change. When documentation differs from the current interface, rely on current official documentation and the actual results in the repository’s Settings, and update the verification date in the project’s maintenance records.
References & further reading
- About repositories ↗
- About repository topics ↗
- GitHub CLI `gh repo view ↗
- GitHub plans ↗
- Repository visibility documentation ↗
- Repository roles for an organization ↗
- gh repo edit ↗
- About issue and pull request templates ↗
- About milestones ↗
- About Projects ↗
- Changing the default branch ↗
- About rulesets ↗
- Available rules for rulesets ↗
- About protected branches ↗
- gh ruleset ↗
- gh api ↗
- About releases ↗
- Managing releases ↗
- gh release ↗
- Transferring a repository ↗
- Archiving a GitHub repository ↗
- Quickstart for securing your repository ↗
- Secret scanning ↗
- Adding a security policy ↗
- About code owners ↗
- GitHub Docs ↗
- GitHub CLI Manual ↗
- About issues ↗
Adapted from technical notes. Examples use generic names.