Contribution Guide¶
Code of Conduct¶
- Be kind to others ;
- Critique code not people.
Work inside a Docker¶
Info
We use docker to isolate from our working environment.
Specify the FISH_VERSION you want, and the CMD executed by the container:
make build-pure-on FISH_VERSION=4.0.2
make dev-pure-on FISH_VERSION=4.0.2 CMD="fishtape tests/*.test.fish"
Working with NixOS
We have targets for NixOS called nix-build-pure-on and nix-dev-pure-on:
❯ make build-pure-on-nix dev-pure-on-nix FISH_VERSION=4.0.2
Code Conventions¶
Be Fishy¶
Use the idiomatic test instead of [ brackets (as recommended by the documentation).
Be Explicit¶
-
Use long form options, e.g.
set --local, as they are more explicit over cryptic 1-letter form.-set -l threshold 0 # in seconds +set --local threshold 0 # in seconds -
Use proxy variable to explicit your intention, e.g. use
last_exit_codeinstead of$argv[-1].-set --local pure_symbol (_pure_prompt_symbol $argv[-1]) # Use last exit code only +set --local last_exit_code $argv[-1] +set --local pure_symbol (_pure_prompt_symbol $last_exit_code)
Naming Public Item¶
Namespace your item with the prefix
pure_.
- Variable:
pure_my_variable - Function:
pure_my_public_function - Filename:
pure_my_public_file.fish - Test file:
pure_my_public_file.test.fish
Naming Private Item¶
Namespace your item with the prefix
_pure_(begin with a single underscore).
- Variable:
_pure_my_variable - Function:
_pure_my_private_function - Filename:
_pure_my_private_file.fish - Test file:
_pure_my_private_file.test.fish
Local and Tools¶
No need to use namespace when your variable is declared locally (
set --local) or your file/test file is related to tooling (installer.fish, testing package managers install).
- Filename:
my_tool.fish - Test file:
my_tool.test.fish
Global Variable¶
- Public settings' default values are placed in conf.d/pure.fish
- Private settings and anything else
pureneeds to do on init are placed in conf.d/__pure_init.fish.
Color's Variables¶
Base colors should follow
$pure_color_<meaning>pattern (cf. bootstrap naming).
Example¶
$pure_color_info # cyan
$pure_color_success # green
$pure_color_warning # yellow
$pure_color_danger # red
$pure_color_light
$pure_color_dark
$pure_color_muted # gray
Feature Design¶
Each feature should have:
- [ ] Documentation
- [ ] entry in the README's table of contents ;
- [ ] entry in the doc feature overview ;
- [ ] a section detailing configuration and behavior in doc feature list ;
- [ ] [screenshot generation]screenshot for the different states of the feature.
- [ ] Configurable variables to control behavior and rendering:
- [ ] a flag variable to enable/disable it, e.g.
$pure_enable_<feature>; - [ ] a prefix symbol variable to allow customization, e.g.
$pure_symbol_<feature>; - [ ] a color variable to allow customization, e.g.
$pure_color_<feature>;
- [ ] a flag variable to enable/disable it, e.g.
- [ ] Clean and tested implementation:
- [ ] a function file to encapsulate its logic, e.g.
functions/_pure_<feature>.fish; - [ ] a test file to encapsulate its tests, e.g.
tests/_pure_<feature>.test.fish;
Feature's Variables¶
Each feature should have a dedicated variables to allow customization. Feature's variables (flag, symbol, color) should use
$pure_<type>_<feature>naming pattern:
Role Name pattern flag $pure_<verb>_<feature>color $pure_color_<feature>symbol $pure_symbol_<feature>
Example¶
$pure_enable_git_status
$pure_symbol_git_unpushed_commits
$pure_color_git_unpulled_commits
Feature Flag's Variable¶
Name should follow
$pure_<verb>_<feature>pattern, where:
verbdescribe the action triggered by the feature (i.e.separate,begin,show, etc.) ;featuredescribe the what of the feature (i.e.prompt_on_error,with_current_directory,git_status, etc.). Value should be a boolean.
Example¶
$pure_begin_prompt_with_current_directory = true
$pure_enable_git_async = false
Avoid abbreviation¶
Use complete word over abbreviation.
Example¶
$pure_threshold_command_duration
Posting on social media¶
There is a manual workflow to post on social media.
Releasing¶
Release process is automated in the pipeline with the following steps.
Info
We follow semver, release is manage in the pipeline
Posting on social media¶
There is a workflow to post on social media that is triggered when a new release is published.
Test¶
We run the test workflow on:
- Pull Request changing
- any
**.fish; - and workflow (
*.yml) files ; - on
masterbranch changing **.fishfiles with the exceptionconf.d/pure.fish, as we have dedicated mechanism to manage versions bump ;- and workflow (
*.yml) files
CI jobs¶
The workflows contain these jobs:
- Alpine tests: build and test Pure with Fish 3.3.1, 3.7.1, 4.0.2, 4.2.1, and
edge. - NixOS tests: build and test Pure with the latest Fish release.
- macOS tests: install Fish with Homebrew and run the FishTape suite.
- Version bump: after Alpine tests pass on
master, compute and push the next version when needed. - Tag creation: when
conf.d/pure.fishchanges onmaster, create avX.Y.Ztag from$pure_version. - Release creation: when a version tag is created, generate notes and publish a GitHub Release.
- Documentation: build screenshots, update
docs/changelog.mdfrom GitHub Releases, and publish the MkDocs site. Pull requests run the build without deployment. - Social posting: when a release is published, post its summary to Bluesky and Mastodon.
Versioning¶
Success
Commit messages must follow conventional commits convention.
Versioning is done automatically based on commit messages and triggered only on master branch.
Details:
- We compute the project's next version using a GitHub Action ;
- Then update
$pure_versionvalue in./conf.d/pure.fish; - Finally commit and push the change to the repo.
Info
We have a git hook to append branch name to version on branch checkout. You need to enable githooks in your local repo with
git config core.hooksPath .githooks/
Adding new tag¶
The add-version-tag.yml pipeline is triggered only for master when ./conf.d/pure.fish is changed and add a tagged based on $pure_version.
Workflows¶
Tests execution¶
---
title: Run tests on CI
---
flowchart TD
PUSH("`_push_ event`") -->|"to master"| CI
PR("`_pull_request_<br/>event`") --> |"
- (re)opened
- synchronize
- ready_for_review
"| CI
DISPATCH("`_workflow_dispatch_<br/>event`") --> CI
FILES_CHANGES(Files changed<br/>event) --> |"
- *.fish
- workflow's *.yml"
| CI{"`_ci.yml_<br/>Run tests on CI`"}
CI -->|alpine.yml| ALPINE["fa:fa-linux Alpine<br>Fish 3.x, 4.x & edge"]
CI -->|nixos.yml| NIXOS["fa:fa-linux NixOS<br/>Latest Fish"]
CI -->|macos.yml| MACOS["fa:fa-apple MacOS<br/>Homebrew Fish"]
ALPINE --> RESULT[Test results]
NIXOS --> RESULT
MACOS --> RESULT
Documentation generation¶
see: .github/workflows/doc.yml
---
title: Screenshot and Publish docs
---
flowchart TD
PUSH("`_push_ event`") -->|"changes on <br>docs/"| IMAGE
PR("`_pull_request_<br/>event`") --> |"
changes on
- docs/
- screenshot.fish
"| IMAGE
DISPATCH("`_workflow_dispatch_<br/>event`") --> IMAGE[Build docker image]
IMAGE --> SCREENSHOTS[Screenshot features]
SCREENSHOTS --> CHANGELOG["`Aggregate release notes<br/>into _docs/changelog.md_`"]
CHANGELOG --> PULL{Is it a<br/>Pull request?}
PULL -->|"`**No**`"| SITE[Deploy MkDocs site]
PULL --x|Yes| SKIP@{ shape: framed-circle, label: "Stop" }
Posting to social networks¶
see: .github/workflows/social-networks.yml
---
title: Post message on social networks
---
flowchart TD
RELEASE("`_release_ event`") --> PREP
DISPATCH("`_workflow_dispatch_<br/>event`") --> PREP
PREP["Prepare message<br/>(truncate)"]
PREP -->|post to| BLUESKY["fa:fa-bluesky Bluesky"]
PREP -->|post to| MASTODON["fa:fa-mastodon Mastodon"]
New release¶
see: .github/workflows/release-notes.yml
---
title: Generate and publish release notes
---
flowchart TD
PUSH(push to master) --> CI{Alpine tests pass?}
CI -->|passed| BUMP["Bump project version"]
CI --x|failed| STOP@{ shape: framed-circle, label: "Stop" }
BUMP -->|Push conf.d/pure.fish| TAG["`Add version tag<br/>(_add-version-tag.yml_)`"]
TAG -->|create: vX.Y.Z tag| RELEASE["`Generate release notes<br/>(_release-notes.yml_)`"]
RELEASE -->|release| SOCIAL["`Post message on social networks<br/>(_social-networks.yml_)`"]