Skip to content

Commit 8b8fddd

Browse files
fix(ci): fix YAML syntax in gitlab-pages-dashboard template
The heredoc Python block had lines at column 0 inside a YAML block scalar, which broke yaml.safe_load and GitLab's release validation. GitLab validates ALL templates/ files when creating CI/CD Catalog releases — this was the root cause of every v1.1.0+ tag pipeline failure (422: could not find expected ':' at line 52 column 1). Fix: replace heredoc with python3 -c and properly indent all lines. Also restore create-release to use the release: keyword (declarative) which is GitLab's recommended approach.
1 parent 98e1893 commit 8b8fddd

File tree

2 files changed

+36
-46
lines changed

2 files changed

+36
-46
lines changed

.gitlab-ci.yml

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -56,48 +56,41 @@ test:
5656
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
5757

5858
# --- Publish release to CI/CD Catalog ---
59-
# Idempotent: if the release already exists (e.g. from a re-synced tag),
60-
# the job succeeds immediately. This prevents cascading failures when
61-
# the GitHub→GitLab sync workflow force-pushes tags.
59+
# Uses the release: keyword (declarative), which GitLab's runner handles
60+
# via release-cli with built-in authentication.
6261
#
63-
# Uses release-cli (not REST API) because CI_JOB_TOKEN lacks api scope
64-
# for the Releases endpoint. release-cli has special internal auth.
62+
# If the release already exists (re-synced tag), GitLab returns an error
63+
# and the job will fail — this is expected and harmless since the prior
64+
# release is already correct. Use allow_failure for idempotency.
6565
create-release:
6666
stage: release
6767
image: registry.gitlab.com/gitlab-org/release-cli:latest
6868
script:
69-
- |
70-
VERSION="${CI_COMMIT_TAG#v}"
71-
echo "Publishing release $CI_COMMIT_TAG to CI/CD Catalog"
72-
73-
release-cli create \
74-
--name "AIIR $CI_COMMIT_TAG" \
75-
--tag-name "$CI_COMMIT_TAG" \
76-
--description "## AIIR ${CI_COMMIT_TAG}
69+
- echo "Publishing release $CI_COMMIT_TAG to CI/CD Catalog"
70+
release:
71+
tag_name: $CI_COMMIT_TAG
72+
name: "AIIR $CI_COMMIT_TAG"
73+
description: |
74+
## AIIR $CI_COMMIT_TAG
7775
7876
AI Integrity Receipts — tamper-evident cryptographic receipts for every AI-generated commit.
7977
8078
### Install
8179
82-
\`\`\`
83-
pip install aiir==${VERSION}
84-
\`\`\`
80+
```
81+
pip install aiir==${CI_COMMIT_TAG#v}
82+
```
8583
8684
### Use as CI/CD Component
8785
88-
\`\`\`yaml
86+
```yaml
8987
include:
90-
- component: gitlab.com/invariant-systems/aiir/receipt@${CI_COMMIT_TAG}
91-
\`\`\`
88+
- component: $CI_SERVER_FQDN/$CI_PROJECT_PATH/receipt@$CI_COMMIT_TAG
89+
```
9290
9391
### Changelog
9492
95-
See [CHANGELOG.md](https://github.com/invariant-systems-ai/aiir/blob/main/CHANGELOG.md)" \
96-
&& echo "✅ Release $CI_COMMIT_TAG created" \
97-
|| {
98-
echo "⚠️ release-cli returned non-zero (release likely already exists)"
99-
echo "✅ Treating as success — idempotent for re-synced tags"
100-
}
93+
See [CHANGELOG.md](https://github.com/invariant-systems-ai/aiir/blob/main/CHANGELOG.md)
10194
rules:
10295
- if: $CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/
10396
allow_failure: false

templates/gitlab-pages-dashboard.yml

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,31 +48,28 @@ pages:
4848
- pip install --quiet aiir
4949
- mkdir -p public
5050
- |
51-
python3 << 'PYEOF'
52-
import json
53-
import glob
51+
python3 -c "
52+
import json, glob, os
53+
from aiir._gitlab import generate_dashboard_html
5454
55-
from aiir._gitlab import generate_dashboard_html
55+
receipts = []
56+
for f in sorted(glob.glob('.aiir-receipts/*.json')):
57+
try:
58+
with open(f) as fh:
59+
data = json.load(fh)
60+
if isinstance(data, dict):
61+
receipts.append(data)
62+
except (json.JSONDecodeError, OSError):
63+
continue
5664
57-
receipts = []
58-
for f in sorted(glob.glob('.aiir-receipts/*.json')):
59-
try:
60-
with open(f) as fh:
61-
data = json.load(fh)
62-
if isinstance(data, dict):
63-
receipts.append(data)
64-
except (json.JSONDecodeError, OSError):
65-
continue
65+
project_name = os.environ.get('CI_PROJECT_NAME', 'Project')
66+
html = generate_dashboard_html(receipts, project_name=project_name)
6667
67-
import os
68-
project_name = os.environ.get("CI_PROJECT_NAME", "Project")
69-
html = generate_dashboard_html(receipts, project_name=project_name)
68+
with open('public/index.html', 'w') as fh:
69+
fh.write(html)
7070
71-
with open("public/index.html", "w") as fh:
72-
fh.write(html)
73-
74-
print(f"Dashboard generated: {len(receipts)} receipts")
75-
PYEOF
71+
print(f'Dashboard generated: {len(receipts)} receipts')
72+
"
7673
artifacts:
7774
paths:
7875
- public

0 commit comments

Comments
 (0)