Knope is open to all kinds of contributions—if you want to contribute code there are a few helpful hints.
The docs website is built using starlight.
The source is contained in the docs directory.
The easiest way to find a document to edit is to go to that doc on the website and click on "Edit page"
at the bottom.
npm --prefix docs install, then npm --prefix docs start (or mise run serve-docs).
CI will fail if the docs are not formatted correctly or there are broken relative links.
Use mise run reformat to reformat the docs and mise run build-docs to check for broken links.
mise is a polyglot tool version manager and task runner (like make) which makes it easier to run
common tasks the same way on many platforms. Specifically, you can run the same sorts of commands that CI does to
replicate failures (or prevent them) locally! Start by installing
via your favorite method (like curl https://mise.run | sh).
Then, run mise tasks to see all the available tasks.
Mise also manages tool versions like Node.js, cargo-deny, taplo, and prettier. When you run mise install, it will
install all the tools defined in mise.toml at the specified versions.
This project uses rustfmt to format Rust code, but depends on unstable features (for example, sorting imports).
You need to install the nightly toolchain (for example, with rustup toolchain install nightly) before formatting the
code.
Prettier formats Markdown (via npx)
and Taplo formats TOML. mise install will install
all required tools including Taplo and Prettier. Node.js/NPM will also be installed by mise.
Most of the tests for Knope are end-to-end snapshot tests in the tests directory, where one directory/module
corresponds to one test.
To create a new test:
- Copy a test directory
- Add it as a
modto whatever directory is above it. - Change the contents of
inas required for what you're testing. - Change the contents of
outto match whatinshould look like after running the command (for example, increased versions) - Change
mod.rsto have the setup & command invocation that you want - Run the test with
mise run test(orcargo test) - If the test fails, you can run
SNAPSHOTS=overwrite mise run testto update the snapshots
Most snapshot tests look like this:
#[test]
fn name_of_test() {
TestCase::new(file!()) // Corresponds to a directory you make for this test
.git(&[ // Run Git commands as needed to set up the test
Commit("Initial commit"),
Tag("v0.1.0"),
])
.env("KNOPE_PRERELEASE_LABEL", "alpha") // Set environment variables as needed
.run("prepare-release --prerelease-label alpha") // The command you want to run, omitting the binary name
}This test must be in a "test directory," which has the following:
- An
indirectory with all the files that the command needs to run.TestCase::runwill create a temporary directory, copy the contents ofininto it, and run the command from there. - An
outdirectory, if the command should alter the files inin. - If the command should succeed (exit with a 0 status code):
- A
stdout.logfile if the command produces an output. - A
dryrun_stdout.logfile if.run()should also execute the command with--dry-runto snapshot the output.
- A
- If the command should fail (exit with a non-0 status code):
- A
stderr.logfile if the command should fail and produce an error message. - A
dryrun_stderr.logfile if.run()should also execute the command with--dry-runto snapshot the output.
- A
If neither of stdout.log or stderr.log are present, the command should succeed and produce no output.
TestCase leverages snapbox under the hood, so you can set SNAPSHOTS=overwrite to
update the snapshots if you've made changes to the test.
The setup functions (new, git, env) of TestCase are const,
so you can define them once and reuse them in multiple cases,
when slightly different setups should produce the same results
(for example, in tests/prepare_release/override_prerelease_label/mod.rs).
In addition to the snapshot tests, there are integration tests that exercise real HTTP calls against the GitHub and Gitea APIs. These validate that the HTTP client works correctly end-to-end and are not part of the default test suite. You must run them manually if you want to test a change.
# Run all integration tests (requires all env vars below)
mise run integration-test
# Run only GitHub tests
mise run integration-test-github
# Run only Gitea tests
mise run integration-test-gitea| Variable | Description |
|---|---|
KNOPE_INTEGRATION_GITHUB_TOKEN |
Fine-grained personal access token (see below) |
KNOPE_INTEGRATION_GITHUB_OWNER |
Owner (user or org) of the test repository |
KNOPE_INTEGRATION_GITHUB_REPO |
Name of the test repository |
| Variable | Description |
|---|---|
KNOPE_INTEGRATION_GITEA_TOKEN |
Personal access token for the Gitea instance |
KNOPE_INTEGRATION_GITEA_HOST |
Full URL of the Gitea instance (like https://codeberg.org) |
KNOPE_INTEGRATION_GITEA_OWNER |
Owner (user or org) of the test repository |
KNOPE_INTEGRATION_GITEA_REPO |
Name of the test repository |
Each test pushes its own branch and creates a v0.1.0 release from scratch,
then cleans everything up at the end. The repositories don't need any content.
- Create a dedicated test repository under a user or organization
(something like
knope-dev/knope-integration-tests). It can be public or private. An empty repository (no initial commit) is fine. - Create a fine-grained personal access token scoped to the test repository
with the following permissions:
- Contents: Read and write (for pushing branches, creating tags and releases)
- Pull requests: Read and write
- Create an account on the Gitea instance you want to test with (for example Codeberg).
- Create a dedicated test repository (for example
knope-integration-tests). An empty repository is fine. - Create a personal access token in your Gitea account settings with repository read/write permissions.
Each test:
- Creates a temporary local git repository pre-configured at
version = "0.1.0". - Pushes a test branch (something like
integration-test-release) to the remote. - Runs
knope release, which calls the GitHub/Gitea API to create av0.1.0release and tag on the remote. - Verifies the release exists via the API.
- Deletes the release, tag, and branch to leave the repository clean.
If a test fails partway through, the next run will detect and clean up any leftover resources before proceeding.