Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
98 changes: 98 additions & 0 deletions .github/DOCUMENTATION_SYNC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Documentation sync: PR checklist, labels, drift CI

Public docs here track Convoy server behavior for **`convoy.json`**, env, CLI, and metrics. Use this when reviewing or writing PRs.

## PR template checklist

The [pull request template](pull_request_template.md) asks authors to update the relevant **config / env / CLI / metrics / Grafana** pages or mark the line **N/A** with a short reason (e.g. copy-only change, dashboard screenshot swap, internal nav). N/A is allowed so trivial PRs are not blocked; anything config-adjacent still needs an explicit call.

Suggested entry points:

- **Config & env:** `docs/deployment/configuration.mdx` (and deployment pages that repeat env names).
- **CLI:** `docs/cli-file/convoy.mdx` (and CLI-adjacent guides).
- **Metrics / Grafana:** `docs/product-manual/metrics.mdx`, `docs/resources/telemetry.mdx` where scrape paths and env overlap.

## Labels

Labels are not defined in-repo; they live in org or repo settings on GitHub. For docs-sync work:

- **`documentation`:** docs-only or mostly docs.
- **`config`**, **`metrics`**, **`cli`**, etc.: optional; helps when many PRs land at once.

Authors and reviewers set labels manually.

## Automation modes

Three independent ways docs can stay aligned with the server. Use one or more.

### Mode A: Docs PR drift checks

**What it does:** On PRs that change docs or drift tooling, CI runs static checks in this repo only. It does not clone the Convoy server or regenerate JSON.

**Implemented here:** Yes. [docs-drift.yml](workflows/docs-drift.yml) runs when the diff touches `docs/**`, `.github/workflows/docs-drift.yml`, `.github/scripts/docs-drift-check.sh`, `.github/docs-drift/**`, `.github/pull_request_template.md`, or `.github/DOCUMENTATION_SYNC.md`. It fails if:

- Any **forbidden substring** from [`.github/docs-drift/forbidden-patterns.txt`](docs-drift/forbidden-patterns.txt) appears under `docs/` (wrong config filenames, deprecated env naming, etc.).
- **Consistency checks** fail (e.g. `configuration.mdx` must still link to `config/config.go`, state CLI > env > `convoy.json` precedence exactly once, and key metrics env names must appear in both the configuration reference and `metrics.mdx`).

Prose under `docs/` stays human-authored.

### Mode B: Generated reference sync (receive)

**What it does:** A workflow checks out the Convoy repo, runs `make docs-generated`, copies `docs/generated/*` into **`docs/generated/convoy/`**, then opens or updates one long-lived PR limited to those paths. Maintainers merge it like any other PR.

**Implemented here:** Yes. [convoy-docs-sync-receive.yml](workflows/convoy-docs-sync-receive.yml):

- **Triggers:** `repository_dispatch` with type **`convoy_docs_sync`**; **`workflow_dispatch`** with optional input `convoy_ref` (default `main`).
- **PR branch:** `chore/sync-convoy-generated-docs` (reused; not deleted after merge).
- **PR title:** `chore(docs): sync Convoy generated reference artifacts`
- **Committed paths:** `docs/generated/**` only (see workflow `add-paths`).

**Secrets (convoy-website)**

| Secret | Required? | Purpose |
|--------|-----------|---------|
| `CONVOY_CHECKOUT_TOKEN` | **Optional** | If set, used as `token` for the second `actions/checkout` of `{owner}/convoy`. If unset, the job uses `GITHUB_TOKEN`, which is enough when Convoy is **public** (or readable by that token). Use a PAT when Convoy is **private** or the default token cannot read it. |

No secret is required on convoy-website **to receive** a dispatch; GitHub authenticates the incoming event.

**Secrets / token (Convoy repo, caller)**

To call **`POST /repos/{owner}/{repo}/dispatches`** on **this** repo from Convoy CI or a script, use a PAT or GitHub App token allowed for that endpoint. Typical setup:

- Fine-grained or classic PAT with access to **convoy-website** (at minimum **Contents** / repository dispatch on that repo; classic `repo` on the website repo also works).
- Store it on the **Convoy** repo, e.g. **`CONVOY_WEBSITE_DISPATCH_TOKEN`**.
- Dispatch from Convoy:

```bash
curl -sS -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${CONVOY_WEBSITE_DISPATCH_TOKEN}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/frain-dev/convoy-website/dispatches" \
-d '{"event_type":"convoy_docs_sync","client_payload":{"convoy_ref":"main"}}'
```

The URL assumes **frain-dev** as owner; change the path for a fork. Optional `client_payload.convoy_ref` overrides the ref (same as the workflow `workflow_dispatch` input).

**Not in this repo:** A Convoy-side job that runs the `curl` (or `peter-evans/repository-dispatch`) after `main` updates. Add that in **convoy** to auto-trigger sync from server merges.

### Mode C: Hands-off pipeline (caller + optional auto-merge)

