From c336f54315f4d3a8f80c2b8c82a0055037e7bf76 Mon Sep 17 00:00:00 2001
From: Patrick Kollitsch <davidsneighbourdev+gh@gmail.com>
Date: Fri, 15 May 2026 01:50:22 +0000
Subject: [PATCH] ci: update branch setup/rules and CONTRIBUTING.md
---
/dev/null | 25 ----
.vscode/extensions.json | 14 +-
CONTRIBUTING.md | 91 +++++++++++---
.vscode/settings.json | 3
.yamllint.yml | 61 ++++++++++
.github/dependabot.yml | 27 +++-
.lintstagedrc.js | 6
.github/workflows/branch-protection.yml | 73 ++++++++++++
.github/workflows/quickstart.yml | 7
9 files changed, 236 insertions(+), 71 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 6f4a854..931fe90 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -10,11 +10,14 @@
day: friday
time: "18:00"
timezone: Asia/Bangkok
+ cooldown:
+ default-days: 14
+ semver-major-days: 14
+ semver-minor-days: 7
+ semver-patch-days: 4
assignees:
- davidsneighbour
- reviewers:
- - davidsneighbour
- target-branch: development
+ target-branch: maintenance
open-pull-requests-limit: 999
pull-request-branch-name:
separator: /
@@ -28,11 +31,14 @@
day: friday
time: "18:00"
timezone: Asia/Bangkok
+ cooldown:
+ default-days: 14
+ semver-major-days: 14
+ semver-minor-days: 7
+ semver-patch-days: 4
assignees:
- davidsneighbour
- reviewers:
- - davidsneighbour
- target-branch: development
+ target-branch: maintenance
open-pull-requests-limit: 999
pull-request-branch-name:
separator: /
@@ -46,11 +52,14 @@
day: friday
time: "18:00"
timezone: Asia/Bangkok
+ cooldown:
+ default-days: 14
+ semver-major-days: 14
+ semver-minor-days: 7
+ semver-patch-days: 4
assignees:
- davidsneighbour
- reviewers:
- - davidsneighbour
- target-branch: development
+ target-branch: maintenance
open-pull-requests-limit: 999
pull-request-branch-name:
separator: /
diff --git a/.github/workflows/branch-protection-main.yml b/.github/workflows/branch-protection-main.yml
deleted file mode 100644
index 117f713..0000000
--- a/.github/workflows/branch-protection-main.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: Validate main branch source
-
-on:
- pull_request:
- branches:
- - main
-
-permissions:
- contents: read
- pull-requests: read
-
-jobs:
- validate-source-branch:
- name: Require development as source branch
- runs-on: ubuntu-latest
-
- steps:
- - name: Validate source branch
- env:
- HEAD_REF: ${{ github.head_ref }}
- run: |
- if [ "${HEAD_REF}" != "development" ]; then
- echo "::error::Pull requests into main must come from development. Current source branch: ${HEAD_REF}"
- exit 1
- fi
\ No newline at end of file
diff --git a/.github/workflows/branch-protection.yml b/.github/workflows/branch-protection.yml
new file mode 100644
index 0000000..45499b7
--- /dev/null
+++ b/.github/workflows/branch-protection.yml
@@ -0,0 +1,73 @@
+name: Validate pull request rules
+
+on:
+ pull_request:
+
+permissions:
+ contents: read
+ pull-requests: read
+
+jobs:
+ validate-main-source-branch:
+ name: Require staging or maintenance as source branch for main
+ runs-on: ubuntu-latest
+ if: github.base_ref == 'main'
+
+ steps:
+ - name: Validate source branch
+ shell: bash
+ env:
+ HEAD_REF: ${{ github.head_ref }}
+ run: |
+ set -euo pipefail
+
+ if [ "${HEAD_REF}" != "staging" ] && [ "${HEAD_REF}" != "maintenance" ]; then
+ echo "::error::Pull requests into main must come from staging or maintenance. Current source branch: ${HEAD_REF}"
+ exit 1
+ fi
+
+ validate-staging-source-branch:
+ name: Require development or maintenance as source branch for staging
+ runs-on: ubuntu-latest
+ if: github.base_ref == 'staging'
+
+ steps:
+ - name: Validate source branch
+ shell: bash
+ env:
+ HEAD_REF: ${{ github.head_ref }}
+ run: |
+ set -euo pipefail
+
+ if [ "${HEAD_REF}" != "development" ] && [ "${HEAD_REF}" != "maintenance" ]; then
+ echo "::error::Pull requests into staging must come from development or maintenance. Current source branch: ${HEAD_REF}"
+ exit 1
+ fi
+
+ protect-package-lock:
+ name: Block package-lock.json outside maintenance
+ runs-on: ubuntu-latest
+ if: github.base_ref != 'maintenance'
+
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Fail if package-lock.json changed outside maintenance
+ shell: bash
+ env:
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
+ BASE_REF: ${{ github.base_ref }}
+ run: |
+ set -euo pipefail
+
+ changed_files=$(git diff --name-only "${BASE_SHA}...${HEAD_SHA}")
+
+ if echo "${changed_files}" | grep -Fxq "package-lock.json"; then
+ echo "::error file=package-lock.json::package-lock.json may only be changed in PRs targeting maintenance. Current target branch: ${BASE_REF}"
+ exit 1
+ fi
\ No newline at end of file
diff --git a/.github/workflows/quickstart.yml b/.github/workflows/quickstart.yml
index 6bff059..a9ece81 100644
--- a/.github/workflows/quickstart.yml
+++ b/.github/workflows/quickstart.yml
@@ -20,17 +20,18 @@
steps:
- name: Check out repository
- uses: actions/checkout@v6
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
+ persist-credentials: false
submodules: false
- name: Set up Node.js
- uses: actions/setup-node@v6
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e
with:
node-version: "24"
- name: Set up Hugo
- uses: peaceiris/actions-hugo@v3
+ uses: peaceiris/actions-hugo@2752ce1d29631191ea3f27c23495fa06139a5b78
with:
hugo-version: "latest"
extended: true
diff --git a/.lintstagedrc.js b/.lintstagedrc.js
index 70217bc..fe4f6f2 100644
--- a/.lintstagedrc.js
+++ b/.lintstagedrc.js
@@ -6,16 +6,14 @@
*/
export default {
"*.{json,jsonc}": ["biome check --write --staged"],
- // '.github/workflows/**/*.y(a?)ml': [
- // 'zizmor --no-exit-codes',
- // ],
+ ".github/{workflows/**/*.y(a?)ml,dependabot.yml}": ["zizmor --no-exit-codes"],
"package-lock.json": [
"lockfile-lint --path package-lock.json --validate-https --allowed-hosts npm",
],
"*.{ts,tsx,(m|c)js,jsx}": (/** @type {string[]} */ files) => {
return [`biome check --write --no-errors-on-unmatched ${files.join(" ")}`];
},
- // '*.yaml': ['yamllint -c .yamllint.yml'],
+ "*.yaml": ["yamllint -c .yamllint.yml"],
// '*.{scss,css}': ['stylelint --fix', "prettier --write"],
// '*.{png,jpeg,jpg,gif,svg}': [
// 'imagemin-lint-staged' // @davidsneighbour/imagemin-lint-staged
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 50aaa68..d438e75 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,7 +1,9 @@
{
- "recommendations": [
- "pkief.material-icon-theme",
- "yzhang.markdown-all-in-one",
- "davidanson.vscode-markdownlint"
- ]
-}
\ No newline at end of file
+ "recommendations": [
+ "pkief.material-icon-theme",
+ "yzhang.markdown-all-in-one",
+ "davidanson.vscode-markdownlint",
+ "zizmor.zizmor-vscode",
+ "redhat.vscode-yaml"
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e22b55e..6600c92 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -27,5 +27,6 @@
"theme.toml": "go.mod, go.sum",
"README.md": "CHANGELOG.md, LICENSE.md, CONTRIBUTING.md, RELEASES.md, DESIGN.md"
},
- "window.autoDetectColorScheme": false
+ "window.autoDetectColorScheme": false,
+ "markdown.extension.tableFormatter.enabled": false
}
diff --git a/.yamllint.yml b/.yamllint.yml
new file mode 100644
index 0000000..533f78e
--- /dev/null
+++ b/.yamllint.yml
@@ -0,0 +1,61 @@
+extends: default
+
+locale: en_US.UTF-8
+
+yaml-files:
+ - "*.yaml"
+ - "*.yml"
+ - "*.md"
+
+ignore: |
+ .github/workflows/update-netlify.yml
+ .github/workflows/daily-audit.yml
+ .github/workflows/codeql-analysis.yml
+ .github/dependabot.yml
+
+# https://yamllint.readthedocs.io/en/stable/rules.html
+rules:
+ braces: enable
+ brackets: enable
+ colons: enable
+ commas: enable
+ comments:
+ require-starting-space: true
+ ignore-shebangs: true
+ min-spaces-from-content: 1
+ level: warning
+ comments-indentation:
+ level: warning
+ document-end: disable
+ document-start: disable
+ empty-lines:
+ max: 1
+ max-start: 0
+ max-end: 1
+ empty-values: disable
+ hyphens: enable
+ indentation:
+ spaces: consistent
+ indent-sequences: consistent
+ check-multi-line-strings: true
+ key-duplicates: enable
+ key-ordering: disable
+ line-length:
+ max: 80
+ level: warning
+ new-line-at-end-of-file: enable
+ new-lines:
+ type: unix
+ octal-values:
+ forbid-implicit-octal: true
+ forbid-explicit-octal: true
+ quoted-strings:
+ quote-type: double
+ required: false
+ # required: only-when-needed
+ extra-required: ["^http://", "^https://", "^ftp://"]
+ extra-allowed: []
+ trailing-spaces: enable
+ truthy:
+ level: warning
+ check-keys: false
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index eade183..fbba7d8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,6 +6,9 @@
* [Release Process](#release-process)
* [Before You Start](#before-you-start)
* [Reporting Bugs and Requesting Features](#reporting-bugs-and-requesting-features)
+* [Branch Strategy](#branch-strategy)
+ * [Long-lived branches](#long-lived-branches)
+ * [Branch naming](#branch-naming)
* [Pull Request Workflow](#pull-request-workflow)
* [Circumventing Git Hooks](#circumventing-git-hooks)
* [Documentation Contributions](#documentation-contributions)
@@ -37,27 +40,27 @@
1. Use a compatible Hugo version (see [`config/_default/module.toml`](https://github.com/gohugo-ananke/ananke/blob/main/config/_default/module.toml) for the current state).
2. Install dependencies:
- ```bash
- npm install
- ```
+ ```bash
+ npm install
+ ```
-3. Run a local preview via `npm run` instead of just calling `hugo server`:
+1. Run a local preview via `npm run` instead of just calling `hugo server`:
- ```bash
- npm run server
- ```
+ ```bash
+ npm run server
+ ```
- This runs the documentation site from `site/` using contents from `docs/` with local configuration.
+ This runs the documentation site from `site/` using contents from `docs/` with local configuration.
-4. Follow the coding style and format commit messages as described in the conventional commits specification (for example: `docs: add troubleshooting section` or `fix: correct hero image path`).
+1. Follow the coding style and format commit messages as described in the conventional commits specification (for example: `docs: add troubleshooting section` or `fix: correct hero image path`).
-5. Make sure to install git hooks for linting and testing before you push changes:
+2. Make sure to install git hooks for linting and testing before you push changes:
- ```bash
- npm run prepare
- ```
+ ```bash
+ npm run prepare
+ ```
- This command is run automatically after `npm install` but you can run it manually to set up hooks in an existing clone or update changed hooks. It uses `simple-git-hooks` to install a commit hook that runs `lint-staged` for markdown files, which in turn runs linting tasks on staged files.
+ This command is run automatically after `npm install` but you can run it manually to set up hooks in an existing clone or update changed hooks. It uses `simple-git-hooks` to install a commit hook that runs `lint-staged` for markdown files, which in turn runs linting tasks on staged files.
## Reporting Bugs and Requesting Features
@@ -65,6 +68,47 @@
* Start feature or idea discussions in [GitHub Discussions](https://github.com/gohugo-ananke/ananke/discussions).
* Include clear reproduction steps, expected behaviour, actual behaviour, and versions (`hugo version`, OS, browser if relevant).
+## Branch Strategy
+
+```mermaid
+flowchart LR
+ feature["feature/*, fix/*, docs/*, refactor/*"] --> development
+ development --> staging
+ maintenance --> staging
+ staging --> main
+ main --> staging
+ staging --> development
+```
+
+This repository uses a linear, rebase-based branch model. Long-lived branches MUST stay connected to `main`, and merge commits MUST NOT be introduced.
+
+### Long-lived branches
+
+| Branch | Purpose | Release role | Write policy | Merge |
+| --- | --- | --- | --- | --- |
+| `main` | Stable source of truth | releases | Protected. Only receives reviewed PRs from `staging` or `maintenance`. | Rebase |
+| `staging` | Pre-release integration | pre-releases | Protected. Only receives reviewed PRs from `development`. | Rebase |
+| `development` | Active development | none | Feature, fix, chore, and documentation PRs target this branch. | Squash |
+| `maintenance` | Dependency maintenance | none | Maintainer-only branch for dependency version updates. | Rebase |
+
+### Branch naming
+
+Use short-lived branches for regular work:
+
+* `feat/<topic>`
+* `fix/<topic>`
+* `docs/<topic>`
+* `chore/<topic>`
+* `refactor/<topic>`
+
+Dependency update branches MUST target `maintenance` unless the change is part of an intentional feature branch and does not touch lock files.
+
+After a successful rebase between those branches, push with lease:
+
+```bash
+git push --force-with-lease
+```
+
## Pull Request Workflow
1. Fork the repository and create a focused branch.
@@ -72,16 +116,17 @@
3. Update docs for all user-facing changes.
4. Run quality checks locally:
- ```bash
- npm run lint:markdown
- ```
+ ```bash
+ npm run lint:markdown
+ ```
-5. If your change affects behaviour, validate with Hugo locally (for example `hugo` or `hugo server` in the relevant project).
-6. Open a pull request with:
- * a clear summary,
- * motivation/context,
- * screenshots when UI/visual output changes,
- * linked issues (for example: `Fixes #123`).
+1. If your change affects behaviour, validate with Hugo locally (for example `hugo` or `hugo server` in the relevant project).
+2. Open a pull request with:
+
+* a clear summary,
+* motivation/context,
+* screenshots when UI/visual output changes,
+* linked issues (for example: `Fixes #123`).
## Circumventing Git Hooks
--
Gitblit v1.10.0