Skip to content

Sync GitCode Release #13

Sync GitCode Release

Sync GitCode Release #13

name: Sync GitCode Release
on:
release:
types:
- published
- edited
workflow_dispatch:
inputs:
dry_run:
description: "Preview the GitCode API request without creating or updating a release"
required: false
default: true
type: boolean
tag_name:
description: "Release tag to sync"
required: true
type: string
release_name:
description: "Release title to sync (defaults to tag name if empty)"
required: false
type: string
body:
description: "Release notes markdown"
required: false
type: string
target_commitish:
description: "Target branch or commit"
required: false
default: main
type: string
prerelease:
description: "Whether this should be treated as a prerelease"
required: false
default: false
type: boolean
skip_assets:
description: "Skip GitCode asset upload and sync metadata only"
required: false
default: false
type: boolean
permissions:
contents: read
concurrency:
group: sync-gitcode-release-${{ github.event.release.tag_name || inputs.tag_name || github.run_id }}
cancel-in-progress: false
jobs:
sync-gitcode-release:
runs-on: ubuntu-latest
env:
GITCODE_OWNER: ${{ secrets.GITCODE_OWNER }}
GITCODE_REPO: ${{ secrets.GITCODE_REPO }}
GITCODE_TOKEN: ${{ secrets.GITCODE_TOKEN }}
GITCODE_API_BASE: ${{ secrets.GITCODE_API_BASE || 'https://api.gitcode.com/api/v5' }}
GH_TAG: ${{ github.event.release.tag_name || inputs.tag_name }}
GH_NAME: ${{ github.event.release.name || inputs.release_name }}
GH_BODY: ${{ github.event.release.body || inputs.body }}
GH_TARGET: ${{ github.event.release.target_commitish || inputs.target_commitish }}
GH_PRERELEASE: ${{ github.event.release.prerelease || inputs.prerelease || false }}
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false }}
SKIP_ASSETS: ${{ github.event_name == 'workflow_dispatch' && inputs.skip_assets || false }}
steps:
- name: Validate configuration
shell: bash
run: |
set -euo pipefail
test -n "${GITCODE_OWNER}"
test -n "${GITCODE_REPO}"
test -n "${GH_TAG}"
if [ "${DRY_RUN}" != "true" ]; then
test -n "${GITCODE_TOKEN}"
fi
- name: Download GitHub release assets
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir -p release-assets
if [ "${SKIP_ASSETS}" = "true" ]; then
echo "Skipping GitHub release asset download."
echo "asset_count=0" >> "${GITHUB_ENV}"
exit 0
fi
if [ "${{ github.event_name }}" = "release" ]; then
asset_count="$(jq '.release.assets | length' "${GITHUB_EVENT_PATH}")"
else
asset_count="$(gh release view "${GH_TAG}" --repo "${GITHUB_REPOSITORY}" --json assets --jq '.assets | length' 2>/dev/null || echo 0)"
fi
echo "GitHub release asset count: ${asset_count}"
echo "asset_count=${asset_count}" >> "${GITHUB_ENV}"
if [ "${asset_count}" = "0" ]; then
exit 0
fi
gh release download "${GH_TAG}" --repo "${GITHUB_REPOSITORY}" --dir release-assets
ls -lah release-assets
- name: Sync release metadata to GitCode
shell: bash
run: |
set -euo pipefail
api="${GITCODE_API_BASE}/repos/${GITCODE_OWNER}/${GITCODE_REPO}"
auth_q="access_token=${GITCODE_TOKEN}"
release_name="${GH_NAME:-$GH_TAG}"
release_body="${GH_BODY:-}"
payload="$(jq -n \
--arg tag "${GH_TAG}" \
--arg name "${release_name}" \
--arg body "${release_body}" \
--argjson prerelease "${GH_PRERELEASE:-false}" \
'{
tag_name: $tag,
name: $name,
body: $body,
prerelease: $prerelease
}'
)"
if [ "${DRY_RUN}" = "true" ]; then
echo "Dry run enabled. No GitCode release will be created or updated."
echo "GET ${api}/releases/tags/${GH_TAG}"
echo "POST ${api}/releases"
echo "PATCH ${api}/releases/<id>"
echo "Payload:"
echo "${payload}" | jq .
if [ "${asset_count:-0}" != "0" ]; then
echo ""
echo "GitHub release assets found:"
find release-assets -maxdepth 1 -type f -printf '%f\n' | sort
echo ""
echo "Planned GitCode attachment flow:"
echo "GET ${api}/releases/${GH_TAG}/upload_url"
echo "POST <upload_url> (multipart file upload)"
fi
exit 0
fi
echo "Checking GitCode release for tag ${GH_TAG}..."
http_code="$(curl -sS -o release.json -w "%{http_code}" \
"${api}/releases/tags/${GH_TAG}?${auth_q}")"
api_error_code="$(jq -r '.error_code // empty' release.json 2>/dev/null || true)"
if [ "${http_code}" = "200" ]; then
release_id="$(jq -r '.id // empty' release.json)"
if [ -z "${release_id}" ] || [ "${release_id}" = "null" ]; then
echo "Existing GitCode release found by tag; no release id in response, skipping metadata update."
jq '{tag_name, name}' release.json
exit 0
fi
echo "Updating existing GitCode release id=${release_id}..."
curl -sS --fail \
-X PATCH \
"${api}/releases/${release_id}?${auth_q}" \
-H "Content-Type: application/json" \
-d "${payload}" \
> result.json
jq '{id, tag_name, name}' result.json
exit 0
fi
if [ "${http_code}" = "400" ] && [ "${api_error_code}" = "404" ]; then
http_code="404"
fi
if [ "${http_code}" != "404" ]; then
echo "Unexpected GitCode release lookup response: ${http_code}"
cat release.json || true
exit 1
fi
echo "Creating GitCode release for tag ${GH_TAG}..."
curl -sS --fail \
-X POST \
"${api}/releases?${auth_q}" \
-H "Content-Type: application/json" \
-d "${payload}" \
> result.json
jq '{id, tag_name, name}' result.json
- name: Upload release assets to GitCode
if: env.DRY_RUN != 'true' && env.asset_count != '0'
shell: bash
run: |
set -euo pipefail
api="${GITCODE_API_BASE}/repos/${GITCODE_OWNER}/${GITCODE_REPO}"
auth_q="access_token=${GITCODE_TOKEN}"
for file in release-assets/*; do
if [ ! -f "${file}" ]; then
continue
fi
file_name="$(basename "${file}")"
echo "Resolving GitCode release upload URL for ${file_name}..."
upload_http_code="$(curl -sS -G -o upload-url.json -w "%{http_code}" \
-H "PRIVATE-TOKEN: ${GITCODE_TOKEN}" \
--data-urlencode "file_name=${file_name}" \
"${api}/releases/${GH_TAG}/upload_url")"
if [ "${upload_http_code}" != "200" ]; then
echo "Unexpected GitCode upload_url response: ${upload_http_code}"
cat upload-url.json || true
exit 1
fi
upload_url="$(jq -r '.upload_url // .url // .data.upload_url // .data.url // empty' upload-url.json)"
if [ -z "${upload_url}" ]; then
upload_url="$(jq -r 'strings' upload-url.json | head -n 1)"
fi
if [ -z "${upload_url}" ] || [ "${upload_url}" = "null" ]; then
echo "Could not determine GitCode release upload URL from response:"
cat upload-url.json
exit 1
fi
echo "Uploading ${file_name} to GitCode release..."
curl -sS --fail \
-X POST \
-H "PRIVATE-TOKEN: ${GITCODE_TOKEN}" \
"${upload_url}" \
-F "file=@${file}"
done
- name: Summary
shell: bash
run: |
{
echo "## GitCode release sync"
echo ""
echo "- tag: \`${GH_TAG}\`"
echo "- repo: \`${GITCODE_OWNER}/${GITCODE_REPO}\`"
echo "- source: \`${{ github.event_name }}\`"
echo "- dry-run: \`${DRY_RUN}\`"
echo "- asset-count: \`${asset_count:-0}\`"
} >> "${GITHUB_STEP_SUMMARY}"