diff --git a/.github/CONFIG.md b/.github/CONFIG.md new file mode 100644 index 0000000..b7db081 --- /dev/null +++ b/.github/CONFIG.md @@ -0,0 +1,63 @@ +# GitHub Actions Configuration + +This document describes the secrets used by the Rhiza-provided GitHub Actions workflows +(`.github/workflows/rhiza_*.yml`) and how to configure them. + +## PAT_TOKEN + +Some workflows may need to push changes to files under `.github/workflows/`. The +automatic `github.token` **cannot** do that — GitHub rejects such pushes unless +the token carries the `workflow` scope. If you need it, create a Personal Access +Token (PAT) with the `workflow` scope and store it as a repository secret named +`PAT_TOKEN`. + +If `PAT_TOKEN` is not configured, workflows fall back to `github.token`. + +### Creating the token + +**Fine-grained PAT** (recommended): + +1. Go to **Settings → Developer settings → Fine-grained tokens → Generate new token** + (). +2. Restrict **Repository access** to the repository (or repositories) using Rhiza. +3. Under **Repository permissions**, grant: + - **Contents**: Read and write + - **Workflows**: Read and write + - **Pull requests**: Read and write (needed for the scheduled sync-PR mode) +4. Generate the token and copy it. + +**Classic PAT** (alternative): + +1. Go to **Settings → Developer settings → Tokens (classic) → Generate new token**. +2. Select the `repo` and `workflow` scopes. +3. Generate the token and copy it. + +### Storing the secret + +In the repository that consumes Rhiza: + +1. Go to **Settings → Secrets and variables → Actions → New repository secret**. +2. Name: `PAT_TOKEN` +3. Value: the token created above. + +Or with the GitHub CLI: + +```bash +gh secret set PAT_TOKEN +``` + +A PAT expires; when sync pushes start failing with a `refusing to allow ... workflow` error, +regenerate the token and update the secret. + +## Release workflow secrets (optional) + +The release workflow (`.github/workflows/rhiza_release.yml`) supports additional secrets, all +optional depending on which release features you use: + +| Secret | Purpose | +| --- | --- | +| `PYPI_TOKEN` | Publish the built package to PyPI. Not needed when using trusted publishing (OIDC). | +| `GH_PAT` | Git authentication for installing private dependencies during the release build. | +| `UV_EXTRA_INDEX_URL` | Extra package index URL (with credentials) for private dependencies. | + +`GITHUB_TOKEN` is provided automatically by GitHub Actions and needs no configuration. diff --git a/.github/DISCUSSION_TEMPLATE/help-wanted.yml b/.github/DISCUSSION_TEMPLATE/help-wanted.yml new file mode 100644 index 0000000..754369c --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/help-wanted.yml @@ -0,0 +1,48 @@ +title: "[Help Wanted] " +labels: ["help wanted"] +body: + - type: markdown + attributes: + value: | + Use this template to surface a contribution opportunity. It lets maintainers + describe work that is ready to be picked up — without opening a formal issue. + + - type: input + id: area + attributes: + label: Topic / Area + description: Which part of the project does this involve? + placeholder: e.g. CI workflows, documentation, a specific bundle + validations: + required: true + + - type: textarea + id: help-needed + attributes: + label: What Help Is Needed + description: Describe the task and what "done" looks like. + validations: + required: true + + - type: textarea + id: getting-started + attributes: + label: Getting Started + description: Pointers to relevant files, docs, or prior discussion that help a contributor begin. + placeholder: | + - Relevant files: ... + - Related docs: ... + validations: + required: false + + - type: dropdown + id: skill-level + attributes: + label: Skill Level + description: Roughly how much experience is needed to take this on? + options: + - Good first issue (beginner friendly) + - Intermediate + - Advanced + validations: + required: false diff --git a/.github/DISCUSSION_TEMPLATE/ideas.yml b/.github/DISCUSSION_TEMPLATE/ideas.yml new file mode 100644 index 0000000..3ed9990 --- /dev/null +++ b/.github/DISCUSSION_TEMPLATE/ideas.yml @@ -0,0 +1,40 @@ +title: "[Idea] " +labels: ["enhancement"] +body: + - type: markdown + attributes: + value: | + Propose an idea before implementing it. This lightweight RFC process lets the + community gauge interest and shape the design before any code is written. + + - type: textarea + id: idea + attributes: + label: The Idea + description: What are you proposing? Describe it clearly enough that others can react. + validations: + required: true + + - type: textarea + id: motivation + attributes: + label: Motivation + description: What problem does this solve, and who benefits? + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Other approaches you weighed, and why this one is preferable. + validations: + required: false + + - type: textarea + id: references + attributes: + label: References + description: Links to prior art, related discussions, issues, or external resources. + validations: + required: false diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 1da7ad1..9c4408e 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -58,7 +58,7 @@ updates: update-types: - "patch" - "minor" - + commit-message: prefix: "chore(deps)" include: "scope" diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 329b071..d9e50ec 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -19,5 +19,6 @@ Closes # ## Checklist - [ ] Commit messages follow the [Conventional Commits](https://www.conventionalcommits.org/) format +- [ ] `CHANGELOG.md` entry added (or not needed for this change) - [ ] Documentation updated if behaviour changed -- [ ] `make deptry` passes (no unused or missing dependencies) +- [ ] `make deps` passes (no unused or missing dependencies) diff --git a/.github/rulesets/main-branch-protection.json b/.github/rulesets/main-branch-protection.json new file mode 100644 index 0000000..f030647 --- /dev/null +++ b/.github/rulesets/main-branch-protection.json @@ -0,0 +1,47 @@ +{ + "name": "main-branch-protection", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["~DEFAULT_BRANCH"], + "exclude": [] + } + }, + "rules": [ + { "type": "deletion" }, + { "type": "non_fast_forward" }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 1, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_review_thread_resolution": false, + "allowed_merge_methods": ["squash", "merge", "rebase"] + } + }, + { + "type": "required_status_checks", + "parameters": { + "strict_required_status_checks_policy": false, + "required_status_checks": [ + { "context": "ci / Pre-commit hooks", "integration_id": 15368 }, + { "context": "ci / Check dependencies with deptry", "integration_id": 15368 }, + { "context": "ci / docs-coverage", "integration_id": 15368 }, + { "context": "ci / Security scanning", "integration_id": 15368 }, + { "context": "ci / License compliance scan", "integration_id": 15368 }, + { "context": "ci / CI gate", "integration_id": 15368 } + ] + } + } + ], + "bypass_actors": [ + { + "actor_type": "RepositoryRole", + "actor_id": 5, + "bypass_mode": "always" + } + ] +} diff --git a/.github/rulesets/tag-protection.json b/.github/rulesets/tag-protection.json new file mode 100644 index 0000000..1c61dac --- /dev/null +++ b/.github/rulesets/tag-protection.json @@ -0,0 +1,24 @@ +{ + "name": "version-tag-protection", + "target": "tag", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": ["refs/tags/v*"], + "exclude": [] + } + }, + "rules": [ + { "type": "creation" }, + { "type": "update" }, + { "type": "deletion" }, + { "type": "non_fast_forward" } + ], + "bypass_actors": [ + { + "actor_type": "RepositoryRole", + "actor_id": 5, + "bypass_mode": "always" + } + ] +}