**Operationally:** (1) Convoy CI (or another process) dispatches on every relevant server change so Mode B runs without **Run workflow**. (2) Optionally, generated-docs PRs auto-merge when checks pass.

**Implemented here:** **Partially.** Only the receive side (Mode B) lives here. Auto-dispatch after server merges belongs in **convoy**. **Auto-merge** for the generated PR is not implemented here unless added on purpose.

Extending drift checks to assert on `docs/generated/convoy/` is optional follow-up.

When you rename or remove an env var or config file on the server, update docs **and** add the old string to `forbidden-patterns.txt` so CI catches regressions.

## Related files

| Item | Path |
|------|------|
| PR template | [`.github/pull_request_template.md`](pull_request_template.md) |
| Mode A workflow | `.github/workflows/docs-drift.yml` |
| Mode B workflow | `.github/workflows/convoy-docs-sync-receive.yml` |
| Mirrored generated artifacts | `docs/generated/convoy/` (see `docs/generated/README.md`) |
| Check script | `.github/scripts/docs-drift-check.sh` |
| Forbidden literals | `.github/docs-drift/forbidden-patterns.txt` |
19 changes: 19 additions & 0 deletions .github/docs-drift/forbidden-patterns.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Substrings that must not appear under docs/ (stale or incorrect product docs).
# Lines starting with # and blank lines are ignored.
# Extend this list when env vars or filenames are renamed or removed in the Convoy server.

# Primary server config file is convoy.json, not YAML.
convoy.yaml
convoy.yml

# Wrong env naming (metrics use CONVOY_METRICS_* in config/config.go).
CONVOY_PROMETHEUS_ENABLED
CONVOY_PROMETHEUS_BACKEND

# Wrong DB pool env names (see CONVOY_DB_MAX_OPEN_CONN / CONVOY_DB_MAX_IDLE_CONN).
CONVOY_DB_MAX_CONNECTIONS
CONVOY_DB_MAX_CONNECTION

# Inverted or outdated precedence wording (canonical line uses cli > env > file).
environment variables` > `cli flags
environment variables > cli flags
12 changes: 12 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Summary

<!-- What does this PR change and why? -->

## Checklist

- [ ] **Config / env / CLI / metrics / Grafana docs** — Updated [`docs/deployment/configuration.mdx`](docs/deployment/configuration.mdx), [`docs/cli-file/convoy.mdx`](docs/cli-file/convoy.mdx), [`docs/product-manual/metrics.mdx`](docs/product-manual/metrics.mdx), and related pages **or** explicitly **N/A** (brief reason in a PR comment). See [Documentation sync (maintainer guide)](.github/DOCUMENTATION_SYNC.md).
- [ ] **Tests / preview** — Docs PRs: Mintlify preview (if applicable) looks correct.

## Labels (optional)

For docs-only or config-doc alignment work, consider **`documentation`** plus topic labels your team uses (**`config`**, **`metrics`**, **`cli`**, etc.) so these PRs are easy to filter.
67 changes: 67 additions & 0 deletions .github/scripts/docs-drift-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Docs drift guard: forbidden substrings + lightweight cross-file consistency.
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
DOCS="$ROOT/docs"
PATTERNS_FILE="$ROOT/.github/docs-drift/forbidden-patterns.txt"
CONFIG_MDX="$DOCS/deployment/configuration.mdx"
METRICS_MDX="$DOCS/product-manual/metrics.mdx"
FEATURE_FLAGS_MDX="$DOCS/resources/feature-flags.mdx"

fail() {
echo "docs-drift-check: ERROR: $*" >&2
exit 1
}

if [[ ! -d "$DOCS" ]]; then
fail "docs directory missing: $DOCS"
fi

echo "== Forbidden patterns ($PATTERNS_FILE) =="
if [[ ! -f "$PATTERNS_FILE" ]]; then
fail "forbidden patterns file missing"
fi
while IFS= read -r line || [[ -n "$line" ]]; do
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
pattern="$line"
if grep -rIlF --include='*.mdx' --include='*.md' "$pattern" "$DOCS" 2>/dev/null | grep -q .; then
echo "Matched forbidden pattern (fixed-string): $pattern" >&2
grep -rInF --include='*.mdx' --include='*.md' "$pattern" "$DOCS" >&2 || true
fail "remove or update stale pattern above"
fi
done <"$PATTERNS_FILE"

echo "== Required anchors (configuration.mdx) =="
[[ -f "$CONFIG_MDX" ]] || fail "missing $CONFIG_MDX"

require_in_file() {
local file="$1"
local needle="$2"
local msg="$3"
grep -qF "$needle" "$file" || fail "$msg (expected in $file): $needle"
}

require_in_file "$CONFIG_MDX" "frain-dev/convoy/blob/main/config/config.go" \
"configuration doc must link to server config source"
require_in_file "$CONFIG_MDX" 'cli flags` > `environment variables` > `convoy.json' \
"configuration doc must document CLI > env > convoy.json precedence"

