Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
952dd62
docs: update readme to be more concise
polyipseity Jan 18, 2026
47fcaf8
docs: add quickstart and development setup
polyipseity Jan 18, 2026
8f4fe3e
docs: migrate and add plugins and routes docs
polyipseity Jan 18, 2026
7cdf722
docs: deduplicate docs
polyipseity Jan 18, 2026
94591bb
docs: add testing, linting, and CI
polyipseity Jan 18, 2026
5c07603
docs: add Docker and deployment
polyipseity Jan 18, 2026
a27f04e
docs: fix typo
polyipseity Jan 18, 2026
6d20041
docs: improve `.env.example` and add env var docs
polyipseity Jan 18, 2026
c1008bb
docs: document `.env` ignore policy in `env-vars.md`
polyipseity Jan 18, 2026
b783da7
docs: format `CONTRIBUTING.md`
polyipseity Jan 18, 2026
e222955
docs: edit `CONTRIBUTING.md` for wording
polyipseity Jan 18, 2026
a7dfa36
docs: add release automation docs
polyipseity Jan 18, 2026
9b49300
docs(ci): document reusable workflows and hosted-first self-hosted fa…
polyipseity Jan 19, 2026
12fe36e
docs(ci): update workflow docs for shared-step try→fallback pattern a…
polyipseity Jan 21, 2026
d0bf1f3
docs(ci): update workflow docs - detect-quota, hosted-first fallback,…
polyipseity Jan 21, 2026
762f5f7
docs(ci): add TypeDoc generation and publishing; update README, .giti…
polyipseity Jan 25, 2026
a4efb72
docs(ci): add docs-publish workflow; generate & publish TypeDoc; upda…
polyipseity Jan 25, 2026
57cb1dc
ci(workflows): enable Corepack, use numeric node-version and add Node…
polyipseity Jan 25, 2026
882cf88
docs: add script docs (compile, lint:check, fmt) and fix lint command
polyipseity Feb 17, 2026
b693501
ci: update docs publish workflow
polyipseity Feb 17, 2026
9abe148
docs: fix docs links
polyipseity Feb 17, 2026
223a575
ci: fix
polyipseity Feb 17, 2026
3424062
docs: sync documentation with code — clarify test runner and .env han…
polyipseity Feb 17, 2026
96ad1c2
chore: format
polyipseity Feb 17, 2026
04ef9dc
ci: bump action versions
polyipseity Feb 19, 2026
bf5f157
docs: fix readme
polyipseity Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Description: Example of .env file
# Example .env file for local development and tests

# MongoDB URI
# MongoDB (optional)
MONGO_URI=mongodb://localhost:27017/your-database-name

# Auth Plugin
# OpenID Connect (used by the auth plugin)
# AUTH_DISCOVERY_URL should point to the provider's discovery document (/.well-known/openid-configuration)
AUTH_DISCOVERY_URL=https://login.microsoftonline.com/c917f3e2-9322-4926-9bb3-daca730413ca/v2.0/.well-known/openid-configuration
AUTH_CLIENT_ID=b4bc4b9a-7162-44c5-bb50-fe935dce1f5a

# When true, the auth plugin skips remote discovery and verification (useful for local testing)
AUTH_SKIP=true

# Optional runtime controls
NODE_ENV=development
PORT=3000

# Test helpers (optional)
# Provide these only when running integration tests that require a real token/user.
TEST_AUTH_TOKEN=
TEST_AUTH_USER=
68 changes: 68 additions & 0 deletions .github/workflows/docs-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: docs:publish

on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: write
pages: write
id-token: write

jobs:
detect-quota:
# Probe the hosted runner so we can decide whether to use hosted or self-hosted.
runs-on: ubuntu-slim
steps:
- name: Quota probe
id: quota_probe
run: |
echo "probe"

build-and-publish:
needs: detect-quota
# NOTE: do not set `continue-on-error` on detect-quota (see docs)
runs-on: ${{ needs.detect-quota.result == 'success' && 'ubuntu-slim' || 'self-hosted' }}
steps:
- uses: actions/checkout@v6

- name: Use Node
uses: actions/setup-node@v6
with:
node-version: 24

- name: Enable Corepack
run: |
corepack enable
corepack install

- name: Enable Node cache
uses: actions/setup-node@v6
with:
cache: yarn

- name: Install dependencies
run: |
yarn install --immutable

- name: Build project
run: |
yarn build

- name: Generate TypeDoc
run: |
yarn docs:typedoc

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: api-docs
path: docs/api

- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/api
62 changes: 62 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: docs

on:
push:
pull_request:
workflow_dispatch:

Comment on lines +1 to +7
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding concurrency control to this workflow (similar to check.yml and docker.yml) to avoid redundant doc builds when multiple commits are pushed to the same PR. This would save CI resources and reduce noise. Example:

concurrency:
  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.sha }}
  cancel-in-progress: true

Copilot uses AI. Check for mistakes.
permissions:
contents: read

