-
Notifications
You must be signed in to change notification settings - Fork 4
99 lines (95 loc) · 4.57 KB
/
Copy pathapi-diff.yml
File metadata and controls
99 lines (95 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
name: API diff
#
# Breaking-change gate on the OpenAPI contract (#196, #202).
#
# Cryptify's routes are unversioned, so there is no way to keep an old shape
# running next to a new one: any breaking change to api-description.yaml
# breaks the clients pinned to it (pg-js, pg-dotnet, the add-ins). This job
# diffs the PR's spec against the branch it targets and fails on anything
# oasdiff rates WARN or ERR.
#
# To land a genuinely breaking change: add a new versioned route, leave the
# old one in place, and deprecate it once privacybydesign/postguard-ops#64
# telemetry shows nobody is calling it. A versioned route added beside the
# unversioned one reads as additive, so this gate passes it. Reach for that
# before reaching for err-ignore.
#
# Why WARN and not ERR
# --------------------
# `fail-on: ERR` left several of the changes this contract forbids passing
# silently, because oasdiff rates them WARN. Measured on this spec against
# oasdiff v1.26.1:
#
# mutation fail-on ERR fail-on WARN
# optional response property removed passes fails
# optional response property renamed passes fails
# request parameter removed passes fails
# request property removed passes fails
# request parameter constraint narrowed passes fails
# response enum value added passes fails
#
# The first five are the "no removing or narrowing" rule, and at ERR the
# request side of it and the optional half of the response side were both
# unguarded. This spec marks most fields `required`, which does make a removed
# *required* response property an ERR, but that is not the whole rule.
#
# WARN adds 30 checks on top of ERR's 212. All but one are changes the contract
# already forbids (request-parameter-removed, request-property-removed,
# response-body-media-type-schema-removed, the constraint-narrowing *-set
# family). The exception is the sixth row above,
# response-property-enum-value-added: adding a value to
# UploadSessionNotFound.reason or PayloadTooLarge.limit fails this gate even
# though a wider response enum is additive on paper. That is deliberate.
# Today's consumers do tolerate it (pg-js reads `reason` as
# `parsed.reason ?? 'unknown'`), but nothing stops a future client from
# switching on those codes, and a gate that asks for a decision beats one that
# passes it silently. It is the one rule here that only WARN enforces, so it is
# also the first casualty of a revert to ERR; mod api_gate_tests in
# src/main.rs pins it.
#
# There is no standing way to switch just that check off, so do not go looking
# for one: warn-ignore takes a file whose lines must each contain the whole
# rendered change text, per operation and naming the new value, not a check id.
# CLAUDE.md has the details and the x-extensible-enum trade-off.
#
# Two more checks are opt-in: they rate ERR but only run when named, so they
# need the include-checks input below. Without it, changing a 401 to a 403 and
# dropping an enum value from a response both pass. mod api_gate_tests reads
# this file and asserts fail-on and include-checks are the constants it pins,
# so editing one side alone fails `cargo test`.
#
# There is deliberately no `on: paths:` filter. A path-filtered job reports no
# status on the PRs it skips, so as a required check it would leave every PR
# that does not touch the spec pending forever. The job is two checkouts and
# one container, so it just always runs.
#
on:
pull_request:
permissions:
contents: read
jobs:
breaking-changes:
name: oasdiff breaking changes
runs-on: ubuntu-latest
steps:
- name: Check out the pull request
uses: actions/checkout@v6
- name: Check out the base spec
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.base.sha }}
path: base
- name: Diff the spec against the base branch
uses: oasdiff/oasdiff-action/breaking@v0.1.10
with:
base: base/api-description.yaml
revision: api-description.yaml
fail-on: WARN
# Both of these rate ERR but are opt-in, so they do not run unless
# named: a changed non-success status (401 -> 403) and an enum value
# dropped from a response property.
include-checks: response-non-success-status-removed,response-property-enum-value-removed
# Do not upload the spec to oasdiff.com for a side-by-side review
# page. The default is `true`; detection and annotations work
# without it, so nothing leaves CI.
review: false