forked from cleveragents/cleveragents-core
00897be24a
## Summary Complete CI/CD pipeline definitions: release workflow, caching, status-check consolidation, and documentation. ### Changes **New: Release pipeline** (`.forgejo/workflows/release.yml`): - Triggered on `v*` tags - 3 jobs: `build-wheel` → `build-docker` → `create-release` - Builds wheel via `nox -s build`, Docker image via multi-stage Dockerfile - Creates Forgejo release via API with wheel artifact attached - Configurable registry push via `REGISTRY_*` secrets **Updated: CI pipeline** (`.forgejo/workflows/ci.yml`): - Added `actions/cache@v3` for `~/.cache/uv` on all 8 primary jobs (keyed on `pyproject.toml` hash) - Added `status-check` consolidation job depending on all required checks — single gate for branch protection **Updated: CONTRIBUTING.md**: - New CI/CD section: pipeline overview, job table, required merge checks, release process, secrets documentation **Tests**: - 13 new Behave scenarios validating workflow YAML structure, tag triggers, job definitions, dependencies - 9 new Robot tests validating file existence, content, nox session references ### Quality Gates | Session | Result | |---|---| | `nox -s lint` | PASS | | `nox -s typecheck` | PASS (0 errors) | | `nox -s unit_tests` | PASS (10,819 scenarios) | | `nox -s coverage_report` | 97.9% (>= 97%) | Closes #858 Reviewed-on: cleveragents/cleveragents-core#983 Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com> Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
142 lines
4.8 KiB
YAML
142 lines
4.8 KiB
YAML
name: Release
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- "v*"
|
|
|
|
env:
|
|
UV_VERSION: "0.8.0"
|
|
PYTHON_VERSION: "3.13"
|
|
NOX_DEFAULT_VENV_BACKEND: "uv"
|
|
|
|
jobs:
|
|
build-wheel:
|
|
runs-on: docker
|
|
container:
|
|
image: python:3.13-slim
|
|
steps:
|
|
- name: Install Node.js (required by actions/checkout)
|
|
run: |
|
|
apt-get update && apt-get install -y -qq nodejs && rm -rf /var/lib/apt/lists/*
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Install uv and nox
|
|
run: |
|
|
pip install -q uv==${{ env.UV_VERSION }} nox
|
|
|
|
- name: Build wheel via nox
|
|
run: |
|
|
nox -s build
|
|
env:
|
|
NOX_DEFAULT_VENV_BACKEND: uv
|
|
|
|
- name: Upload wheel artifact
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheel
|
|
path: dist/*.whl
|
|
retention-days: 30
|
|
|
|
build-docker:
|
|
runs-on: docker
|
|
container:
|
|
image: docker:dind
|
|
options: --privileged
|
|
needs: [build-wheel]
|
|
steps:
|
|
- name: Start Docker daemon and install dependencies
|
|
run: |
|
|
dockerd &
|
|
apk add --no-cache git nodejs
|
|
for i in $(seq 1 30); do docker info >/dev/null 2>&1 && break || sleep 1; done
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Extract tag name
|
|
id: tag
|
|
run: |
|
|
TAG_NAME="${FORGEJO_REF_NAME:-${GITHUB_REF_NAME:-unknown}}"
|
|
echo "TAG_NAME=${TAG_NAME}" >> $FORGEJO_OUTPUT
|
|
|
|
- name: Build Docker image
|
|
run: |
|
|
TAG="${{ steps.tag.outputs.TAG_NAME }}"
|
|
docker build \
|
|
-t "${{ secrets.CONTAINER_REGISTRY }}:${TAG}" \
|
|
-t "${{ secrets.CONTAINER_REGISTRY }}:latest" \
|
|
.
|
|
|
|
- name: Push Docker image to registry
|
|
if: secrets.CONTAINER_REGISTRY != ''
|
|
run: |
|
|
TAG="${{ steps.tag.outputs.TAG_NAME }}"
|
|
if [ -n "${{ secrets.CONTAINER_REGISTRY_USER }}" ]; then
|
|
echo "${{ secrets.CONTAINER_REGISTRY_PASSWORD }}" | \
|
|
docker login \
|
|
-u "${{ secrets.CONTAINER_REGISTRY_USER }}" \
|
|
--password-stdin \
|
|
"${{ secrets.CONTAINER_REGISTRY }}"
|
|
fi
|
|
docker push "${{ secrets.CONTAINER_REGISTRY }}:${TAG}"
|
|
docker push "${{ secrets.CONTAINER_REGISTRY }}:latest"
|
|
|
|
create-release:
|
|
runs-on: docker
|
|
container:
|
|
image: python:3.13-slim
|
|
needs: [build-wheel, build-docker]
|
|
steps:
|
|
- name: Install system dependencies
|
|
run: |
|
|
apt-get update && apt-get install -y -qq nodejs curl jq && rm -rf /var/lib/apt/lists/*
|
|
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download wheel artifact
|
|
uses: actions/download-artifact@v3
|
|
with:
|
|
name: wheel
|
|
path: dist/
|
|
|
|
- name: Extract tag name
|
|
id: tag
|
|
run: |
|
|
TAG_NAME="${FORGEJO_REF_NAME:-${GITHUB_REF_NAME:-unknown}}"
|
|
echo "TAG_NAME=${TAG_NAME}" >> $FORGEJO_OUTPUT
|
|
|
|
- name: Create Forgejo release with wheel
|
|
env:
|
|
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
|
|
FORGEJO_URL: ${{ secrets.FORGEJO_URL }}
|
|
run: |
|
|
TAG="${{ steps.tag.outputs.TAG_NAME }}"
|
|
REPO="${{ forgejo.repository }}"
|
|
API_URL="${FORGEJO_URL}/api/v1/repos/${REPO}/releases"
|
|
|
|
# Create the release
|
|
RELEASE_ID=$(curl -s -X POST "${API_URL}" \
|
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{
|
|
\"tag_name\": \"${TAG}\",
|
|
\"name\": \"${TAG}\",
|
|
\"body\": \"Release ${TAG}\",
|
|
\"draft\": false,
|
|
\"prerelease\": false
|
|
}" | jq -r '.id')
|
|
|
|
echo "Created release ID: ${RELEASE_ID}"
|
|
|
|
# Attach wheel artifacts
|
|
for whl in dist/*.whl; do
|
|
FILENAME=$(basename "${whl}")
|
|
curl -s -X POST \
|
|
"${API_URL}/${RELEASE_ID}/assets?name=${FILENAME}" \
|
|
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
|
-H "Content-Type: application/octet-stream" \
|
|
--data-binary "@${whl}"
|
|
echo "Attached ${FILENAME} to release"
|
|
done
|