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

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:

ToolVersionDescription
Node.js / npmLatest LTSRequired for packaging and testing the linting ruleset.
VacuumLatestCLI 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 rules
  • ukhsa.oas.rules.yml - UKHSA-specific linting rules
  • zalando.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 issue if 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:

  1. Search existing issues to avoid duplicates
  2. Use issue templates if available
  3. Be clear and specific about:
    • What needs to be changed/added
    • Why it's important
    • Any relevant context

Making Changes

  1. Create a new branch for your work:

    git checkout -b feature/your-feature-name
    

    or

    git checkout -b fix/issue-you-are-fixing
    
  2. Make your changes following the development guidelines below.

  3. Test your changes (see Testing Guidelines)

  4. 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>
TypeDescriptionSemVer Impact
buildA change to CI configuration files and scripts, or that affect the build system or external dependenciesNone (unless functionality is affected)
docsDocumentation only changesNone
featA new featureMINOR (x.Y.z)
fixA bug fixPATCH (x.y.Z)
perfA code change that improves performancePATCH (x.y.Z)
refactorA code change that improve code quality but have no functional effectNone (unless functionality is affected)
revertReverts a previous commitDepends on the reverted change
testAdding or correcting testsNone

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

  1. 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-collaboration GitHub organisation, you can update your branch with the latest from main with the following commands:

    git fetch
    git rebase origin/main
    

    Note

    This repository maintains a linear commit history.

    Always use rebase instead of merge when keeping your branch up to date with the main branch.

  2. link PR to issue if you are solving one.

  3. Push your changes to your branch/fork:

    If its your first push to the branch you can use:

    git push -u origin your-branch-name
    

    or if you have already pushed to the branch you can use:

    git push origin your-branch-name
    

    If you've previously pushed your branch and have rebased, you may need to force push:

    git push --force-with-lease origin your-branch-name
    
  4. Create a Pull Request from your branch/fork to the main repository

    if you are a member of the ukhsa-collaboration GitHub 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.

  5. Fill in the PR template with all relevant information

  6. Request a review from maintainers

  7. 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
  8. Prepare for merge: Before your PR is merged, make sure your branch is up to date with the latest changes from the main branch.

    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 main branch:

    # from your feature branch
    git fetch upstream
    git rebase upstream/main
    

    If you are a member of the ukhsa-collaboration GitHub organisation, you can use the following commands to keep your branch up to date with the main branch:

    # from your feature branch
    git fetch
    git rebase origin/main
    

    Occasionally 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/main
    

    If you are a member of the ukhsa-collaboration GitHub 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/main
    

    Note

    This repository maintains a linear commit history.

    Always use rebase instead of merge when keeping your branch up to date with the main branch (see previous step).

  9. 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-forward merge by adding the fast-forward label to the pull request. This will initiate an automated, permission-checked fast-forward merge process. Only users with write or admin permissions 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-forward label.
    • Phase 2: If you have sufficient permissions and the PR is mergeable, the workflow will perform a true fast-forward merge 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.md documentation.

  10. 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 start before 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.yml file.

  • Rules should be clearly categorised as MUST, MUST NOT, SHOULD, SHOULD NOT, MAY, MAY NOT and matched against the appropriate severity level.

    Rule CategorySeverity Level
    MUSTerror
    MUST NOTerror
    SHOULDwarn
    SHOULD NOTwarn
    MAYinfo or hint
    MAY NOTinfo or hint
  • 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 documentationUrl so Vacuum outputs can surface a deep link to the matching documentation page (for example https://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.yaml from 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:

    1. Define the rule in ukhsa.oas.rules.yml.
    2. Create a Jest test file in:
      src/__tests__/rules/<rule-name>.test.ts
      
    3. 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>' }],
        },
      ]);
      
  • 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.json following Semantic Versioning principles:
    • MAJOR version for incompatible changes
    • MINOR version for added functionality in a backwards compatible manner
    • PATCH version for backwards compatible bug fixes

2. Document the Changes

  • Document all changes in a CHANGELOG.md file, including:
    • New rules added
    • Existing rules modified
    • Rules deprecated or removed
    • Bug fixes

3. Create a Release

  • Trigger the /.github/workflows/publish-rules.yml workflow 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!