Skip to content

Commit d7d5175

Browse files
authored
Merge pull request #27 from InKCre/codex/dx-closure
fix(dx): close preview and workflow gaps
2 parents 8b50cbb + a9770aa commit d7d5175

32 files changed

Lines changed: 567 additions & 427 deletions

‎.github/actions/preview-verify/action.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Verify preview source
2-
description: Require a same-repository pull request and green checks for its exact head
2+
description: Require an open same-repository pull request and green checks for its exact head
33

44
inputs:
55
github_token:
@@ -34,6 +34,7 @@ runs:
3434
)"
3535
test "$(jq -r '.head.repo.full_name' <<<"$pr_json")" = "$GITHUB_REPOSITORY"
3636
test "$(jq -r '.head.sha' <<<"$pr_json")" = "$HEAD_SHA"
37+
test "$(jq -r '.state' <<<"$pr_json")" = "open"
3738
3839
required_checks=(
3940
"Hermetic repository contract"
@@ -51,7 +52,9 @@ runs:
5152
for check_name in "${required_checks[@]}"; do
5253
conclusion="$(
5354
jq -r --arg name "$check_name" \
54-
'[.check_runs[] | select(.name == $name)] | last | .conclusion // ""' \
55+
'[.check_runs[] |
56+
select(.name == $name and .app.slug == "github-actions")] |
57+
last | .conclusion // ""' \
5558
<<<"$checks_json"
5659
)"
5760
if [ "$conclusion" != "success" ]; then

‎.github/workflows/branching-database.yml‎

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,88 @@ jobs:
8888
8989
cleanup:
9090
name: Delete preview branch
91-
if: github.event.action == 'closed'
91+
if: >-
92+
github.event.action == 'closed' &&
93+
github.event.pull_request.head.repo.full_name == github.repository
9294
runs-on: ubuntu-latest
9395
steps:
9496
- name: Delete deterministic Neon branch
95-
uses: neondatabase/delete-branch-action@v3
96-
with:
97-
project_id: ${{ env.NEON_PROJECT_ID }}
98-
branch: ${{ env.NEON_BRANCH_NAME }}
99-
api_key: ${{ secrets.NEON_API_KEY }}
97+
env:
98+
NEON_API_KEY: ${{ secrets.NEON_API_KEY }}
99+
run: |
100+
set -euo pipefail
101+
102+
: "${NEON_API_KEY:?missing NEON_API_KEY}"
103+
: "${NEON_PROJECT_ID:?missing NEON_PROJECT_ID}"
104+
: "${NEON_BRANCH_NAME:?missing NEON_BRANCH_NAME}"
105+
if [[ ! "$NEON_BRANCH_NAME" =~ ^preview/pr-[0-9]+$ ]]; then
106+
echo "Refusing unexpected branch namespace: $NEON_BRANCH_NAME" >&2
107+
exit 1
108+
fi
109+
110+
cli=(npx --yes neonctl@2.36.0)
111+
list_json="$(
112+
"${cli[@]}" branches list \
113+
--project-id "$NEON_PROJECT_ID" \
114+
--output json \
115+
--no-analytics \
116+
--no-color
117+
)"
118+
matches="$(
119+
jq -c --arg name "$NEON_BRANCH_NAME" \
120+
'[.[] | select(.name == $name)]' <<<"$list_json"
121+
)"
122+
match_count="$(jq 'length' <<<"$matches")"
123+
124+
if [[ "$match_count" == 0 ]]; then
125+
echo "Neon branch already absent: $NEON_BRANCH_NAME"
126+
exit 0
127+
fi
128+
if [[ "$match_count" != 1 ]]; then
129+
echo "Expected one Neon branch named $NEON_BRANCH_NAME" >&2
130+
exit 1
131+
fi
132+
133+
parent_matches="$(
134+
jq -c --arg name "$NEON_PARENT_BRANCH" \
135+
'[.[] | select(.name == $name)]' <<<"$list_json"
136+
)"
137+
if [[ "$(jq 'length' <<<"$parent_matches")" != 1 ]]; then
138+
echo "Expected one Neon parent named $NEON_PARENT_BRANCH" >&2
139+
exit 1
140+
fi
141+
142+
branch_id="$(jq -r '.[0].id' <<<"$matches")"
143+
actual_parent_id="$(jq -r '.[0].parent_id' <<<"$matches")"
144+
expected_parent_id="$(jq -r '.[0].id' <<<"$parent_matches")"
145+
if [[ ! "$branch_id" =~ ^br-[a-z0-9-]+$ ]] ||
146+
[[ ! "$expected_parent_id" =~ ^br-[a-z0-9-]+$ ]]; then
147+
echo "Refusing unexpected Neon branch identity" >&2
148+
exit 1
149+
fi
150+
if [[ "$actual_parent_id" != "$expected_parent_id" ]]; then
151+
echo "Refusing Neon branch with unexpected parent" >&2
152+
exit 1
153+
fi
154+
155+
if "${cli[@]}" branches delete "$branch_id" \
156+
--project-id "$NEON_PROJECT_ID" \
157+
--no-analytics \
158+
--no-color; then
159+
exit 0
160+
fi
161+
162+
echo "Delete failed; rechecking branch state" >&2
163+
remaining="$(
164+
"${cli[@]}" branches list \
165+
--project-id "$NEON_PROJECT_ID" \
166+
--output json \
167+
--no-analytics \
168+
--no-color
169+
)"
170+
if jq -e --arg name "$NEON_BRANCH_NAME" \
171+
'any(.[]; .name == $name)' <<<"$remaining" >/dev/null; then
172+
echo "Neon branch still exists: $NEON_BRANCH_NAME" >&2
173+
exit 1
174+
fi
175+
echo "Neon branch disappeared concurrently: $NEON_BRANCH_NAME"

