GitCode is the source of truth for code review, issues, tags, and native release downloads. GitHub Actions owns release automation and also publishes a GitHub Release mirror. Both releases receive the same rendered notes and binary set.
Use SemVer tags with a v prefix:
v0.1.0The release binary prints the same version without the v prefix:
gitcode-mcp --versiongitcode-mcp 0.1.0
- Ensure
mainis up to date and clean. - Run:
go test ./...
python3 -m unittest discover -s scripts/release -p 'test_*.py'
git diff --check- Create and push a tag in GitCode:
git tag v0.1.0
git push origin v0.1.0- GitCode push mirroring propagates the tag to GitHub.
- GitHub Actions runs the release workflow from the mirrored tag.
- The workflow generates
dist/release-notes.mdfrom the first-parent Git history between the previous release tag and the current tag. - The workflow creates or updates the GitHub Release with those notes, binary
assets, and
checksums.txt. - If the
GITCODE_TOKENGitHub Actions secret is configured, the workflow creates or updates the matching GitCode release through the PAT-compatible API using the same Markdown file and GitHub fallback links. - The workflow requests a short-lived upload contract for each artifact, uploads it without forwarding the GitCode token to object storage, and verifies the final GitCode asset names and byte sizes.
Creating and pushing the tag remains the only required release action. Release
note generation is not part of the shipped gitcode-mcp binary.
The first release workflow builds:
darwin/arm64linux/amd64linux/arm64windows/amd64
Unix targets are published as .tar.gz. Windows is published as .zip.
Run the release builder locally:
./scripts/release/build.shTo build a single target:
GOOS=linux GOARCH=amd64 ./scripts/release/build.shThe script writes artifacts to dist/ and generates dist/checksums.txt.
Preview the next release notes without creating a tag:
python3 scripts/release/generate_notes.py \
--tag v0.2.0 \
--preview \
--previous-tag v0.1.0 \
--gitcode-web-base-url https://gitcode.com/YOUR_OWNER/YOUR_REPOThe generator reads only local Git history. GitCode merge commit subjects and bodies preserve merge request numbers, titles, and closing issue references; direct commits remain visible as commit links. The GitHub mirror currently does not mirror GitCode merge request records, so GitHub native generated notes are not the metadata source for this workflow.
For a release that needs human-written context, add an optional reviewed file at
.github/release-notes/TAG.md, for example
.github/release-notes/v0.2.0.md. CI includes it as the Maintainer notes
section. The generated file itself is not committed.
Run the generator fixture tests locally:
python3 -m unittest discover -s scripts/release -p 'test_*.py'The generator emits deterministic Markdown and reports its SHA-256 fingerprint. The release workflow records that fingerprint in the GitHub Actions job summary before either release publisher runs.
After both publishers complete:
- Confirm the release commit matches the GitCode tag commit.
- Confirm the GitCode Download list contains every archive and
checksums.txt; use the GitHub mirror as a fallback. - Verify the checksum.
- Run
gitcode-mcp --version.
Release assets must not include local config, credentials, cache files, or repository-local .gitcode/mcp data.
GitCode releases are published by the Go CLI, not by an ad hoc shell script:
gitcode-mcp publish-release \
--repo urandon/gitcode-mcp \
--tag v0.1.0 \
--ref main \
--title "gitcode-mcp v0.1.0" \
--input /path/to/release-notes.md \
--asset gitcode-mcp_v0.1.0_darwin_arm64.tar.gz=https://github.com/urandon/gitcode-mcp/releases/download/v0.1.0/gitcode-mcp_v0.1.0_darwin_arm64.tar.gz \
--status latest \
--idempotency-key release-v0.1.0The command validates with --dry-run and otherwise performs an idempotent create-or-update by tag:
GET /api/v5/repos/{owner}/{repo}/releases/tags/{tag}POST /api/v5/repos/{owner}/{repo}/releaseswhen missingPATCH /api/v5/repos/{owner}/{repo}/releases/{tag}when present
The automated flow publishes binary artifacts to both GitHub Releases and the
native GitCode Download section. GitHub links remain in the Markdown as a
portable fallback. Both publishers consume dist/release-notes.md.
GitCode attachments use a separate presigned upload flow. The workflow first
creates or updates release metadata, requests an HTTPS upload contract for each
filename, then sends the artifact bytes with exactly the returned object-store
headers. It never forwards GITCODE_TOKEN to the presigned URL and never prints
the URL or contract headers. A rerun skips an existing name only when its byte
size matches; a mismatch fails closed. The final release asset inventory is
polled for a bounded period and verified by name and size.
Create a dedicated GitCode bot or service account token for release publishing. Give that account access only to this repository, with the minimum project role that can create/update releases and tags. The GitCode frontend maps release creation to tag creation permission, so a read-only or reporter-like token is not enough.
Store the token in the GitHub mirror as a repository Actions secret named GITCODE_TOKEN. The release workflow only reads it in the tag-triggered release job; pull request CI does not receive it.