Contributing to UKHSA API Guidelines
July 13, 2026 · View on GitHub
Thank you for your interest in contributing to the UKHSA API Guidelines! This repository contains guidelines and best practices for designing, developing, and maintaining APIs at UKHSA.
Table of Contents
- Contributing to UKHSA API Guidelines
Code of Conduct
Please read the Code of Conduct before contributing.
Getting Started
Setting Up Your Development Environment
1. Fork the repository
If you're an external contributor make sure to fork this project first
2. Clone the repository
If you are a member of the ukhsa-collaboration GitHub organisation, you can clone the repository directly:
git clone https://github.com/ukhsa-collaboration/standards-api.git
cd standards-api
Otherwise, if you are an external contributor, you can clone your fork:
git clone https://github.com/YOUR-USERNAME/standards-api.git
cd standards-api
3. Install dependencies
Before you begin, ensure you have the following installed:
| Tool | Version | Description |
|---|---|---|
| Node.js / npm | Latest LTS | Required for packaging and testing the linting ruleset. |
| Vacuum | Latest | CLI for running the UKHSA linting ruleset. |
You can install npm and Vacuum CLI using your system's package manager or download them from their respective websites.
You can verify your installations with:
node --version
npm --version
vacuum --version
install the required dependencies with the following command:
npm install
4. Compile TypeScript
To transpile TypeScript files to JavaScript:
npm run build
Build the Vacuum-compatible functions (used by the linter at runtime) with:
npm run build:functions:cjs
This generates .js files in ./dist and produces Vacuum wrapper functions in ./dist/functions.
Understanding the Repository Structure
/docs/- Documentation content written in Markdown/docs/api-design-guidelines/- API design guidelines content/docs/linting-rules/- Documentation for API linting rules/example/- Example OpenAPI specifications/src/functions/- JavaScript functions used by the linting rulesukhsa.oas.rules.yml- UKHSA-specific linting ruleszalando.oas.rules.yml- Zalando API guidelines rules
Contributing Process
Finding Issues to Work On
- Check the Issues section for open tasks
- Look for issues tagged with
good first issueif you're new to the project
Signed Commits
All commits to this repository MUST be signed with a GPG key to verify the committer's identity. This helps ensure the security and integrity of the codebase.
To set up signed commits:
1. Generate a GPG key (if you don't have one already)
gpg --full-generate-key
2. Configure Git to use your GPG key
# List your GPG keys to get the ID
gpg --list-secret-keys --keyid-format=long
# Configure Git to use your key (replace KEY_ID with your GPG key ID)
git config --global user.signingkey KEY_ID
# Enable commit signing by default
git config --global commit.gpgsign true
3. Add your GPG key to GitHub
- Export your public key:
gpg --armor --export KEY_ID - Add this key to your GitHub account under Settings > SSH and GPG keys
4. Sign your commits
# If you've enabled signing by default, just commit normally
git commit -m "Your commit message"
# Or explicitly sign a commit
git commit -S -m "Your commit message"
For more information, see GitHub's documentation on signing commits.
Opening New Issues
Before opening a new issue:
- Search existing issues to avoid duplicates
- Use issue templates if available
- Be clear and specific about:
- What needs to be changed/added
- Why it's important
- Any relevant context
Making Changes
-
Create a new branch for your work:
git checkout -b feature/your-feature-nameor
git checkout -b fix/issue-you-are-fixing -
Make your changes following the development guidelines below.
-
Test your changes (see Testing Guidelines)
-
Commit your changes with clear commit messages and sign them (see Signed Commits):
We follow the Conventional Commits specification for commit messages. This provides a standardised format that makes the commit history more readable and enables automated tools for versioning and changelog generation.
The commit message should be structured as follows:
Subject:
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: "ruleset" for changes to linting rules or should be omitted otherwise
│
└─⫸ Commit Type: build|docs|feat|fix|perf|refactor|revert|test
Body:
<detailed description of changes made in the commit> (wrap at 72 characters)
Footer:
<any additional information, such as references or issue numbers>
| Type | Description | SemVer Impact |
|---|---|---|
build | A change to CI configuration files and scripts, or that affect the build system or external dependencies | None (unless functionality is affected) |
docs | Documentation only changes | None |
feat | A new feature | MINOR (x.Y.z) |
fix | A bug fix | PATCH (x.y.Z) |
perf | A code change that improves performance | PATCH (x.y.Z) |
refactor | A code change that improve code quality but have no functional effect | None (unless functionality is affected) |
revert | Reverts a previous commit | Depends on the reverted change |
test | Adding or correcting tests | None |
Note
A commit that has a footer BREAKING CHANGE:, or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type.
Example
git commit -m "feat(scope): add rate limiting recommendations"
or with more details:
git commit -m "fix(scope): correct validation for API versioning
Resolves issue #123"
Pull Request Process
-
Update your branch/fork with the latest from upstream:
If you are an external contributor, you will need to add the upstream repository as a remote, see fork the repository for more details.
Make sure to keep your fork up to date with the main repository by syncing your fork with the upstream repository.
If you are a member of the
ukhsa-collaborationGitHub organisation, you can update your branch with the latest frommainwith the following commands:git fetch git rebase origin/mainNote
This repository maintains a linear commit history.
Always use
rebaseinstead ofmergewhen keeping your branch up to date with themainbranch. -
link PR to issue if you are solving one.
-
Push your changes to your branch/fork:
If its your first push to the branch you can use:
git push -u origin your-branch-nameor if you have already pushed to the branch you can use:
git push origin your-branch-nameIf you've previously pushed your branch and have rebased, you may need to force push:
git push --force-with-lease origin your-branch-name -
Create a Pull Request from your branch/fork to the main repository
if you are a member of the
ukhsa-collaborationGitHub organisation, you can create a pull request directly from your branch.If you are an external contributor, you can create a pull request from your fork to the main repository.
-
Fill in the PR template with all relevant information
-
Request a review from maintainers
-
Address any feedback provided during the review process. When making changes to address feedback:
- Make additional commits while the PR is under review
- Once approved, consider squashing related commits for a cleaner history
- Use descriptive commit messages that explain the changes
-
Prepare for merge: Before your PR is merged, make sure your branch is up to date with the latest changes from the
mainbranch.You should be able to do this from the GitHub UI or from the command line.
If you are an external contributor, you can use the following commands to keep your branch up to date with the
mainbranch:# from your feature branch git fetch upstream git rebase upstream/mainIf you are a member of the
ukhsa-collaborationGitHub organisation, you can use the following commands to keep your branch up to date with themainbranch:# from your feature branch git fetch git rebase origin/mainOccasionally you may also be asked to squash your commits to maintain a clean project history. If you are an external contributor, you can use the following commands to squash your commits:
# Squash multiple commits into one git rebase -i HEAD~{number of commits to squash} # and follow the instructions in the editor to squash your commits # or squash all commits since branching from main git fetch upstream git rebase -i upstream/mainIf you are a member of the
ukhsa-collaborationGitHub organisation, you can use the following commands to squash your commits:# Squash multiple commits into one git rebase -i HEAD~{number of commits to squash} # and follow the instructions in the editor to squash your commits # or squash all commits since branching from main git fetch git rebase -i origin/mainNote
This repository maintains a linear commit history.
Always use
rebaseinstead ofmergewhen keeping your branch up to date with themainbranch (see previous step). -
Merge the PR: Once approved and all status checks have passed, including the branch being up to date with main, you can trigger a
fast-forwardmerge by adding thefast-forwardlabel to the pull request. This will initiate an automated, permission-checkedfast-forwardmerge process. Only users withwriteoradminpermissions on the repository can trigger this action. If you're an external contributor, a maintainer may need to do this for you, as the automated process only responds to this tag when it has been added by an authorised user.The merge process is handled by our two-phase GitHub Actions workflow:
- Phase 1: Checks your permissions and PR status when you add the
fast-forwardlabel. - Phase 2: If you have sufficient permissions and the PR is mergeable, the workflow will perform a true
fast-forwardmerge and post the result as a comment on the PR.
If you do not have permission, the workflow will notify you and request you contact a member of the API Standards Team.
Information on why we use a non-standard GitHub merge process can be found in the
fast-forward-pr-merge-init.mddocumentation. - Phase 1: Checks your permissions and PR status when you add the
-
Congratulations! 🎉🎉 You've successfully contributed to the UKHSA API Guidelines, any documentation changes will be automatically deployed to the UKHSA Organisation standards site.
Development Guidelines
Documentation Standards
- Write in clear, concise language suitable for technical audiences.
- Use RFC2119 keywords (MUST, SHOULD, MAY, etc.) correctly to indicate requirement levels.
- Include practical examples where appropriate.
- Follow Markdown best practices for formatting.
- Place documentation in the appropriate section of the
/docs/directory. - Preview changes locally using
npm startbefore submitting.
Linting Rules Development
Vacuum is the supported CLI for running the UKHSA ruleset. Rules are authored in the ruleset format that Vacuum consumes.
-
For rule syntax and guidance, see Custom Rulesets.
-
UKHSA specific rules are defined in the
ukhsa.oas.rules.ymlfile. -
Rules should be clearly categorised as MUST, MUST NOT, SHOULD, SHOULD NOT, MAY, MAY NOT and matched against the appropriate severity level.
Rule Category Severity Level MUST errorMUST NOT errorSHOULD warnSHOULD NOT warnMAY infoorhintMAY NOT infoorhint -
Each rule should have a corresponding documentation file in the relevant folder
/docs/linting-rules/must/,/docs/linting-rules/should/or/docs/linting-rules/may/. -
Every rule definition MUST set
documentationUrlso Vacuum outputs can surface a deep link to the matching documentation page (for examplehttps://ukhsa-collaboration.github.io/standards-org/api-design-guidelines/linting-rules/must/<rule-name>/). -
Include references to the relevant sections of the API guidelines.
-
Test the rules that you have created or modified.
-
For information on how to use these rules with your API project, check the How to use the rules documentation section.
Testing Guidelines
-
Test new rules against the example specifications in the
/example/directory (you may need to modify the example definition to test your rules). Vacuum auto-discovers./vacuum.conf.yamlfrom the working directory.vacuum lint example/example.1.0.0.oas.yml -
Verify that rules produce the expected results for both valid and invalid API definitions.
-
Add automated tests for each new rule:
- Define the rule in
ukhsa.oas.rules.yml. - Create a Jest test file in:
src/__tests__/rules/<rule-name>.test.ts - Use the Vacuum test helper to run the rule against inline specs:
import testRule from '../__helpers__/vacuum-helper.js'; testRule('<rule-name>', [ { name: 'passes when condition is met', document: ` openapi: 3.0.0 info: title: My API version: 1.0.0 paths: {} `, errors: [], }, { name: 'fails when condition is not met', document: ` openapi: 3.0.0 info: title: Bad API version: 1.0.0 paths: {} `, errors: [{ code: '<rule-name>' }], }, ]);
- Define the rule in
-
Run the rule tests:
npm run test -
For documentation, serve the site locally (see Viewing the Guidelines Locally)
Viewing the Guidelines Locally
The documentation is organised into various markdown files under the docs/ directory. You can navigate and edit these files directly. To preview the documentation as it will appear on the website:
npm run start
This uses docker to host your docs under the hood. After running this script you can view your docs by going to http://localhost:8080/api-design-guidelines/.
While this script is running it will notice when files change and update them so you can see how they look live.
Documentation Deployment
The documentation is continuously deployed from the main branch by GitHub Actions, using the workflow defined in /.github/workflows/publish-guidelines.yml which will trigger a deployment of the main standards-org repository
When documentation changes are merged into the main branch, the documentation site is automatically updated and re-published on GitHub Pages.
Ruleset Release
When updating rules, follow these steps to ensure proper release and distribution:
1. Update the Version Number
- Update the version number in
package.jsonfollowing Semantic Versioning principles:MAJORversion for incompatible changesMINORversion for added functionality in a backwards compatible mannerPATCHversion for backwards compatible bug fixes
2. Document the Changes
- Document all changes in a
CHANGELOG.mdfile, including:- New rules added
- Existing rules modified
- Rules deprecated or removed
- Bug fixes
3. Create a Release
- Trigger the
/.github/workflows/publish-rules.ymlworkflow to create a release using GitHub Actions. - Add detailed release notes.
- Tag the release with the version number.
Note
Only maintainers with the appropriate permissions can publish new releases of the ruleset npm package.
Thank you for contributing to improving API design and development practices across the UKHSA!