jobs:
detect-quota:
# Probe the hosted runner so we can decide whether to use a hosted
# runner or fall back to self-hosted. The job should fail if quota is exhausted.
runs-on: ubuntu-slim
steps:
- name: Quota probe
id: quota_probe
run: |
echo "probe"

build:
needs: detect-quota
# NOTE: Do not set `continue-on-error: true` on the `detect-quota` job.
# If `continue-on-error` is enabled the job result will always be
# 'success', which defeats detection (we rely on `needs.detect-quota.result`).
runs-on: ${{ needs.detect-quota.result == 'success' && 'ubuntu-slim' || 'self-hosted' }}
steps:
- uses: actions/checkout@v6

- name: Use Node
uses: actions/setup-node@v6
with:
node-version: 24

- name: Enable Corepack
run: |
corepack enable
corepack install

- name: Enable Node cache
uses: actions/setup-node@v6
with:
cache: yarn

- name: Install dependencies
run: |
yarn install --immutable

- name: Build project
run: |
yarn build

- name: Generate TypeDoc
run: |
yarn docs:typedoc

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: api-docs
path: docs/api
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ dist
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Generated TypeDoc output (do not commit generated API docs)
docs/api/
docs/api/**
23 changes: 9 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# How to Contribute

Thanks for reading this, because we really need everyone to follow some collaboration guidelines to make our codebase
maintainable, clean and concise.
Thanks for taking a moment to read this. Following these collaboration guidelines helps keep the codebase maintainable,
clean, and easy to review.

The standard workflow to contribute to the project is as follows:

1. Create an issue to track the things (feature, bug or something else) you are working on. This also allows other
contributors to know what you are working on, and to potentially offer suggestions or help.
2. On the right hand side of the issue page, there is a button that allows you to create a new branch for the issue.
This will automatically create a new branch with the issue number and title. I strongly recommend you to use this
feature instead of creating a branch manually, because it will make it easier to track the issue that you are working
on.
2. On the right hand side of an issue page there is a button to create a branch for that issue. It will create a branch
named from the issue number and title. We recommend using that feature (rather than creating branches manually) to
make it easier to track work against the originating issue.
3. Make your changes in the new branch. Ideally, your commit messages should follow
the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. We will rebase your PR
later if your commits are well-organized and the messages are well-formatted. Otherwise, we may ask you to fix them,
Expand All @@ -34,8 +33,8 @@ but we will try our best to achieve the following goals:
- Use iterative methods on collections instead of loops whenever possible.
- Avoid side effects in a function as much as possible.

That's not only because functional programming is cool, but also because it reduces the complexity of the code, and
makes it easier to reason about the code. For example, you should _never_ do:
Apart from functional programming being cool, this reduces complexity and
makes code easier to reason about. For example, you should _avoid_:

```typescript
const numbers = [1, 2, 3];
Expand Down Expand Up @@ -66,13 +65,10 @@ The general principles are the following:
- If the comment is a change suggestion...
- If it's clear and uncontroversial how to apply the suggestion, you should resolve the comment after you have made
the corresponding changes to the PR.

- If you are not 100% sure that you have applied the suggestion correctly, leave a comment asking it. Do not resolve
the comment in this case.

- If you don't fully understand or agree with the suggestion, reply to the comment with your questions and
rebuttals. Do not resolve the comment in this case.

- If the comment is a clarification request, answer it. Do not resolve the comment in this case. We will either come
back with further questions or suggestions, or close the comment ourselves if we find your answer satisfactory.

Expand All @@ -85,6 +81,5 @@ Please make sure your code passes all automated CI tests (unless under special c
You may trigger them by simply pushing your commits to a branch, or by opening a PR. Reviewing a PR that doesn't pass
tests is a waste of time for everyone involved.

During code review, it is not supposed to happen that we have to keep coming back to your PR, continually finding more
problems more unpolished changes, and having to go through lots of back-and-forth interactions this way. This will only
lead to growing frustration on both ends.
During code review, please try to address issues thoroughly before requesting another round of review. This reduces
unnecessary back-and-forth and speeds up the process for everyone.
79 changes: 45 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,70 @@
# USThing Template API
# template-api

The template repository for USThing backend services, powered by Fastify.
<!-- NOTE: If you use this repository as a template, replace `USThing/template-api` with your own GitHub owner/repo in the badge URLs. -->

## Available Scripts
[![CI](https://github.com/USThing/template-api/actions/workflows/check.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/check.yml) [![Docs](https://github.com/USThing/template-api/actions/workflows/docs-publish.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/docs-publish.yml) [![Release](https://github.com/USThing/template-api/actions/workflows/release.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/release.yml) [![Docs site](https://img.shields.io/badge/docs-site-blue)](https://usthing.github.io/template-api/index.html)

In the project directory, you can run:
A concise Fastify + TypeScript starter used by USThing backend services. This repository provides a minimal, well-tested scaffold with recommended scripts, linting, and CI configuration.

### `yarn run dev`
## Prerequisites

Run the app in development mode; watch the source for changes.
- Node.js (see `engines` in `package.json`)
- Yarn via Corepack

Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
Enable Corepack (recommended) and the Yarn version used by this repo:

### `yarn run compile`
```bash
corepack enable
# `packageManager` field in `package.json` ensures the correct Yarn version is used
```

Run the TypeScript compiler to check for type errors.
## Quickstart (local)

### `yarn run build`, `yarn run start`
```bash
corepack enable
yarn install
yarn build
yarn start
```

- Build the app for production to the `dist` folder.
- Start the built app in production mode.
## Developer workflow

### `yarn run test`
- Start dev mode (watch + Fastify): `yarn dev`
- Run tests (TypeScript tests run via `tsx`): `yarn test`
- Lint and format (auto-fixes): `yarn lint` and `yarn fmt`

Run the tests.
## Automatic API docs

### `yarn run lint`
API docs are generated from source by TypeDoc and published by CI. To generate locally:

Run the linter and fix any issues.
```bash
yarn docs:typedoc
```

`lint:check` does not fix the issues.
Generated docs are placed under `docs/api` (CI publishes these artifacts — do not commit generated files).

### `yarn run fmt`
## Project layout

Run the formatter and fix any issues.
- `src/` — application code (routes, plugins, utils)
- `src/app.ts` — Fastify app and plugin registration
- `src/routes/` — route modules
- `test/` — tests and helpers
- `docs/` — human-authored guides and docs
- `.env.example` — example environment variables

`fmt:check` does not fix the issues.
## Environment

## Environment Variables
Tests and some dev helpers reference `TEST_AUTH_TOKEN` / `TEST_AUTH_USER`. See `docs/env-vars.md` for recommended env variables and CI secret usage. Keep secrets out of the repo and use your CI's secret manager.

For Fastify-level environment variables, please refer to the [fastify-cli documentation](https://github.com/fastify/fastify-cli).
## Contributing

For the application-level environment variables, please refer to the
`.env.example` file. `yarn run dev` automatically loads a `.env` file if it exists.
Follow `CONTRIBUTING.md` (commitlint, lint, tests). The project uses Conventional Commits for releases.

## CI / CD
## Support

This template supports GitHub Actions for CI / CD. The available workflows are:
Open an issue on GitHub using the provided templates for bugs or feature requests.

- Checks / eslint: Run ES Lint to check problems and the format of the code.
- Checks / commitlint: Run Commitlint to check the format of the commit messages.
- Checks / tests: Run unit tests of the project.
- Docker CI / docker: Build the Docker image and push it to the GitHub Container Registry.
- Release Please / release-please: Automatic releasing. See also [release-please](https://github.com/googleapis/release-please).
## Learn more

## Learn More

To learn Fastify, check out the [Fastify documentation](https://fastify.dev/docs/latest/).
- Fastify: <https://www.fastify.dev/>
- Docs folder: `docs/` (detailed guides and examples)
16 changes: 16 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# CI workflows

The repository uses three primary GitHub Actions workflows in `.github/workflows/`:

- `check.yml` — runs on push and pull_request. It probes runner availability (a small `detect-quota` job) and then runs ESLint, commitlint, and tests. Each job uses a hosted-first → self-hosted fallback by selecting `runs-on` based on the probe result.
- `docker.yml` — builds and pushes container images (Buildx). It also probes runner availability and uses a hosted-first fallback. The workflow prepares Docker metadata (tags include sha, branch/ref, and PR tags) and pushes images to `REGISTRY`/`IMAGE_NAME`.
- `release.yml` — runs `googleapis/release-please-action@v4` on pushes to `main`. When a release is created the workflow tags versions and (optionally) builds/pushes images. See `release.yml` for the exact tagging and build steps.

## Key notes

- Hosted-first fallback: jobs use a small probe job (`detect-quota`) and set `runs-on` dynamically so CI prefers `ubuntu-latest` but can fall back to `self-hosted` when needed.
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states that CI jobs prefer ubuntu-latest, but the actual workflow files (check.yml, docs.yml, docs-publish.yml) use ubuntu-slim as the hosted runner label. Update this line to reference ubuntu-slim to match the actual implementation.

Suggested change
- Hosted-first fallback: jobs use a small probe job (`detect-quota`) and set `runs-on` dynamically so CI prefers `ubuntu-latest` but can fall back to `self-hosted` when needed.
- Hosted-first fallback: jobs use a small probe job (`detect-quota`) and set `runs-on` dynamically so CI prefers `ubuntu-slim` but can fall back to `self-hosted` when needed.

Copilot uses AI. Check for mistakes.
- Docker workflow permissions: the docker workflow requests permissions to push packages and to request an `id-token` for registry login; it logs into the registry using the workflow token by default.
- Release workflow: `release-please` creates release PRs or releases and exposes outputs such as `release_created`, `major`, `minor`, `patch`, `tag_name`, and `body` that downstream steps use.
- Tokens: the action uses the default `GITHUB_TOKEN` unless configured to use a PAT; if you need CI checks to run on Release PRs, configure a PAT as described in the action docs.

If a run fails, open the workflow run in GitHub Actions and inspect the primary (hosted) job logs first. Avoid committing generated artifacts; let CI produce and publish them.
Loading