Repository navigation
147 lines (141 loc) · 6.66 KB
/
Copy pathci.yml
File metadata and controls
147 lines (141 loc) · 6.66 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
142
143
144
145
146
147
name: CI
on:
push:
branches: [main]
pull_request:
# The release workflow runs every gate here first, and publishes the archive this run built.
workflow_call:
permissions:
contents: read
jobs:
lint:
name: PHP ${{ matrix.php }} syntax
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# The plugin header promises 7.4; the test container runs 8.3.
php: ['7.4', '8.3']
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
- name: Lint every PHP file
run: find . -name '*.php' -not -path './.git/*' -print0 | xargs -0 -n1 -P4 php -l
phpcs:
name: WordPress coding standards
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
coverage: none
tools: composer:v2
- run: composer install --no-interaction --no-progress
# phpcs.xml.dist: WordPress-Extra + PHPCompatibilityWP (7.4-) on the files the archive ships. Every
# phpcs:ignore in the code carries its reason on the same line; the gate honours them, and the second run
# lists what they cover so a review can read it in the log without trusting the annotations.
- run: composer lint
- run: composer lint:all -- --report=source || true
metadata:
name: Plugin metadata is consistent
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Header version, constant and readme stable tag agree
run: |
header=$(sed -n 's/^ \* Version: *//p' contentrain-bridge.php | tr -d '[:space:]')
constant=$(sed -n "s/.*CONTENTRAIN_BRIDGE_VERSION', *'\([^']*\)'.*/\1/p" contentrain-bridge.php)
stable=$(sed -n 's/^Stable tag: *//p' readme.txt | tr -d '[:space:]')
echo "header=$header constant=$constant stable=$stable"
test "$header" = "$constant" && test "$header" = "$stable"
- name: External requests are disclosed in readme.txt
# The plugin calls the GitHub API. A readme that says otherwise is both
# a WordPress.org review failure and an inaccurate privacy statement.
run: |
if grep -rqE 'wp_remote_(get|post|request|head)' includes/; then
grep -q '= External services =' readme.txt
grep -q 'api.github.com' readme.txt
fi
! grep -qiE 'no external (network )?requests|makes no external requests' readme.txt README.md
acceptance:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- run: npm ci --ignore-scripts
- run: npm run test:wordpress
env:
KEEP: 1
# BR-25: requests the host kills mid-step (a child PHP process per request, ended the way a time or
# memory limit ends one). The single tick wp-admin used to send never moves; `Jobs::run` shrinks,
# leaves the attachment that kills out, and ends; a post that kills every request fails the export
# after MAX_ATTEMPTS; a clean export finishes under memory_limit=64M. Right after the fixture, before
# the gates that count this site's content: it adds thirty attachments and removes them again.
- run: npm run test:hang
- run: npm run test:plugin
# B-04: no-plugin case, then Yoast SEO + Redirection. Every exported head
# value is compared with the page WordPress serves, every redirect is
# requested, and @contentrain/verify establishes old/new parity from it.
- run: npm run test:seo
# B-06: T0 inventory through a real export, twelve mutations, an exact
# delta, idempotency and the refusals. Mutates the throwaway site, so it
# runs after the store the other gates read has been copied out.
- run: npm run test:delta
# Everything handed over — store and delta — scanned for planted secrets.
# B-08: a fixture theme's interface text from every source — gettext, HTML,
# echo, JS, widgets, menus, Customizer and five rendered pages. Every
# occurrence is accounted for, one outcome per candidate, keys stable.
- run: npm run test:text
# B-07: services the site is connected to, with evidence and a reconnect
# flag; fake credentials planted in their settings must not leave.
- run: npm run test:integrations
- run: npm run test:secrets
# Repeat delivery: deletions the delta proves are removed, unexplained ones
# refused, a person's edit reported and resolved; replayed into real Git.
- run: npm run test:delivery-git
# B-11: export -> (GitHub) -> Astro build via @contentrain/query, three
# edits, second export, Git diff, rebuild. The GitHub leg runs only when
# the repository secrets exist; otherwise it is reported as skipped.
- run: npm run test:e2e
env:
BRIDGE_TEST_REPO: ${{ secrets.BRIDGE_TEST_REPO }}
BRIDGE_TEST_TOKEN: ${{ secrets.BRIDGE_TEST_TOKEN }}
# B-02: every source WordPress keeps content in, counted in the database
# and split into exported / excluded / unsupported, in both scopes; then
# Bridge's RawIR against a WXR export read by A-03's own parser.
- run: npm run test:coverage
- run: npm run test:store
# The reader gate: this writer's own output, read back with the pinned
# @contentrain/types. It decides whether escape-bearing metadata survives,
# so a reader regression fails here rather than in a customer's store.
- run: npm run test:reader
# Page-builder layout meta and the design system (global settings, Elementor kit, Divi options,
# block templates) reach RawIR; secrets inside them and protected posts' trees do not.
- run: npm run test:builder
- run: npm test
- name: WordPress uninstall cleanup
run: docker compose -f tests/compose.yml run --rm -T cli eval-file /var/www/html/wp-content/plugins/contentrain-bridge/tests/uninstall.php
- run: npm run package
- uses: actions/upload-artifact@v4
with:
name: contentrain-bridge
path: dist/contentrain-bridge.zip
# Contract fixtures from the throwaway test site, for the readers in Migrate and ai.
- uses: actions/upload-artifact@v4
with:
name: contract-fixtures
path: |
tests/.out/coverage/remote/rest-export.json
tests/.out/seo/seo.json
tests/.out/seo/seo-entries.json
- name: Remove acceptance containers
if: always()
run: docker compose -f tests/compose.yml down -v