diff --git a/content/en/docs/contribution-guidelines/_index.md b/content/en/docs/contribution-guidelines/_index.md index cb32ed5..7ec533c 100644 --- a/content/en/docs/contribution-guidelines/_index.md +++ b/content/en/docs/contribution-guidelines/_index.md @@ -1,9 +1,398 @@ --- -title: Contribution Guidelines -description: Articles related to developers +title: Developer Workflow +description: > + End-to-end guide for contributing to ClusterCockpit using GitHub Flow + with git rebase for a clean, linear history. weight: 80 +tags: [Developer] --- +## Overview -You can find a list with articles related to contributing to ClusterCockpit -[here](/tags/developer/). +ClusterCockpit uses a **GitHub Flow** variant: `main` is always in a deployable +state, all development happens on short-lived feature branches, and every change +lands via a pull request (PR). A linear git history is maintained by rebasing +instead of merging — there are no merge commits from feature branches. + +Two persistent branch types exist alongside the short-lived work branches: + +| Branch | Purpose | +|---|---| +| `main` | Active development; source for the next release | +| `release/v1.x` | Long-lived; created when cutting a minor/major release, receives backported fixes | + +Two contributor models are supported: + +- **External contributors** fork the repository on GitHub and work on branches + inside their fork. +- **Core team members** work on branches directly in the upstream repository. + +The PR-based code review step is identical for both paths. + +--- + +## Prerequisites + +- **Git 2.x** — the workflow uses `--rebase`, `--autostash`, and interactive rebase +- **GitHub account** with access to the relevant ClusterCockpit repository +- Language toolchains for the component you are working on: + - Go 1.25+ for backend components — see [Getting Started]({{< ref "/docs/getting-started" >}}) + - Node.js + npm for the web frontend — see [Frontend Development Setup]({{< ref "frontend-testing" >}}) + - Hugo extended for documentation — see [Contributing to Documentation]({{< ref "documentation" >}}) + +Configure git to rebase by default whenever you pull, and to stash local +changes automatically during a rebase: + +```bash +git config --global pull.rebase true +git config --global rebase.autoStash true +``` + +--- + +## Repository Setup + +### External contributors — fork model + +1. Fork the repository on GitHub (e.g. `ClusterCockpit/cc-backend`). + +2. Clone your fork: + ```bash + git clone https://github.com//cc-backend.git + cd cc-backend + ``` + +3. Add the upstream remote: + ```bash + git remote add upstream https://github.com/ClusterCockpit/cc-backend.git + ``` + +4. Verify: + ```bash + git remote -v + # origin https://github.com//cc-backend.git (fetch) + # origin https://github.com//cc-backend.git (push) + # upstream https://github.com/ClusterCockpit/cc-backend.git (fetch) + # upstream https://github.com/ClusterCockpit/cc-backend.git (push) + ``` + +5. Never commit directly to your fork's `main`. Keep it as a clean mirror of + upstream and always work on named branches. + +### Core team members — direct clone + +1. Clone the upstream repository: + ```bash + git clone https://github.com/ClusterCockpit/cc-backend.git + cd cc-backend + ``` + +2. There is a single `origin` remote pointing to upstream. Push branches to + `origin` and open PRs from there. + +In the commands that follow, core team members replace `upstream` with `origin`. + +--- + +## Branch Naming Conventions + +Short-lived work branches follow this format: + +``` +/- +``` + +The type mirrors the [commit message prefix conventions]({{< ref "commit-messages" >}}): + +| Prefix | Use for | +|---|---| +| `feat/` | New features | +| `fix/` | Bug fixes | +| `sec/` | Security fixes | +| `doc/` | Documentation changes | +| `fix/backport-` | Backports of fixes to a release branch | + +**Examples:** + +``` +feat/123-auto-job-tagging +fix/423-wal-rotation-partial-failure +sec/512-api-token-expiry +doc/rebase-workflow-guide +fix/backport-423-wal-rotation-v1.3 +``` + +Persistent release branches are named `release/v1.x` (minor version only, no +patch number — the branch spans all `v1.x.y` patch releases). + +Avoid generic names like `my-changes`, `patch`, or `wip`. + +--- + +## Daily Development Workflow + +### Step 1 — Sync with upstream before starting + +External contributors: +```bash +git fetch upstream +git checkout main +git rebase upstream/main +git push origin main # keep your fork's main up to date +``` + +Core team: +```bash +git fetch origin +git checkout main +git rebase origin/main +``` + +### Step 2 — Create a feature branch + +Always branch off from `main`: + +```bash +git checkout -b feat/123-my-feature main +``` + +### Step 3 — Develop and commit + +Make small, focused commits as you work. Messages during development can be +informal — they will be cleaned up with interactive rebase before the PR is +opened. Reference issue numbers in commit messages or the PR description. +See [Commit Message Conventions]({{< ref "commit-messages" >}}) for the +prefix rules that apply to the final commit messages. + +### Step 4 — Push your branch + +```bash +git push -u origin feat/123-my-feature +``` + +After any subsequent rebase, push with `--force-with-lease` (never bare +`--force`, which can silently overwrite collaborators' pushes): + +```bash +git push --force-with-lease origin feat/123-my-feature +``` + +--- + +## Keeping Your Branch Up to Date + +While your branch is open, `main` may receive other commits. Rebase rather +than merging to keep the history linear. + +External contributors: +```bash +git fetch upstream +git rebase upstream/main +``` + +Core team: +```bash +git fetch origin +git rebase origin/main +``` + +When conflicts occur, git pauses at each conflicting commit. Resolve the +conflict, stage the resolved files, then continue: + +```bash +# edit conflicting files, then: +git add +git rebase --continue +``` + +To abandon the rebase and restore the pre-rebase state: + +```bash +git rebase --abort +``` + +After rebasing a branch that was already pushed, a force-push is required: + +```bash +git push --force-with-lease origin feat/123-my-feature +``` + +If others are collaborating on your branch, coordinate with them before +force-pushing. + +--- + +## Interactive Rebase — Cleaning Up Before a PR + +Before opening a PR, use interactive rebase to clean up the branch history so +each commit represents a logical, self-contained change with a proper commit +message. + +```bash +git rebase -i upstream/main # or origin/main for core team +``` + +This opens an editor listing every commit on your branch since it diverged +from `main`. Available actions: + +| Action | Effect | +|---|---| +| `pick` | Keep commit as-is | +| `reword` | Keep commit, edit its message | +| `squash` | Fold into the previous commit, combine messages | +| `fixup` | Fold into the previous commit, discard this message | +| `drop` | Remove the commit entirely | + +**Example** — squash four WIP commits into one clean commit: + +``` +pick a1b2c3 feat: initial skeleton for job tagging +squash d4e5f6 wip: add tagger logic +fixup 7g8h9i typo +fixup j0k1l2 add test +``` + +After saving, git prompts you to edit the combined commit message. Apply the +`feat:` / `fix:` prefix conventions here. Then push: + +```bash +git push --force-with-lease origin feat/123-my-feature +``` + +--- + +## Pre-PR Checklist + +Before opening a pull request, verify: + +- [ ] Branch is rebased on current `main` — no merge commits in the branch +- [ ] All commits carry proper prefix messages (see [Commit Message Conventions]({{< ref "commit-messages" >}})) +- [ ] Go tests pass locally: `make test` (see [Unit Tests]({{< ref "testing" >}})) +- [ ] Frontend build passes if frontend files were changed: `npm run build` (see [Frontend Development Setup]({{< ref "frontend-testing" >}})) +- [ ] No debug output, commented-out code, or temporary scaffolding is committed +- [ ] Branch name follows the naming conventions above +- [ ] The relevant issue number is referenced in at least one commit message or the PR description +- [ ] Documentation is updated if the change affects user-facing behaviour (see [Contributing to Documentation]({{< ref "documentation" >}})) + +--- + +## Creating and Managing Pull Requests + +Open a PR from your branch against `ClusterCockpit//main` (or against a +`release/v1.x` branch for backports — see [Preparing a Release]({{< ref "release" >}})). + +**PR title** — follow the same commit prefix conventions: + +``` +feat: add automatic job tagging +fix: correct WAL rotation on partial flush +``` + +**PR description** should include: + +- What the change does and why +- How to test or reproduce the scenario +- The issue number using a closing keyword so GitHub links and closes it automatically: + ``` + Fixes #423 + ``` + See [Commit Message Conventions]({{< ref "commit-messages" >}}) for the full list of accepted keywords. + +**Practical guidelines:** + +- Use GitHub's **Draft** status while work is in progress instead of adding + "WIP" to the title. +- Add reviewers explicitly — do not leave the reviewer field empty. +- Keep PRs small and focused. Split large changes into a series of dependent + PRs when possible. +- Address all review comments before requesting re-review. + +--- + +## Code Review Process + +### For reviewers + +- Review the diff, not the developer. Keep comments constructive and specific. +- Distinguish blocking concerns from suggestions — use **Request changes** only + for issues that must be addressed before merge. +- Check: does the code do what the PR description says? Do tests cover the + change? Are commit messages correct? + +### For authors + +- Address all review comments, either by making changes or by explaining why + no change is needed. +- After addressing feedback, push updated commits to the branch. Coordinate + with the reviewer whether to add new commits or to amend/rebase and + force-push — either approach is acceptable, but agree first. +- Use the **Re-request review** button when ready for another look. +- Do not resolve the reviewer's comment threads yourself; let the reviewer + dismiss their own requests. + +--- + +## Merging + +Only maintainers merge PRs into `main` or `release/v1.x`. + +The preferred merge strategy is **Rebase and merge**: it replays the branch's +commits on top of the target branch without a merge commit, preserving the +linear history. Because authors clean up commits with interactive rebase before +opening the PR, the rebased commits are already in final form. + +After merge: +- GitHub closes the linked issue automatically if the PR description used a + closing keyword (`Fixes #N`, `Closes #N`, etc.). +- The merged branch is deleted from the remote immediately — enable this in + GitHub repository settings (*Automatically delete head branches*). + +--- + +## After Merge Cleanup + +Sync your local `main`: + +External contributors: +```bash +git fetch upstream +git checkout main +git rebase upstream/main +git push origin main +``` + +Core team: +```bash +git fetch origin +git checkout main +git rebase origin/main +``` + +Delete the local feature branch: + +```bash +git branch -d feat/123-my-feature +``` + +Use `-D` instead of `-d` only if the branch was squash-merged and git reports +it as unmerged. If the remote branch was not deleted automatically: + +```bash +git push origin --delete feat/123-my-feature +``` + +You are now ready to start the next feature. Return to +[Daily Development Workflow](#daily-development-workflow). + +--- + +## Reference + +The pages in this section cover topic-specific details that apply within the +workflow described above: + +- [Commit Message Conventions]({{< ref "commit-messages" >}}) — prefix tags, issue linking, goreleaser integration +- [Unit Tests]({{< ref "testing" >}}) — Go test conventions and how to run the test suite locally +- [Frontend Development Setup]({{< ref "frontend-testing" >}}) — Svelte/npm workflow for cc-backend +- [Contributing to Documentation]({{< ref "documentation" >}}) — Hugo setup, local preview, Docsy conventions +- [Preparing a Release]({{< ref "release" >}}) — release branches, tagging, goreleaser, backporting diff --git a/content/en/docs/contribution-guidelines/commit-messages.md b/content/en/docs/contribution-guidelines/commit-messages.md index 187a2a6..e9f6820 100644 --- a/content/en/docs/contribution-guidelines/commit-messages.md +++ b/content/en/docs/contribution-guidelines/commit-messages.md @@ -1,50 +1,79 @@ --- -title: Commit message naming conventions -weight: 90 -description: Special keywords to reference tickets and control release notes +title: Commit Message Conventions +weight: 10 +description: Prefix tags for release notes, issue linking, and goreleaser integration tags: [Developer] --- + ## Introduction ClusterCockpit uses [goreleaser](https://goreleaser.com/) for building and -uploading releases. In this process the release notes including all notable -changes are automatically generated based on special commit message tags. -Moreover GitHub will parse special characters and words to link and close -issues. +uploading releases. Release notes are generated automatically from commit +messages using the prefix tags described below. GitHub also parses special +keywords to link commits and PRs to issues. -## Reference issue tickets +Before opening a pull request, use [interactive rebase]({{< ref "_index#interactive-rebase----cleaning-up-before-a-pr" >}}) +to clean up your branch history and ensure the final commit messages follow +these conventions. -It is good practice to always create a ticket for notable changes. -This allows to comment and discuss about source code changes. Any commit that -contributes to the ticket should reference the ticket id (in the commit message -or description). This is achieved in GitHub by prefixing the ticket id with a -number sign character (`#`): +--- + +## Release Note Prefixes + +Commits carrying one of the following prefixes appear in the generated release +notes: + +| Prefix | Appears under | +|---|---| +| `feat:` | New features | +| `fix:` | Bug fixes | +| `sec:` | Security fixes (ClusterCockpit-specific) | +| `doc:` | Documentation updates | +| `feat dep:` or `fix dep:` | Dependency additions or changes | + +Commits without a recognised prefix are not included in the release notes. + +**Examples:** -```txt -This change contributes to #235 +``` +feat: add automatic job tagging +fix: correct WAL rotation on partial flush (#423) +sec: enforce API token expiry +doc: update rebase workflow guide +feat dep: upgrade to Go 1.22 ``` -GitHub will detect if a pull request or commit uses special keywords to close a -ticket: +--- -- close, closes, closed -- fix, fixes, fixed -- resolve, resolves, resolved +## Referencing Issues -The ticket will not be closed before the commit appears on the main branch. -Example: +It is good practice to create a GitHub issue for any notable change so that +the motivation and discussion are preserved. Reference an issue in any commit +message or PR description using the `#` syntax: -```txt -This change fixes #423 ``` +This change contributes to #235 +``` + +--- + +## Automatically Closing Issues -## Control release notes with preconfigured commit message prefixes +GitHub closes an issue automatically when a PR containing one of the following +keywords merges into the default branch: -Commits with one of the following prefixes will appear in the release notes: +- `close`, `closes`, `closed` +- `fix`, `fixes`, `fixed` +- `resolve`, `resolves`, `resolved` + +The issue is not closed until the commit appears on `main`. Example: + +``` +fix: correct WAL rotation on partial flush + +Fixes #423 +``` -- **feat:** Mark a commit to contain changes related to new features -- **fix:** Mark a commit to contain changes related to bug fixes -- **sec:** Mark a commit to contain changes related to security fixes -- **doc:** Mark a commit to contain changes related to documentation updates -- **[feat|fix] dep:** Mark a commit that is related to a dependency introduction - or change +Place the closing keyword in the PR description rather than a WIP commit +message, since commit messages are often rewritten with interactive rebase +before the PR is merged. diff --git a/content/en/docs/contribution-guidelines/documentation.md b/content/en/docs/contribution-guidelines/documentation.md index 20ef3aa..3458962 100644 --- a/content/en/docs/contribution-guidelines/documentation.md +++ b/content/en/docs/contribution-guidelines/documentation.md @@ -1,62 +1,64 @@ --- -title: Contribute documentation -weight: 90 -description: How to contribute to the documentation website +title: Contributing to Documentation +weight: 40 +description: How to set up a local Hugo environment and contribute to the documentation website +tags: [Developer] --- -We use [Hugo](https://gohugo.io/) to format and generate our website, the -[Docsy](https://github.com/google/docsy) theme for styling and site structure. -Hugo is an open-source static site generator that provides us with templates, -content organisation in a standard directory structure, and a website generation -engine. You write the pages in Markdown (or HTML if you want), and Hugo wraps them up into a website. -All submissions, including submissions by project members, require review. We -use GitHub pull requests for this purpose. Consult -[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more -information on using pull requests. +The ClusterCockpit documentation is built with [Hugo](https://gohugo.io/) using +the [Docsy](https://github.com/google/docsy) theme. Pages are written in +Markdown. Hugo wraps them into a static site with navigation, search, and +versioning. -## Quick start +All documentation contributions follow the same branch and PR workflow +described in the [Developer Workflow]({{< ref "_index" >}}) guide. The +repository to fork or clone is +[ClusterCockpit/cc-doc](https://github.com/ClusterCockpit/cc-doc). -Here's a quick guide to updating the docs. It assumes you're familiar with the -GitHub workflow and you're happy to use the automated preview of your doc -updates: +--- -1. Fork the [cc-docs repo](https://github.com/ClusterCockpit/cc-doc) on GitHub. -1. Make your changes and send a pull request (PR). -1. If you're not yet ready for a review, add "WIP" to the PR name to indicate - it's a work in progress. -1. Preview the website locally as described beyond. -1. Continue updating your doc and pushing your changes until you're happy with - the content. -1. When you're ready for a review, add a comment to the PR, and remove any - "WIP" markers. +## Local Setup -## Updating a single page +You need the **Hugo extended** version (for SCSS support), at minimum Hugo +0.45 — the most recent available version is recommended. -If you've just spotted something you'd like to change while using the docs, Docsy has a shortcut for you: +Clone the repository with submodules (required for the Docsy theme): -1. Click **Edit this page** in the top right hand corner of the page. -1. If you don't already have an up to date fork of the project repo, you are prompted to get one - click **Fork this repository and propose changes** or **Update your Fork** to get an up to date version of the project to edit. The appropriate page in your fork is displayed in edit mode. +```bash +git clone --recurse-submodules https://github.com/ClusterCockpit/cc-doc.git +cd cc-doc +``` -## Previewing your changes locally +Start the local development server: -If you want to run your own local Hugo server to preview your changes as you work: +```bash +hugo server +``` -1. Follow the instructions in [Getting started](https://www.docsy.dev/docs/get-started/) to install Hugo and any other tools you need. You'll need at least **Hugo version 0.45** (we recommend using the most recent available version), and it must be the **extended** version, which supports SCSS. -1. Fork the [cc-docs](https://github.com/ClusterCockpit/cc-doc) repo into your own project, then create a local copy using `git clone`. Don’t forget to use `--recurse-submodules` or you won’t pull down some of the code you need to generate a working site. +Your site is available at . Hugo watches for file +changes and automatically rebuilds and reloads the page. -```sh -git clone --recurse-submodules --depth 1 https://github.com/ClusterCockpit/cc-doc.git -``` +--- -1. Run `hugo server` in the site root directory. By default your site will be available at . Now that you're serving your site locally, Hugo will watch for changes to the content and automatically refresh your site. -1. Continue with the usual GitHub workflow to edit files, commit them, push the changes up to your fork, and create a pull request. +## Quick Edit via GitHub -## Creating an issue +For small corrections to an existing page, use the **Edit this page** link in +the top-right corner of any documentation page. GitHub will prompt you to fork +the repository if you have not already, open the file in edit mode, and guide +you through creating a PR. -If you've found a problem in the docs, but you're not sure how to fix it yourself, please create an issue in the [cc-docs](https://github.com/ClusterCockpit/cc-doc/issues). You can also create an issue about a specific page by clicking the **Create Issue** button in the top right hand corner of the page. +--- + +## Creating an Issue + +If you have found a problem but are not ready to fix it yourself, open an issue +in the [cc-doc repository](https://github.com/ClusterCockpit/cc-doc/issues). +You can also use the **Create Issue** button in the top-right corner of any +documentation page. + +--- -## Useful resources +## Useful Resources -* [Docsy user guide](https://www.docsy.dev/docs/): All about Docsy, including how it manages navigation, look and feel, and multi-language support. -* [Hugo documentation](https://gohugo.io/documentation/): Comprehensive reference for Hugo. -* [Github Hello World!](https://guides.github.com/activities/hello-world/): A basic introduction to GitHub concepts and workflow. +- [Docsy user guide](https://www.docsy.dev/docs/) — navigation, look and feel, multi-language support +- [Hugo documentation](https://gohugo.io/documentation/) — comprehensive Hugo reference diff --git a/content/en/docs/contribution-guidelines/example-page.md b/content/en/docs/contribution-guidelines/example-page.md deleted file mode 100644 index f3b2ae4..0000000 --- a/content/en/docs/contribution-guidelines/example-page.md +++ /dev/null @@ -1,228 +0,0 @@ ---- -title: Docsy example page -weight: 90 -description: Example page to showcase formatting options for docsy. ---- - -{{% pageinfo %}} -This is a placeholder page. Replace it with your own content. -{{% /pageinfo %}} - -Text can be **bold**, _italic_, or ~~strikethrough~~. [Links](https://gohugo.io) should be blue with no underlines (unless hovered over). - -There should be whitespace between paragraphs. Vape migas chillwave sriracha poutine try-hard distillery. Tattooed shabby chic small batch, pabst art party heirloom letterpress air plant pop-up. Sustainable chia skateboard art party banjo cardigan normcore affogato vexillologist quinoa meggings man bun master cleanse shoreditch readymade. Yuccie prism four dollar toast tbh cardigan iPhone, tumblr listicle live-edge VHS. Pug lyft normcore hot chicken biodiesel, actually keffiyeh thundercats photo booth pour-over twee fam food truck microdosing banh mi. Vice activated charcoal raclette unicorn live-edge post-ironic. Heirloom vexillologist coloring book, beard deep v letterpress echo park humblebrag tilde. - -90's four loko seitan photo booth gochujang freegan tumeric listicle fam ugh humblebrag. Bespoke leggings gastropub, biodiesel brunch pug fashion axe meh swag art party neutra deep v chia. Enamel pin fanny pack knausgaard tofu, artisan cronut hammock meditation occupy master cleanse chartreuse lumbersexual. Kombucha kogi viral truffaut synth distillery single-origin coffee ugh slow-carb marfa selfies. Pitchfork schlitz semiotics fanny pack, ugh artisan vegan vaporware hexagon. Polaroid fixie post-ironic venmo wolf ramps **kale chips**. - -> There should be no margin above this first sentence. -> -> Blockquotes should be a lighter gray with a border along the left side in the secondary color. -> -> There should be no margin below this final sentence. - -## First Header 2 - -This is a normal paragraph following a header. Knausgaard kale chips snackwave microdosing cronut copper mug swag synth bitters letterpress glossier **craft beer**. Mumblecore bushwick authentic gochujang vegan chambray meditation jean shorts irony. Viral farm-to-table kale chips, pork belly palo santo distillery activated charcoal aesthetic jianbing air plant woke lomo VHS organic. Tattooed locavore succulents heirloom, small batch sriracha echo park DIY af. Shaman you probably haven't heard of them copper mug, crucifix green juice vape _single-origin coffee_ brunch actually. Mustache etsy vexillologist raclette authentic fam. Tousled beard humblebrag asymmetrical. I love turkey, I love my job, I love my friends, I love Chardonnay! - -Deae legum paulatimque terra, non vos mutata tacet: dic. Vocant docuique me plumas fila quin afuerunt copia haec o neque. - -On big screens, paragraphs and headings should not take up the full container width, but we want tables, code blocks and similar to take the full width. - -Scenester tumeric pickled, authentic crucifix post-ironic fam freegan VHS pork belly 8-bit yuccie PBR&B. **I love this life we live in**. - -## Second Header 2 - -> This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. - -### Header 3 - -``` -This is a code block following a header. -``` - -Next level leggings before they sold out, PBR&B church-key shaman echo park. Kale chips occupy godard whatever pop-up freegan pork belly selfies. Gastropub Belinda subway tile woke post-ironic seitan. Shabby chic man bun semiotics vape, chia messenger bag plaid cardigan. - -#### Header 4 - -* This is an unordered list following a header. -* This is an unordered list following a header. -* This is an unordered list following a header. - -##### Header 5 - -1. This is an ordered list following a header. -2. This is an ordered list following a header. -3. This is an ordered list following a header. - -###### Header 6 - -| What | Follows | -|-----------|-----------------| -| A table | A header | -| A table | A header | -| A table | A header | - ----------------- - -There's a horizontal rule above and below this. - ----------------- - -Here is an unordered list: - -* Liverpool F.C. -* Chelsea F.C. -* Manchester United F.C. - -And an ordered list: - -1. Michael Brecker -2. Seamus Blake -3. Branford Marsalis - -And an unordered task list: - -* [x] Create a Hugo theme -* [x] Add task lists to it -* [ ] Take a vacation - -And a "mixed" task list: - -* [ ] Pack bags -* ? -* [ ] Travel! - -And a nested list: - -* Jackson 5 - * Michael - * Tito - * Jackie - * Marlon - * Jermaine -* TMNT - * Leonardo - * Michelangelo - * Donatello - * Raphael - -Definition lists can be used with Markdown syntax. Definition headers are bold. - -Name -: Godzilla - -Born -: 1952 - -Birthplace -: Japan - -Color -: Green - ----------------- - -Tables should have bold headings and alternating shaded rows. - -| Artist | Album | Year | -|-------------------|-----------------|------| -| Michael Jackson | Thriller | 1982 | -| Prince | Purple Rain | 1984 | -| Beastie Boys | License to Ill | 1986 | - -If a table is too wide, it should scroll horizontally. - -| Artist | Album | Year | Label | Awards | Songs | -|-------------------|-----------------|------|-------------|----------|-----------| -| Michael Jackson | Thriller | 1982 | Epic Records | Grammy Award for Album of the Year, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Selling Album, Grammy Award for Best Engineered Album, Non-Classical | Wanna Be Startin' Somethin', Baby Be Mine, The Girl Is Mine, Thriller, Beat It, Billie Jean, Human Nature, P.Y.T. (Pretty Young Thing), The Lady in My Life | -| Prince | Purple Rain | 1984 | Warner Brothers Records | Grammy Award for Best Score Soundtrack for Visual Media, American Music Award for Favorite Pop/Rock Album, American Music Award for Favorite Soul/R&B Album, Brit Award for Best Soundtrack/Cast Recording, Grammy Award for Best Rock Performance by a Duo or Group with Vocal | Let's Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I'm a Star, Purple Rain | -| Beastie Boys | License to Ill | 1986 | Mercury Records | noawardsbutthistablecelliswide | Rhymin & Stealin, The New Style, She's Crafty, Posse in Effect, Slow Ride, Girls, (You Gotta) Fight for Your Right, No Sleep Till Brooklyn, Paul Revere, Hold It Now, Hit It, Brass Monkey, Slow and Low, Time to Get Ill | - ----------------- - -Code snippets like `var foo = "bar";` can be shown inline. - -Also, `this should vertically align` ~~`with this`~~ ~~and this~~. - -Code can also be shown in a block element. - -``` -foo := "bar"; -bar := "foo"; -``` - -Code can also use syntax highlighting. - -```go -func main() { - input := `var foo = "bar";` - - lexer := lexers.Get("javascript") - iterator, _ := lexer.Tokenise(nil, input) - style := styles.Get("github") - formatter := html.New(html.WithLineNumbers()) - - var buff bytes.Buffer - formatter.Format(&buff, style, iterator) - - fmt.Println(buff.String()) -} -``` - -``` -Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this. -``` - -Inline code inside table cells should still be distinguishable. - -| Language | Code | -|-------------|--------------------| -| Javascript | `var foo = "bar";` | -| Ruby | `foo = "bar"{` | - ----------------- - -Small images should be shown at their actual size. - -![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Picea_abies_shoot_with_buds%2C_Sogndal%2C_Norway.jpg/240px-Picea_abies_shoot_with_buds%2C_Sogndal%2C_Norway.jpg) - -Large images should always scale down and fit in the content container. - -![](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Picea_abies_shoot_with_buds%2C_Sogndal%2C_Norway.jpg/1024px-Picea_abies_shoot_with_buds%2C_Sogndal%2C_Norway.jpg) - -_The photo above of the Spruce Picea abies shoot with foliage buds: Bjørn Erik Pedersen, CC-BY-SA._ - -## Components - -### Alerts - -{{< alert >}}This is an alert.{{< /alert >}} -{{< alert title="Note" >}}This is an alert with a title.{{< /alert >}} -{{% alert title="Note" %}}This is an alert with a title and **Markdown**.{{% /alert %}} -{{< alert color="success" >}}This is a successful alert.{{< /alert >}} -{{< alert color="warning" >}}This is a warning.{{< /alert >}} -{{< alert color="warning" title="Warning" >}}This is a warning with a title.{{< /alert >}} - -## Another Heading - -Add some sections here to see how the ToC looks like. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong. - -### This Document - -Inguina genus: Anaphen post: lingua violente voce suae meus aetate diversi. Orbis unam nec flammaeque status deam Silenum erat et a ferrea. Excitus rigidum ait: vestro et Herculis convicia: nitidae deseruit coniuge Proteaque adiciam _eripitur_? Sitim noceat signa _probat quidem_. Sua longis _fugatis_ quidem genae. - -### Pixel Count - -Tilde photo booth wayfarers cliche lomo intelligentsia man braid kombucha vaporware farm-to-table mixtape portland. PBR&B pickled cornhole ugh try-hard ethical subway tile. Fixie paleo intelligentsia pabst. Ennui waistcoat vinyl gochujang. Poutine salvia authentic affogato, chambray lumbersexual shabby chic. - -### Contact Info - -Plaid hell of cred microdosing, succulents tilde pour-over. Offal shabby chic 3 wolf moon blue bottle raw denim normcore poutine pork belly. - -### External Links - -Stumptown PBR&B keytar plaid street art, forage XOXO pitchfork selvage affogato green juice listicle pickled everyday carry hashtag. Organic sustainable letterpress sartorial scenester intelligentsia swag bushwick. Put a bird on it stumptown neutra locavore. IPhone typewriter messenger bag narwhal. Ennui cold-pressed seitan flannel keytar, single-origin coffee adaptogen occupy yuccie williamsburg chillwave shoreditch forage waistcoat. - -``` -This is the final element on the page and there should be no margin below this. -``` diff --git a/content/en/docs/contribution-guidelines/frontend-testing.md b/content/en/docs/contribution-guidelines/frontend-testing.md index 8912955..45eba2e 100644 --- a/content/en/docs/contribution-guidelines/frontend-testing.md +++ b/content/en/docs/contribution-guidelines/frontend-testing.md @@ -1,46 +1,77 @@ --- -title: Tips for cc-backend frontend development -weight: 99 -description: > - How to setup cc-backend for easiert frontend development +title: Frontend Development Setup +weight: 30 +description: How to set up cc-backend for fast frontend development iteration categories: [cc-backend] tags: [Developer] --- -## ClusterCockpit web frontend +## Overview -The frontend assets including the Svelte js files are per default embedded in -the go binary. To enable a quick turnaround cycle for web development of the -frontend disable embedding of static assets in `config.json`: +The cc-backend web frontend is built with Svelte. By default, the compiled +frontend assets are embedded directly in the Go binary. During frontend +development this is impractical — use the setup below to enable fast +rebuild-on-save iteration without recompiling the backend. + +For all other aspects of the development process (branching, commits, PRs) +follow the [Developer Workflow]({{< ref "_index" >}}) guide. + +--- + +## Setup + +### 1. Disable embedded static files + +In `config.json`, set: ```json "embed-static-files": false, -"static-files": "./web/frontend/public/", - +"static-files": "./web/frontend/public/" ``` -Start the node build process (in directory `./web/frontend`) in development mode: +This tells cc-backend to serve assets from disk rather than from the embedded +filesystem. + +### 2. Start the frontend build in watch mode + +In the `./web/frontend` directory: -```sh -> npm run dev +```bash +npm run dev ``` -This will start the build process in listen mode. Whenever you change a source -files the depending javascript targets will be automatically rebuild. -In case the javascript files are minified you may need to set the production -flag by hand to false in `./web/frontend/rollup.config.mjs`: +This starts the Rollup build in listen mode. Whenever you save a source file, +the affected JavaScript targets are rebuilt automatically. + +If the output is minified when you expect it not to be, set the production flag +manually in `./web/frontend/rollup.config.mjs`: ```mjs const production = false ``` -Usually this should work automatically. +This should normally be set automatically based on the npm script, but the +override is available if needed. + +### 3. Start cc-backend + +From the repository root: + +```bash +./cc-backend -server -dev +``` + +Because assets are served by cc-backend (not a separate dev server), you must +reload the page in your browser manually after each frontend rebuild. + +--- -Because the files are still served by ./cc-backend you have to reload the view -explicitly in your browser. +## Recommended Terminal Layout -A common setup is to have three terminals open: +A common setup is three terminals running concurrently: -* One running cc-backend (working directory repository root): `./cc-backend -server -dev` -* Another running npm in developer mode (working directory `./web/frontend`): `npm run dev` -* And the last one editing the frontend source files +| Terminal | Directory | Command | +|---|---|---| +| 1 | repository root | `./cc-backend -server -dev` | +| 2 | `./web/frontend` | `npm run dev` | +| 3 | any | editor / shell for source edits | diff --git a/content/en/docs/contribution-guidelines/release.md b/content/en/docs/contribution-guidelines/release.md index 1acf9a2..7c5e67e 100644 --- a/content/en/docs/contribution-guidelines/release.md +++ b/content/en/docs/contribution-guidelines/release.md @@ -1,19 +1,150 @@ --- -title: How to prepare a new release +title: Preparing a Release description: > - Steps to prepare releases with goreleaser -tags: [developer] + How to cut new releases and backport fixes using persistent release branches + and goreleaser. +weight: 50 +tags: [Developer] --- -## Steps to prepare a release - -1. On `hotfix` branch: - * Update ReleaseNotes.md - * Update version in Makefile - * Commit, push, and pull request - * Merge in master - -2. On Linux host: - * Pull master - * Ensure that GitHub Token environment variable `GITHUB_TOKEN` is set - * Create release tag: `git tag v1.1.0 -m release` - * Execute `goreleaser release` + +## Branch Model + +ClusterCockpit maintains two types of long-lived branches: + +| Branch | Purpose | +|---|---| +| `main` | Active development; all new features and fixes land here first | +| `release/v1.x` | Persistent branch for a minor release series; receives backported fixes | + +A `release/v1.x` branch is created once when cutting a new minor or major +release and stays open indefinitely. All `v1.x.y` patch releases are tagged +from this branch. Short-lived fix branches for backports are PRed into the +release branch, not into `main`. + +Every change — including urgent fixes — follows the same feature-branch/PR +workflow described in the [Developer Workflow]({{< ref "_index" >}}) guide. +There is no "hotfix directly to main" shortcut. + +--- + +## Cutting a New Minor or Major Release + +### 1. Prepare `main` + +Ensure all PRs intended for the release are merged and CI is green on `main`. + +### 2. Create the release branch + +```bash +git checkout main +git pull --rebase +git checkout -b release/v1.x +git push -u origin release/v1.x +``` + +### 3. Bump the version + +On a short-lived branch from `release/v1.x`, update the version in `Makefile` +and prepare `ReleaseNotes.md`: + +```bash +git checkout -b doc/release-v1.x.0 release/v1.x +# edit Makefile and ReleaseNotes.md +git add Makefile ReleaseNotes.md +git commit -m "doc: prepare release v1.x.0" +git push -u origin doc/release-v1.x.0 +``` + +Open a PR targeting `release/v1.x` (not `main`), get it reviewed, and merge. + +### 4. Tag the release + +On a Linux host with repository push access: + +```bash +git fetch origin +git checkout release/v1.x +git pull --rebase +git tag v1.x.0 -m "release v1.x.0" +git push origin v1.x.0 +``` + +### 5. Run goreleaser + +Ensure the `GITHUB_TOKEN` environment variable is set, then: + +```bash +goreleaser release +``` + +goreleaser builds the release artifacts, generates release notes from commit +prefixes, and publishes everything to the GitHub Releases page. See +[Commit Message Conventions]({{< ref "commit-messages" >}}) for the prefix +tags that control what appears in the release notes. + +### 6. Post-release + +- Verify the release appears correctly on the GitHub Releases page. +- Close the milestone for this release if one was used. +- Announce the release in the appropriate channels. + +--- + +## Patch Releases — Backporting Fixes + +Patch releases (`v1.x.1`, `v1.x.2`, …) are cut from the `release/v1.x` +branch after backporting one or more fixes from `main`. + +### 1. Develop the fix on `main` first + +Follow the standard feature-branch workflow and merge the fix into `main` via +a PR. Note the commit SHA(s) of the fix once merged. + +### 2. Create a backport branch + +```bash +git fetch origin +git checkout release/v1.x +git pull --rebase +git checkout -b fix/backport-- +``` + +### 3. Cherry-pick the fix + +```bash +git cherry-pick +``` + +If the cherry-pick produces conflicts, resolve them, stage the files, then +continue: + +```bash +git add +git cherry-pick --continue +``` + +### 4. Open a PR targeting the release branch + +```bash +git push -u origin fix/backport-- +``` + +Open the PR on GitHub and set the **base branch** to `release/v1.x`, not +`main`. The PR description should reference the original issue and the commit +SHA that was cherry-picked. + +### 5. Tag the patch release + +After the backport PR is merged: + +```bash +git fetch origin +git checkout release/v1.x +git pull --rebase +git tag v1.x.1 -m "release v1.x.1" +git push origin v1.x.1 +goreleaser release +``` + +Repeat steps 2–5 for each additional fix that needs to be included in the +patch release before tagging. diff --git a/content/en/docs/contribution-guidelines/testing.md b/content/en/docs/contribution-guidelines/testing.md index 39edf0a..804974f 100644 --- a/content/en/docs/contribution-guidelines/testing.md +++ b/content/en/docs/contribution-guidelines/testing.md @@ -1,41 +1,58 @@ --- -title: Unit tests -description: > - How to do software testing +title: Unit Tests +weight: 20 +description: Go test conventions and how to run the test suite locally tags: [Developer] --- + ## Overview -We use the standard golang testing environment. +ClusterCockpit uses the standard Go testing environment. Run the full test +suite locally before pushing to avoid CI failures — this is part of the +[pre-PR checklist]({{< ref "_index#pre-pr-checklist" >}}). + +--- -The following conventions are used: +## Conventions -* *White box unit tests*: Tests for internal functionality are placed in files -* *Black box unit tests*: Tests for public interfaces are placed in files -with `_test.go` and belong to the package `_test`. -There only exists one package test file per package. -* *Integration tests*: Tests that use multiple componenents are placed in a -package test file. These are named `_test.go` and belong to the -package `_test`. -* *Test assets*: Any required files are placed in a directory `./testdata` -within each package directory. +- **White-box unit tests** — tests for internal (unexported) functionality are + placed in the same file as the code under test, within the same package. +- **Black-box unit tests** — tests for public interfaces are placed in a + separate file named `_test.go` and belong to the package + `_test`. There is at most one such file per package. +- **Integration tests** — tests that exercise multiple components are also + placed in the `_test.go` file under the `_test` + package. +- **Test assets** — any required fixture files are placed in a `./testdata/` + directory within the package directory. -## Executing tests +--- -Visual Studio Code has a very good golang test integration. -For debugging a test this is the recommended solution. +## Running Tests -The Makefile provided by us has a `test` target that executes: +The project `Makefile` provides a `test` target that runs: -```sh -> go clean -testcache -> go build ./... -> go vet ./... -> go test ./... +```bash +go clean -testcache +go build ./... +go vet ./... +go test ./... ``` -Of course the commands can also be used on the command line. -For details about golang testing refer to the standard documentation: +Run it with: + +```bash +make test +``` + +You can also run any of the individual commands directly from the command line. + +For debugging individual tests, Visual Studio Code has excellent Go test +integration including breakpoint support. + +--- + +## Further Reading -* [Testing package](https://pkg.go.dev/testing) -* [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages) +- [Testing package](https://pkg.go.dev/testing) +- [go test command](https://pkg.go.dev/cmd/go#hdr-Test_packages) diff --git a/content/en/docs/reference/cc-metric-collector/installation.md b/content/en/docs/reference/cc-metric-collector/installation.md index fdcc850..0db3433 100644 --- a/content/en/docs/reference/cc-metric-collector/installation.md +++ b/content/en/docs/reference/cc-metric-collector/installation.md @@ -10,7 +10,7 @@ weight: 3 ### Prerequisites -- Go 1.16 or higher +- Go 1.25 or higher - Git - Make - Standard build tools (gcc, etc.) diff --git a/content/en/docs/reference/cc-slurm-adapter/installation.md b/content/en/docs/reference/cc-slurm-adapter/installation.md index 10fa51b..9de3dcf 100644 --- a/content/en/docs/reference/cc-slurm-adapter/installation.md +++ b/content/en/docs/reference/cc-slurm-adapter/installation.md @@ -8,7 +8,7 @@ weight: 1 ## Prerequisites -- Go 1.24.0 or higher +- Go 1.25.0 or higher - Slurm with slurmdbd configured - cc-backend instance with API access - Access to the slurmctld node @@ -18,7 +18,7 @@ weight: 1 ### Requirements ``` -go 1.24.0+ +go 1.25.0+ ``` ### Dependencies