Repository navigation
141 lines (123 loc) · 5.77 KB
/
Copy pathrelease.yml
File metadata and controls
141 lines (123 loc) · 5.77 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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
name: Release
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
validate:
name: Validate (tests green before publishing)
runs-on: ubuntu-latest
env:
# The pinned conformance release (ADR-0032). Keep identical to ci.yml.
BQ_CONFORMANCE_VERSION: "1.10.0"
BQ_FETCH_SH_SHA256: 8bb6ba567b288fb0ac71a70fd17041b2503df119e01998d76fdad372570bf849
steps:
- uses: actions/checkout@v7
# A tag may land on a commit CI never saw: re-verify the vendored suite against the
# release asset before the results.json below is allowed to claim this version.
- name: Verify the vendored suite against the release asset
run: |
curl -fsSL -o "$RUNNER_TEMP/fetch.sh" \
"https://raw.githubusercontent.com/BabelQueue/conformance/v${BQ_CONFORMANCE_VERSION}/fetch.sh"
echo "${BQ_FETCH_SH_SHA256} $RUNNER_TEMP/fetch.sh" | sha256sum -c -
bash "$RUNNER_TEMP/fetch.sh" --check "$BQ_CONFORMANCE_VERSION" tests/conformance
test "$(tr -d '[:space:]' < tests/conformance/CONFORMANCE_VERSION)" = "$BQ_CONFORMANCE_VERSION"
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: json
coverage: none
tools: composer:v2
- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress
# The run produces the package's own conformance proof (ADR-0032). The runner fails the
# run when a bound transport is missing from `bindings` or its sections are missing.
- name: Run tests (writes results.json)
env:
BQ_CONFORMANCE_RESULTS: ${{ runner.temp }}/results.json
run: vendor/bin/phpunit
- name: Validate results.json against the schema
run: |
python3 -m pip install --quiet jsonschema
python3 -I - "$RUNNER_TEMP/results.json" tests/conformance/schema/results.schema.json conformance-known-gaps.json <<'PY'
import json, re, sys
import jsonschema
results = json.load(open(sys.argv[1]))
jsonschema.validate(results, json.load(open(sys.argv[2])))
gaps = json.load(open(sys.argv[3]))["gaps"]
listed = {(g["section"], g["case"]) for g in gaps}
unreferenced = sorted((g["section"], g["case"]) for g in gaps if not re.search(r"ADR-[0-9]{4}|\.ssot/plans/", g.get("reason", "")))
status = {(s, c): v["status"] for s, cases in results["sections"].items() for c, v in cases.items()}
failed = {k for k, v in status.items() if v == "fail"}
unlisted = sorted(failed - listed)
stale = sorted(k for k in listed if status.get(k) != "fail")
for s, c in unreferenced:
print(f"::error::gap {s}/{c} must reference an ADR-NNNN or a .ssot/plans/ entry in its reason")
for s, c in unlisted:
print(f"::error::fail of {s}/{c} is not listed in conformance-known-gaps.json")
for s, c in stale:
print(f"::error::stale gap: {s}/{c} is listed in conformance-known-gaps.json but is {status.get((s, c), 'not reported')}; remove the entry")
print(f"results.json valid; fail = {len(failed)} (known gaps = {len(failed & listed)}, unlisted = {len(unlisted)}, stale = {len(stale)}, unreferenced = {len(unreferenced)})")
sys.exit(1 if unlisted or stale or unreferenced else 0)
PY
- name: Upload results.json
uses: actions/upload-artifact@v7
with:
name: conformance-results
path: ${{ runner.temp }}/results.json
if-no-files-found: error
coverage:
name: Coverage gate (>=90%)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: json
coverage: pcov
tools: composer:v2
- name: Install dependencies
run: composer update --prefer-dist --no-interaction --no-progress
- name: Tests with coverage
run: vendor/bin/phpunit --coverage-clover=coverage.xml --exclude-group benchmark
- name: Enforce coverage gate
run: php bin/check-coverage.php coverage.xml 90
release:
name: Publish
needs: [validate, coverage]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Download results.json
uses: actions/download-artifact@v8
with:
name: conformance-results
path: conformance-results
- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
generate_release_notes: true
files: conformance-results/results.json
# Packagist normally auto-updates via its GitHub webhook. If you instead set
# PACKAGIST_USERNAME / PACKAGIST_TOKEN secrets, this pings its API.
# Release order matters: publish babelqueue/php-sdk BEFORE its adapters.
- name: Notify Packagist (optional)
env:
PACKAGIST_USERNAME: ${{ secrets.PACKAGIST_USERNAME }}
PACKAGIST_TOKEN: ${{ secrets.PACKAGIST_TOKEN }}
run: |
if [ -n "$PACKAGIST_TOKEN" ]; then
# Credentials travel in the Authorization header (Packagist's recommended
# "Bearer USERNAME:API_TOKEN" scheme), never in the URL, so they cannot
# leak through request logs, proxies or curl error output.
curl -sf -XPOST -H 'Content-Type: application/json' \
-H "Authorization: Bearer ${PACKAGIST_USERNAME}:${PACKAGIST_TOKEN}" \
'https://packagist.org/api/update-package' \
-d '{"repository":"https://github.com/BabelQueue/php-sdk"}'
else
echo "Packagist secrets not set — relying on the Packagist GitHub webhook."
fi