Sync GitCode Release #19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 "No id in tag lookup response. Tag lookup returned:" | |
| jq '.' release.json || cat release.json | |
| echo "Searching releases list..." | |
| curl -sS -o releases-list.json \ | |
| "${api}/releases?${auth_q}&per_page=100" | |
| echo "Releases list response:" | |
| jq '.[0:3] | .[] | {id, tag_name, name}' releases-list.json || cat releases-list.json | |
| release_id="$(jq -r --arg tag "${GH_TAG}" '.[] | select(.tag_name == $tag) | .id // empty' releases-list.json | head -n 1)" | |
| fi | |
| if [ -z "${release_id}" ] || [ "${release_id}" = "null" ]; then | |
| echo "Could not determine release id for tag ${GH_TAG}, skipping update." | |
| 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 | |
| echo "gitcode_release_id=${release_id}" >> "${GITHUB_ENV}" | |
| 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 | |
| release_id="$(jq -r '.id // empty' result.json)" | |
| if [ -n "${release_id}" ] && [ "${release_id}" != "null" ]; then | |
| echo "gitcode_release_id=${release_id}" >> "${GITHUB_ENV}" | |
| fi | |
| - 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 upload URL for ${file_name}..." | |
| curl -sS -G -o upload-url.json -w "" \ | |
| --data-urlencode "file_name=${file_name}" \ | |
| "${api}/releases/${GH_TAG}/upload_url?${auth_q}" | |
| 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 upload URL for ${file_name}:" | |
| cat upload-url.json | |
| exit 1 | |
| fi | |
| echo "Upload URL: ${upload_url}" | |
| echo "Uploading ${file_name} with Bearer auth..." | |
| curl -sS --fail \ | |
| -X POST \ | |
| -H "Authorization: Bearer ${GITCODE_TOKEN}" \ | |
| -F "file=@${file}" \ | |
| "${upload_url}" | |
| 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}" |