‎.github/workflows/openapi-doc.yml‎

Lines changed: 0 additions & 104 deletions
This file was deleted.

‎.github/workflows/preview-deploy.yml‎

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
name: Preview application
22

33
on:
4-
workflow_run:
5-
workflows:
6-
- Repository and artifact checks
7-
types:
8-
- completed
94
pull_request_target:
105
types:
6+
- opened
7+
- reopened
8+
- synchronize
119
- closed
1210

1311
permissions:
@@ -16,20 +14,14 @@ permissions:
1614
pull-requests: read
1715

1816
concurrency:
19-
group: >-
20-
preview-application-pr-${{
21-
github.event.workflow_run.pull_requests[0].number ||
22-
github.event.pull_request.number
23-
}}
24-
cancel-in-progress: false
17+
group: preview-application-pr-${{ github.event.pull_request.number }}
18+
cancel-in-progress: true
2519

2620
jobs:
2721
deploy:
2822
if: >-
29-
github.event_name == 'workflow_run' &&
30-
github.event.workflow_run.conclusion == 'success' &&
31-
github.event.workflow_run.event == 'pull_request' &&
32-
github.event.workflow_run.pull_requests[0].head.repo.full_name == github.repository
23+
github.event.action != 'closed' &&
24+
github.event.pull_request.head.repo.full_name == github.repository
3325
runs-on: ubuntu-latest
3426
environment: preview
3527
steps:
@@ -40,23 +32,23 @@ jobs:
4032
path: .delivery
4133
persist-credentials: false
4234

35+
- name: Verify exact pull request head
36+
uses: ./.delivery/.github/actions/preview-verify
37+
with:
38+
github_token: ${{ github.token }}
39+
head_sha: ${{ github.event.pull_request.head.sha }}
40+
pr_number: ${{ github.event.pull_request.number }}
41+
4342
- name: Checkout isolated pull request source
4443
uses: actions/checkout@v5
4544
with:
46-
ref: ${{ github.event.workflow_run.head_sha }}
45+
ref: ${{ github.event.pull_request.head.sha }}
4746
path: source
4847
persist-credentials: false
4948

