Some checks failed
CI / Lint (bash) (push) Has been cancelled
CI / Lint (markdown) (push) Has been cancelled
CI / Lint (nickel) (push) Has been cancelled
CI / Lint (nushell) (push) Has been cancelled
CI / Lint (rust) (push) Has been cancelled
CI / Code Coverage (push) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (macos-latest) (push) Has been cancelled
CI / Build (ubuntu-latest) (push) Has been cancelled
CI / Build (windows-latest) (push) Has been cancelled
CI / Benchmark (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / License Compliance (push) Has been cancelled
132 lines
4.4 KiB
YAML
132 lines
4.4 KiB
YAML
# Release Pipeline using Dockerfile.cross
|
|
# Uses existing Dockerfile.cross for consistent multi-platform builds
|
|
# Triggers on tags: v*
|
|
|
|
when:
|
|
event: tag
|
|
tag: v*
|
|
|
|
steps:
|
|
# Create GitHub-style release via Gitea API
|
|
create-release:
|
|
image: alpine:latest
|
|
secrets: [gitea_token]
|
|
commands:
|
|
- apk add --no-cache curl jq
|
|
- |
|
|
RELEASE_DATA=$(jq -n \
|
|
--arg tag "${CI_COMMIT_TAG}" \
|
|
--arg name "Release ${CI_COMMIT_TAG}" \
|
|
--arg body "Multi-platform build using Dockerfile.cross" \
|
|
'{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}')
|
|
|
|
RELEASE_ID=$(curl -X POST "${GITEA_URL}/api/v1/repos/${CI_REPO}/releases" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "${RELEASE_DATA}" | jq -r '.id')
|
|
|
|
echo "RELEASE_ID=${RELEASE_ID}" > /tmp/release.env
|
|
echo "✓ Created release ${CI_COMMIT_TAG} (ID: ${RELEASE_ID})"
|
|
|
|
# Build binaries using Dockerfile.cross (matrix)
|
|
build-binaries:
|
|
image: docker:27-cli
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
matrix:
|
|
TARGET:
|
|
- x86_64-unknown-linux-gnu
|
|
- aarch64-unknown-linux-gnu
|
|
- x86_64-apple-darwin
|
|
- aarch64-apple-darwin
|
|
- x86_64-pc-windows-msvc
|
|
commands:
|
|
- echo "Building for target ${TARGET}..."
|
|
|
|
# Build using Dockerfile.cross
|
|
- |
|
|
docker build -t typedialog-build:${TARGET} \
|
|
--build-arg TARGET=${TARGET} \
|
|
-f .woodpecker/Dockerfile.cross .
|
|
|
|
# Create container and extract binaries
|
|
- docker create --name extract-${TARGET} typedialog-build:${TARGET}
|
|
- mkdir -p dist-${TARGET}
|
|
- docker cp extract-${TARGET}:/output/bin/. dist-${TARGET}/
|
|
- docker cp extract-${TARGET}:/output/BUILD_INFO.json dist-${TARGET}/ || true
|
|
- docker rm extract-${TARGET}
|
|
|
|
# Package binaries
|
|
- tar czf typedialog-${CI_COMMIT_TAG}-${TARGET}.tar.gz -C dist-${TARGET} .
|
|
- sha256sum typedialog-${CI_COMMIT_TAG}-${TARGET}.tar.gz > typedialog-${CI_COMMIT_TAG}-${TARGET}.tar.gz.sha256
|
|
|
|
- echo "✓ Built and packaged ${TARGET}"
|
|
depends_on:
|
|
- create-release
|
|
|
|
# Generate SBOMs (SPDX + CycloneDX)
|
|
generate-sbom:
|
|
image: typedialog-ci:latest # Uses custom image with cargo-sbom pre-installed
|
|
commands:
|
|
- cargo sbom --output-format spdx_json_2_3 > sbom-spdx.json
|
|
- cargo sbom --output-format cyclone_dx_json_1_4 > sbom-cyclonedx.json
|
|
- echo "✓ Generated SBOMs"
|
|
depends_on:
|
|
- create-release
|
|
|
|
# Upload all artifacts to Gitea release
|
|
upload-artifacts:
|
|
image: alpine:latest
|
|
secrets: [gitea_token]
|
|
commands:
|
|
- apk add --no-cache curl jq
|
|
- source /tmp/release.env
|
|
- echo "Uploading to release ID ${RELEASE_ID}..."
|
|
|
|
# Upload binary archives and checksums
|
|
- |
|
|
for file in typedialog-${CI_COMMIT_TAG}-*.tar.gz*; do
|
|
if [ -f "${file}" ]; then
|
|
echo "Uploading ${file}..."
|
|
curl -X POST "${GITEA_URL}/api/v1/repos/${CI_REPO}/releases/${RELEASE_ID}/assets?name=${file}" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/octet-stream" \
|
|
--data-binary "@${file}"
|
|
fi
|
|
done
|
|
|
|
# Upload SBOMs
|
|
- |
|
|
for file in sbom-*.json; do
|
|
if [ -f "${file}" ]; then
|
|
echo "Uploading ${file}..."
|
|
curl -X POST "${GITEA_URL}/api/v1/repos/${CI_REPO}/releases/${RELEASE_ID}/assets?name=${file}" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
--data-binary "@${file}"
|
|
fi
|
|
done
|
|
|
|
- echo "✓ All artifacts uploaded successfully"
|
|
depends_on:
|
|
- build-binaries
|
|
- generate-sbom
|
|
|
|
# Optional: Publish to crates.io
|
|
publish-crates:
|
|
image: rust:latest
|
|
secrets: [cargo_token]
|
|
when:
|
|
# Only if CARGO_TOKEN secret is set
|
|
evaluate: 'CI_PIPELINE_EVENT == "tag" && CI_COMMIT_TAG =~ "^v[0-9]"'
|
|
commands:
|
|
- |
|
|
for crate in typedialog-core typedialog-ag-core typedialog-ai typedialog-prov-gen typedialog typedialog-tui typedialog-web typedialog-ag typedialog-ag-server; do
|
|
echo "Publishing ${crate}..."
|
|
cargo publish -p ${crate} --token ${CARGO_TOKEN} || true
|
|
sleep 30
|
|
done
|
|
- echo "✓ Published to crates.io"
|
|
depends_on:
|
|
- upload-artifacts
|