count="$(grep -cF 'cli flags` > `environment variables` > `convoy.json' "$CONFIG_MDX" || true)"
[[ "$count" -eq 1 ]] || fail "precedence line must appear exactly once in configuration.mdx (count=$count)"

echo "== Metrics / feature-flag naming consistency =="
[[ -f "$METRICS_MDX" ]] || fail "missing $METRICS_MDX"
[[ -f "$FEATURE_FLAGS_MDX" ]] || fail "missing $FEATURE_FLAGS_MDX"

# Keep metrics onboarding aligned with canonical env names in configuration.mdx.
for sym in CONVOY_METRICS_ENABLED CONVOY_METRICS_BACKEND CONVOY_METRICS_QUERY_TIMEOUT; do
require_in_file "$CONFIG_MDX" "$sym" "configuration reference must mention $sym"
require_in_file "$METRICS_MDX" "$sym" "metrics doc must mention $sym"
done
require_in_file "$CONFIG_MDX" "CONVOY_METRICS_SAMPLE_TIME" "configuration reference must mention CONVOY_METRICS_SAMPLE_TIME"

require_in_file "$METRICS_MDX" "CONVOY_ENABLE_FEATURE_FLAG" "metrics doc must document feature flag env for prometheus"
require_in_file "$FEATURE_FLAGS_MDX" "CONVOY_ENABLE_FEATURE_FLAG" "feature flags doc must document CONVOY_ENABLE_FEATURE_FLAG"

echo "docs-drift-check: OK"
90 changes: 90 additions & 0 deletions .github/workflows/convoy-docs-sync-receive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Receives repository_dispatch convoy_docs_sync from the Convoy server repo (or manual
# workflow_dispatch), regenerates docs on convoy main (or requested ref), copies
# docs/generated/* into docs/generated/convoy/, then opens or updates PR branch
# chore/sync-convoy-generated-docs via peter-evans/create-pull-request.
name: Receive Convoy docs sync

on:
repository_dispatch:
types:
- convoy_docs_sync
workflow_dispatch:
inputs:
convoy_ref:
description: "Convoy repo ref (branch, tag, or SHA)"
required: false
default: main

permissions:
contents: write
pull-requests: write

concurrency:
group: convoy-docs-sync-receive-${{ github.repository }}
cancel-in-progress: true

jobs:
sync:
runs-on: ubuntu-latest
env:
CONVOY_REF: ${{ github.event.inputs.convoy_ref || github.event.client_payload.convoy_ref || 'main' }}
steps:
- name: Check out convoy-website
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: main

- name: Check out Convoy server
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: ${{ github.repository_owner }}/convoy
ref: ${{ env.CONVOY_REF }}
path: convoy-src
# Prefer PAT when Convoy is private or GITHUB_TOKEN cannot read it; else default token (public convoy).
token: ${{ secrets.CONVOY_CHECKOUT_TOKEN || github.token }}

- name: Set up Go
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6
with:
go-version: "1.25.7"

- name: Cache Go modules (Convoy)
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-convoy-docs-sync-receive-${{ hashFiles('convoy-src/go.sum') }}

- name: Download modules
working-directory: convoy-src
run: go mod download

- name: Regenerate reference artifacts
working-directory: convoy-src
run: make docs-generated

- name: Copy generated artifacts into website tree
run: |
rm -rf docs/generated/convoy
mkdir -p docs/generated/convoy
cp -R convoy-src/docs/generated/. docs/generated/convoy/

- name: Open or update PR when drift exists
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
with:
commit-message: "chore(docs): sync Convoy generated reference artifacts"
title: "chore(docs): sync Convoy generated reference artifacts"
body: |
This PR was opened or updated automatically after a **`convoy_docs_sync`** `repository_dispatch` (or a manual run of this workflow).

**Source:** `${{ github.repository_owner }}/convoy` at ref **`${{ env.CONVOY_REF }}`**, `make docs-generated`, mirrored under `docs/generated/convoy/`.

**What to do:** Review the diff; if it matches the config/CLI state you expect on Convoy `main`, merge.

**Branch:** `chore/sync-convoy-generated-docs` is reused and updated when new drift appears.

Maintainer reference: **Automation modes** → **Mode B — Generated reference sync (receive)** in `.github/DOCUMENTATION_SYNC.md` (dispatch token on the Convoy repo, optional `CONVOY_CHECKOUT_TOKEN` here).
branch: chore/sync-convoy-generated-docs
base: main
delete-branch: false
add-paths: |
docs/generated/**
23 changes: 23 additions & 0 deletions .github/workflows/docs-drift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Docs drift

on:
pull_request:
paths:
- 'docs/**'
- '.github/workflows/docs-drift.yml'
- '.github/scripts/docs-drift-check.sh'
- '.github/docs-drift/**'
- '.github/pull_request_template.md'
- '.github/DOCUMENTATION_SYNC.md'

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run docs drift checks
run: bash .github/scripts/docs-drift-check.sh
Loading
Loading