-
Notifications
You must be signed in to change notification settings - Fork 8
186 lines (170 loc) · 7.22 KB
/
Copy pathci.yaml
File metadata and controls
186 lines (170 loc) · 7.22 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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
name: CI
on:
push:
branches: [ main ]
# Run on every PR regardless of base branch so stacked PRs get CI too.
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lint-and-build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run linting
run: yarn lint
- name: Build project
run: yarn build
test:
needs: lint-and-build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20, 22]
env:
# Backend suite runs only for same-repo events AND when the provisioning
# secret is available. Fork PRs and secret-less runs (e.g. Dependabot)
# fall back to the no-backend suite.
RUN_BACKEND: ${{ (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && secrets.PROJECT_API_KEY != '' }}
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node-version }}
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
# Fail fast if a same-repo run lacks the backend secret, so the full
# suite can't be silently downgraded to unit-only and still report green.
# Forks (different head repo) intentionally skip this and fall back below.
- name: Require backend secret on same-repo runs
if: ${{ (github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository) && env.RUN_BACKEND != 'true' }}
run: |
echo "::error::PROJECT_API_KEY is not set for a same-repo run; integration/e2e would be silently skipped. Failing instead of reporting a misleading green." >&2
exit 1
# ---------- Backend path (same-repo only) ----------
- name: Provision temp Permit env
id: provision
if: env.RUN_BACKEND == 'true'
env:
PROJECT_API_KEY: ${{ secrets.PROJECT_API_KEY }}
PROJECT_ID: 7f55831d77c642739bc17733ab0af138
ENV_KEY: node-sdk-ci-${{ github.run_id }}-${{ github.run_attempt }}-n${{ matrix.node-version }}
run: |
response=$(curl -sS -X POST \
"https://api.permit.io/v2/projects/${PROJECT_ID}/envs" \
-H "Authorization: Bearer ${PROJECT_API_KEY}" \
-H 'Content-Type: application/json' \
-d "{\"key\":\"${ENV_KEY}\",\"name\":\"${ENV_KEY}\"}")
env_id=$(printf '%s' "$response" | jq -r '.id // empty')
if [ -z "$env_id" ]; then
echo "Failed to create env (key=${ENV_KEY})." >&2
exit 1
fi
echo "env_id=${env_id}" >> "$GITHUB_OUTPUT"
- name: Fetch env API key
id: fetch_key
if: env.RUN_BACKEND == 'true'
env:
PROJECT_API_KEY: ${{ secrets.PROJECT_API_KEY }}
PROJECT_ID: 7f55831d77c642739bc17733ab0af138
ENV_ID: ${{ steps.provision.outputs.env_id }}
run: |
response=$(curl -sS -X GET \
"https://api.permit.io/v2/api-key/${PROJECT_ID}/${ENV_ID}" \
-H "Authorization: Bearer ${PROJECT_API_KEY}")
env_api_key=$(printf '%s' "$response" | jq -r '.secret // empty')
if [ -z "$env_api_key" ]; then
echo "Failed to fetch env API key." >&2
exit 1
fi
# Mask BEFORE writing to the env file so it is redacted everywhere.
echo "::add-mask::${env_api_key}"
echo "ENV_API_KEY=${env_api_key}" >> "$GITHUB_ENV"
- name: Start local PDP
if: env.RUN_BACKEND == 'true'
env:
ENV_API_KEY: ${{ env.ENV_API_KEY }}
run: |
docker run -d --name pdp -p 7766:7000 \
-e PDP_API_KEY="$ENV_API_KEY" \
-e PERMIT_API_KEY="$ENV_API_KEY" \
permitio/pdp-v2:latest
- name: Wait for PDP to be ready
if: env.RUN_BACKEND == 'true'
run: |
for i in $(seq 1 60); do
if curl -sf http://127.0.0.1:7766/healthy >/dev/null; then
echo "PDP ready after ${i} attempt(s)"
exit 0
fi
sleep 2
done
echo "PDP did not become healthy in time; dumping logs:" >&2
docker logs pdp || true
exit 1
- name: Run full test suite (backend)
if: env.RUN_BACKEND == 'true'
env:
PDP_API_KEY: ${{ env.ENV_API_KEY }}
PERMIT_API_KEY: ${{ env.ENV_API_KEY }}
API_TIER: prod
# Force IPv4: Node resolves `localhost` to ::1 first, but the runner's
# Docker IPv6 publish refuses connections, so PDP checks would hit
# ECONNREFUSED. 127.0.0.1 pins the working IPv4 path.
PDP_URL: http://127.0.0.1:7766
run: yarn test:ci:full
# Dump PDP diagnostics whenever the backend path fails. The SDK reports
# PDP connection errors with no HTTP response, so the PDP side is otherwise
# invisible; this captures container state and logs to tell a transient
# restart/readiness blip apart from a crashed/exited container.
- name: Dump PDP diagnostics on failure
if: ${{ failure() && env.RUN_BACKEND == 'true' }}
run: |
echo "::group::docker ps -a"
docker ps -a --filter name=pdp || true
echo "::endgroup::"
echo "::group::PDP container state"
docker inspect -f \
'status={{.State.Status}} restartCount={{.RestartCount}} exitCode={{.State.ExitCode}} oomKilled={{.State.OOMKilled}} startedAt={{.State.StartedAt}} finishedAt={{.State.FinishedAt}}' \
pdp || true
echo "::endgroup::"
echo "::group::docker logs pdp"
docker logs pdp || true
echo "::endgroup::"
echo "::group::curl -sv http://localhost:7766/healthy"
curl -sv http://localhost:7766/healthy || true
echo "::endgroup::"
# ---------- No-backend path (forks / secret-less) ----------
- name: Run no-backend test suite
if: env.RUN_BACKEND != 'true'
run: yarn test:ci:unit
# ---------- Cleanup (always, even on failure/cancel) ----------
- name: Delete temp Permit env
if: ${{ always() && steps.provision.outputs.env_id != '' }}
env:
PROJECT_API_KEY: ${{ secrets.PROJECT_API_KEY }}
PROJECT_ID: 7f55831d77c642739bc17733ab0af138
ENV_ID: ${{ steps.provision.outputs.env_id }}
run: |
curl -sS -X DELETE \
"https://api.permit.io/v2/projects/${PROJECT_ID}/envs/${ENV_ID}" \
-H "Authorization: Bearer ${PROJECT_API_KEY}" || true