Skip to content

Commit 98e1893

Browse files
fix(ci): use release-cli for idempotent GitLab releases
CI_JOB_TOKEN lacks api scope for the Releases REST endpoint. Switch from curl+REST to release-cli which has special internal auth. Error is caught so re-synced tags don't cascade failures.
1 parent 2be80ed commit 98e1893

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

.gitlab-ci.yml

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,39 +59,45 @@ test:
5959
# Idempotent: if the release already exists (e.g. from a re-synced tag),
6060
# the job succeeds immediately. This prevents cascading failures when
6161
# the GitHub→GitLab sync workflow force-pushes tags.
62+
#
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.
6265
create-release:
6366
stage: release
64-
image: python:3.11-slim
67+
image: registry.gitlab.com/gitlab-org/release-cli:latest
6568
script:
6669
- |
67-
echo "Checking release status for $CI_COMMIT_TAG"
70+
VERSION="${CI_COMMIT_TAG#v}"
71+
echo "Publishing release $CI_COMMIT_TAG to CI/CD Catalog"
6872
69-
# Check if release already exists (REST API with CI_JOB_TOKEN)
70-
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
71-
--header "JOB-TOKEN: $CI_JOB_TOKEN" \
72-
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases/${CI_COMMIT_TAG}")
73+
release-cli create \
74+
--name "AIIR $CI_COMMIT_TAG" \
75+
--tag-name "$CI_COMMIT_TAG" \
76+
--description "## AIIR ${CI_COMMIT_TAG}
7377
74-
if [ "$STATUS" = "200" ]; then
75-
echo "✅ Release $CI_COMMIT_TAG already exists — skipping"
76-
exit 0
77-
fi
78+
AI Integrity Receipts — tamper-evident cryptographic receipts for every AI-generated commit.
7879
79-
# Strip 'v' prefix for pip install version
80-
VERSION="${CI_COMMIT_TAG#v}"
80+
### Install
81+
82+
\`\`\`
83+
pip install aiir==${VERSION}
84+
\`\`\`
85+
86+
### Use as CI/CD Component
87+
88+
\`\`\`yaml
89+
include:
90+
- component: gitlab.com/invariant-systems/aiir/receipt@${CI_COMMIT_TAG}
91+
\`\`\`
8192
82-
# Create release via REST API
83-
curl -s --fail \
84-
--header "JOB-TOKEN: $CI_JOB_TOKEN" \
85-
--header "Content-Type: application/json" \
86-
--data "{
87-
\"tag_name\": \"${CI_COMMIT_TAG}\",
88-
\"name\": \"AIIR ${CI_COMMIT_TAG}\",
89-
\"description\": \"## AIIR ${CI_COMMIT_TAG}\\n\\nAI Integrity Receipts — tamper-evident cryptographic receipts for every AI-generated commit.\\n\\n### Install\\n\\n\\\`\\\`\\\`\\npip install aiir==${VERSION}\\n\\\`\\\`\\\`\\n\\n### Use as CI/CD Component\\n\\n\\\`\\\`\\\`yaml\\ninclude:\\n - component: ${CI_SERVER_FQDN}/${CI_PROJECT_PATH}/receipt@${CI_COMMIT_TAG}\\n\\\`\\\`\\\`\\n\\n### Changelog\\n\\nSee [CHANGELOG.md](https://github.com/invariant-systems-ai/aiir/blob/main/CHANGELOG.md)\"
90-
}" \
91-
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases"
93+
### Changelog
9294
93-
echo ""
94-
echo "✅ Release $CI_COMMIT_TAG created"
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+
}
95101
rules:
96102
- if: $CI_COMMIT_TAG =~ /^v?\d+\.\d+\.\d+$/
97103
allow_failure: false

0 commit comments

Comments
 (0)