50-
- name: Verify exact pull request head
51-
uses: ./.delivery/.github/actions/preview-verify
52-
with:
53-
github_token: ${{ github.token }}
54-
head_sha: ${{ github.event.workflow_run.head_sha }}
55-
pr_number: ${{ github.event.workflow_run.pull_requests[0].number }}
56-
5749
- name: Build web and release images without deployment secrets
5850
env:
59-
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
51+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
6052
run: |
6153
docker build \
6254
--target heroku-web \
@@ -67,21 +59,27 @@ jobs:
6759
--tag "inkcre-preview-release:$HEAD_SHA" \
6860
"${{ github.workspace }}/source"
6961
62+
- name: Reverify preview authority before delivery
63+
uses: ./.delivery/.github/actions/preview-verify
64+
with:
65+
github_token: ${{ github.token }}
66+
head_sha: ${{ github.event.pull_request.head.sha }}
67+
pr_number: ${{ github.event.pull_request.number }}
68+
7069
- name: Deliver preview
7170
uses: ./.delivery/.github/actions/preview-delivery
7271
with:
73-
head_sha: ${{ github.event.workflow_run.head_sha }}
72+
head_sha: ${{ github.event.pull_request.head.sha }}
7473
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
7574
llm_sp_ak: ${{ secrets.LLM_SP_AK }}
7675
llm_sp_base_url: ${{ secrets.LLM_SP_BASE_URL }}
7776
neon_api_key: ${{ secrets.NEON_API_KEY }}
7877
neon_project_id: ${{ vars.NEON_PROJECT_ID }}
79-
pr_number: ${{ github.event.workflow_run.pull_requests[0].number }}
78+
pr_number: ${{ github.event.pull_request.number }}
8079

8180
cleanup:
8281
name: Delete Heroku preview
8382
if: >-
84-
github.event_name == 'pull_request_target' &&
8583
github.event.action == 'closed' &&
8684
github.event.pull_request.head.repo.full_name == github.repository
8785
runs-on: ubuntu-latest

‎.pre-commit-config.yaml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ repos:
99

1010
- repo: local
1111
hooks:
12+
- id: check-format
13+
name: Check Ruff formatting
14+
entry: ruff format --check .
15+
language: system
16+
files: ^(.*\.py|pyproject\.toml|ruff\.toml)$
17+
pass_filenames: false
1218
- id: check-lock
1319
name: Check PDM lock
1420
entry: python scripts/check_lock.py

‎CONTRIBUTING.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ pdm run check
1313
`doctor` reports a mismatch when the local toolchain does not match that contract.
1414

1515
`check` is the same hermetic repository gate used by CI. It verifies the lock and
16-
requirements export, migration configuration and append-only baseline, repository lint,
17-
and the complete unit-test suite. Use narrower commands while iterating:
16+
requirements export, migration configuration and append-only baseline, Ruff formatting,
17+
repository lint, and the complete unit-test suite. Use narrower commands while iterating:
1818

1919
```bash
20+
pdm run format:check
2021
pdm run lint
2122
pdm run test
2223
pdm run check:foundation

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pdm run dev
1313
```
1414

1515
`pdm run check` is the hermetic repository contract used by CI: frozen dependency
16-
checks, migration containment, lint, and the complete unit-test suite.
16+
checks, migration containment, formatting, lint, and the complete unit-test suite.
1717

1818
Developer setup and shared-skill notes: [CONTRIBUTING.md](CONTRIBUTING.md)
1919

@@ -35,3 +35,5 @@ If `docs/_shared/` is missing, run `git submodule update --init --recursive` bef
3535
## Generated Artifacts
3636

3737
- OpenAPI schema: `docs/openapi.json`
38+
- Regenerate locally with `pdm run python scripts/generate-openapi.py`.
39+
- The repository does not publish hosted API documentation automatically.

‎app/business/client/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .main import ClientManager
22

33
__all__ = [
4-
"ClientManager",
4+
"ClientManager",
55
]

‎app/business/extension/main.py‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,7 @@ def install(cls, extid: ExtensionID, version: Opt[str] = None) -> ExtensionModel
206206
raise ValueError(f"Extension {extid} has no valid local metadata")
207207
local_version = local_version or "0.1.0"
208208
if version is not None and version != local_version:
209-
raise ValueError(
210-
f"Extension {extid} version {version} is not part of this artifact"
211-
)
209+
raise ValueError(f"Extension {extid} version {version} is not part of this artifact")
212210

213211
with SessionLocal() as db:
214212
existing = db.exec(

0 commit comments

Comments
 (0)