406 lines
14 KiB
YAML
406 lines
14 KiB
YAML
# .gitea/workflows/module-publish.yml
|
|
# Per-module NuGet and container publishing to Gitea registry
|
|
# Sprint: SPRINT_20251226_004_CICD
|
|
|
|
name: Module Publish
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
module:
|
|
description: 'Module to publish'
|
|
required: true
|
|
type: choice
|
|
options:
|
|
- Authority
|
|
- Attestor
|
|
- Concelier
|
|
- Scanner
|
|
- Policy
|
|
- Signer
|
|
- Excititor
|
|
- Gateway
|
|
- Scheduler
|
|
- Orchestrator
|
|
- TaskRunner
|
|
- Notify
|
|
- CLI
|
|
version:
|
|
description: 'Semantic version (e.g., 1.2.3)'
|
|
required: true
|
|
type: string
|
|
publish_nuget:
|
|
description: 'Publish NuGet packages'
|
|
type: boolean
|
|
default: true
|
|
publish_container:
|
|
description: 'Publish container image'
|
|
type: boolean
|
|
default: true
|
|
prerelease:
|
|
description: 'Mark as prerelease'
|
|
type: boolean
|
|
default: false
|
|
push:
|
|
tags:
|
|
- 'module-*-v*' # e.g., module-authority-v1.2.3
|
|
|
|
env:
|
|
DOTNET_VERSION: '10.0.100'
|
|
DOTNET_NOLOGO: 1
|
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
|
REGISTRY: git.stella-ops.org
|
|
NUGET_SOURCE: https://git.stella-ops.org/api/packages/stella-ops.org/nuget/index.json
|
|
|
|
jobs:
|
|
# ===========================================================================
|
|
# PARSE TAG (for tag-triggered builds)
|
|
# ===========================================================================
|
|
|
|
parse-tag:
|
|
name: Parse Tag
|
|
runs-on: ubuntu-22.04
|
|
if: github.event_name == 'push'
|
|
outputs:
|
|
module: ${{ steps.parse.outputs.module }}
|
|
version: ${{ steps.parse.outputs.version }}
|
|
steps:
|
|
- name: Parse module and version from tag
|
|
id: parse
|
|
run: |
|
|
TAG="${{ github.ref_name }}"
|
|
# Expected format: module-{name}-v{version}
|
|
# Example: module-authority-v1.2.3
|
|
if [[ "$TAG" =~ ^module-([a-zA-Z]+)-v([0-9]+\.[0-9]+\.[0-9]+.*)$ ]]; then
|
|
MODULE="${BASH_REMATCH[1]}"
|
|
VERSION="${BASH_REMATCH[2]}"
|
|
# Capitalize first letter
|
|
MODULE="$(echo "${MODULE:0:1}" | tr '[:lower:]' '[:upper:]')${MODULE:1}"
|
|
echo "module=$MODULE" >> "$GITHUB_OUTPUT"
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "Parsed: module=$MODULE, version=$VERSION"
|
|
else
|
|
echo "::error::Invalid tag format. Expected: module-{name}-v{version}"
|
|
exit 1
|
|
fi
|
|
|
|
# ===========================================================================
|
|
# VALIDATE
|
|
# ===========================================================================
|
|
|
|
validate:
|
|
name: Validate Inputs
|
|
runs-on: ubuntu-22.04
|
|
needs: [parse-tag]
|
|
if: always() && (needs.parse-tag.result == 'success' || needs.parse-tag.result == 'skipped')
|
|
outputs:
|
|
module: ${{ steps.resolve.outputs.module }}
|
|
version: ${{ steps.resolve.outputs.version }}
|
|
publish_nuget: ${{ steps.resolve.outputs.publish_nuget }}
|
|
publish_container: ${{ steps.resolve.outputs.publish_container }}
|
|
steps:
|
|
- name: Resolve inputs
|
|
id: resolve
|
|
run: |
|
|
if [[ "${{ github.event_name }}" == "push" ]]; then
|
|
MODULE="${{ needs.parse-tag.outputs.module }}"
|
|
VERSION="${{ needs.parse-tag.outputs.version }}"
|
|
PUBLISH_NUGET="true"
|
|
PUBLISH_CONTAINER="true"
|
|
else
|
|
MODULE="${{ github.event.inputs.module }}"
|
|
VERSION="${{ github.event.inputs.version }}"
|
|
PUBLISH_NUGET="${{ github.event.inputs.publish_nuget }}"
|
|
PUBLISH_CONTAINER="${{ github.event.inputs.publish_container }}"
|
|
fi
|
|
|
|
echo "module=$MODULE" >> "$GITHUB_OUTPUT"
|
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
echo "publish_nuget=$PUBLISH_NUGET" >> "$GITHUB_OUTPUT"
|
|
echo "publish_container=$PUBLISH_CONTAINER" >> "$GITHUB_OUTPUT"
|
|
|
|
echo "=== Resolved Configuration ==="
|
|
echo "Module: $MODULE"
|
|
echo "Version: $VERSION"
|
|
echo "Publish NuGet: $PUBLISH_NUGET"
|
|
echo "Publish Container: $PUBLISH_CONTAINER"
|
|
|
|
- name: Validate version format
|
|
run: |
|
|
VERSION="${{ steps.resolve.outputs.version }}"
|
|
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
|
|
echo "::error::Invalid version format. Expected: MAJOR.MINOR.PATCH[-prerelease]"
|
|
exit 1
|
|
fi
|
|
|
|
# ===========================================================================
|
|
# PUBLISH NUGET
|
|
# ===========================================================================
|
|
|
|
publish-nuget:
|
|
name: Publish NuGet
|
|
runs-on: ubuntu-22.04
|
|
needs: [validate]
|
|
if: needs.validate.outputs.publish_nuget == 'true'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup .NET
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Determine project path
|
|
id: path
|
|
run: |
|
|
MODULE="${{ needs.validate.outputs.module }}"
|
|
|
|
# Map module names to project paths
|
|
case "$MODULE" in
|
|
Authority)
|
|
PROJECT="src/Authority/StellaOps.Authority.WebService/StellaOps.Authority.WebService.csproj"
|
|
;;
|
|
Attestor)
|
|
PROJECT="src/Attestor/StellaOps.Attestor.WebService/StellaOps.Attestor.WebService.csproj"
|
|
;;
|
|
Concelier)
|
|
PROJECT="src/Concelier/StellaOps.Concelier.WebService/StellaOps.Concelier.WebService.csproj"
|
|
;;
|
|
Scanner)
|
|
PROJECT="src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj"
|
|
;;
|
|
Policy)
|
|
PROJECT="src/Policy/StellaOps.Policy.Gateway/StellaOps.Policy.Gateway.csproj"
|
|
;;
|
|
Signer)
|
|
PROJECT="src/Signer/StellaOps.Signer.WebService/StellaOps.Signer.WebService.csproj"
|
|
;;
|
|
Excititor)
|
|
PROJECT="src/Excititor/StellaOps.Excititor.WebService/StellaOps.Excititor.WebService.csproj"
|
|
;;
|
|
Gateway)
|
|
PROJECT="src/Gateway/StellaOps.Gateway.WebService/StellaOps.Gateway.WebService.csproj"
|
|
;;
|
|
Scheduler)
|
|
PROJECT="src/Scheduler/StellaOps.Scheduler.WebService/StellaOps.Scheduler.WebService.csproj"
|
|
;;
|
|
Orchestrator)
|
|
PROJECT="src/Orchestrator/StellaOps.Orchestrator.WebService/StellaOps.Orchestrator.WebService.csproj"
|
|
;;
|
|
TaskRunner)
|
|
PROJECT="src/TaskRunner/StellaOps.TaskRunner.WebService/StellaOps.TaskRunner.WebService.csproj"
|
|
;;
|
|
Notify)
|
|
PROJECT="src/Notify/StellaOps.Notify.WebService/StellaOps.Notify.WebService.csproj"
|
|
;;
|
|
CLI)
|
|
PROJECT="src/Cli/StellaOps.Cli/StellaOps.Cli.csproj"
|
|
;;
|
|
*)
|
|
echo "::error::Unknown module: $MODULE"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
echo "project=$PROJECT" >> "$GITHUB_OUTPUT"
|
|
echo "Project path: $PROJECT"
|
|
|
|
- name: Restore dependencies
|
|
run: dotnet restore ${{ steps.path.outputs.project }}
|
|
|
|
- name: Build
|
|
run: |
|
|
dotnet build ${{ steps.path.outputs.project }} \
|
|
--configuration Release \
|
|
--no-restore \
|
|
-p:Version=${{ needs.validate.outputs.version }}
|
|
|
|
- name: Pack NuGet
|
|
run: |
|
|
dotnet pack ${{ steps.path.outputs.project }} \
|
|
--configuration Release \
|
|
--no-build \
|
|
-p:Version=${{ needs.validate.outputs.version }} \
|
|
-p:PackageVersion=${{ needs.validate.outputs.version }} \
|
|
--output out/packages
|
|
|
|
- name: Push to Gitea NuGet registry
|
|
run: |
|
|
for nupkg in out/packages/*.nupkg; do
|
|
echo "Pushing: $nupkg"
|
|
dotnet nuget push "$nupkg" \
|
|
--source "${{ env.NUGET_SOURCE }}" \
|
|
--api-key "${{ secrets.GITEA_TOKEN }}" \
|
|
--skip-duplicate
|
|
done
|
|
|
|
- name: Upload NuGet artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: nuget-${{ needs.validate.outputs.module }}-${{ needs.validate.outputs.version }}
|
|
path: out/packages/*.nupkg
|
|
retention-days: 30
|
|
|
|
# ===========================================================================
|
|
# PUBLISH CONTAINER
|
|
# ===========================================================================
|
|
|
|
publish-container:
|
|
name: Publish Container
|
|
runs-on: ubuntu-22.04
|
|
needs: [validate]
|
|
if: needs.validate.outputs.publish_container == 'true' && needs.validate.outputs.module != 'CLI'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Log in to Gitea Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITEA_TOKEN }}
|
|
|
|
- name: Determine image name
|
|
id: image
|
|
run: |
|
|
MODULE="${{ needs.validate.outputs.module }}"
|
|
VERSION="${{ needs.validate.outputs.version }}"
|
|
MODULE_LOWER=$(echo "$MODULE" | tr '[:upper:]' '[:lower:]')
|
|
|
|
IMAGE="${{ env.REGISTRY }}/stella-ops.org/${MODULE_LOWER}"
|
|
|
|
echo "name=$IMAGE" >> "$GITHUB_OUTPUT"
|
|
echo "tag_version=${IMAGE}:${VERSION}" >> "$GITHUB_OUTPUT"
|
|
echo "tag_latest=${IMAGE}:latest" >> "$GITHUB_OUTPUT"
|
|
|
|
echo "Image: $IMAGE"
|
|
echo "Tags: ${VERSION}, latest"
|
|
|
|
- name: Build and push container
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
context: .
|
|
file: devops/docker/Dockerfile.platform
|
|
target: ${{ needs.validate.outputs.module | lower }}
|
|
push: true
|
|
tags: |
|
|
${{ steps.image.outputs.tag_version }}
|
|
${{ steps.image.outputs.tag_latest }}
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
labels: |
|
|
org.opencontainers.image.title=StellaOps ${{ needs.validate.outputs.module }}
|
|
org.opencontainers.image.version=${{ needs.validate.outputs.version }}
|
|
org.opencontainers.image.source=https://git.stella-ops.org/stella-ops.org/git.stella-ops.org
|
|
org.opencontainers.image.revision=${{ github.sha }}
|
|
|
|
# ===========================================================================
|
|
# PUBLISH CLI BINARIES (multi-platform)
|
|
# ===========================================================================
|
|
|
|
publish-cli:
|
|
name: Publish CLI (${{ matrix.runtime }})
|
|
runs-on: ubuntu-22.04
|
|
needs: [validate]
|
|
if: needs.validate.outputs.module == 'CLI'
|
|
strategy:
|
|
matrix:
|
|
runtime:
|
|
- linux-x64
|
|
- linux-arm64
|
|
- win-x64
|
|
- osx-x64
|
|
- osx-arm64
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup .NET
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Install cross-compilation tools
|
|
if: matrix.runtime == 'linux-arm64'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install -y --no-install-recommends binutils-aarch64-linux-gnu
|
|
|
|
- name: Publish CLI
|
|
run: |
|
|
dotnet publish src/Cli/StellaOps.Cli/StellaOps.Cli.csproj \
|
|
--configuration Release \
|
|
--runtime ${{ matrix.runtime }} \
|
|
--self-contained true \
|
|
-p:Version=${{ needs.validate.outputs.version }} \
|
|
-p:PublishSingleFile=true \
|
|
-p:PublishTrimmed=true \
|
|
-p:EnableCompressionInSingleFile=true \
|
|
--output out/cli/${{ matrix.runtime }}
|
|
|
|
- name: Create archive
|
|
run: |
|
|
VERSION="${{ needs.validate.outputs.version }}"
|
|
RUNTIME="${{ matrix.runtime }}"
|
|
|
|
cd out/cli/$RUNTIME
|
|
if [[ "$RUNTIME" == win-* ]]; then
|
|
zip -r ../stellaops-cli-${VERSION}-${RUNTIME}.zip .
|
|
else
|
|
tar -czvf ../stellaops-cli-${VERSION}-${RUNTIME}.tar.gz .
|
|
fi
|
|
|
|
- name: Upload CLI artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: cli-${{ needs.validate.outputs.version }}-${{ matrix.runtime }}
|
|
path: |
|
|
out/cli/*.zip
|
|
out/cli/*.tar.gz
|
|
retention-days: 30
|
|
|
|
# ===========================================================================
|
|
# SUMMARY
|
|
# ===========================================================================
|
|
|
|
summary:
|
|
name: Publish Summary
|
|
runs-on: ubuntu-22.04
|
|
needs: [validate, publish-nuget, publish-container, publish-cli]
|
|
if: always()
|
|
steps:
|
|
- name: Generate Summary
|
|
run: |
|
|
echo "## Module Publish Summary" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
|
|
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
|
echo "| Module | ${{ needs.validate.outputs.module }} |" >> $GITHUB_STEP_SUMMARY
|
|
echo "| Version | ${{ needs.validate.outputs.version }} |" >> $GITHUB_STEP_SUMMARY
|
|
echo "| NuGet | ${{ needs.publish-nuget.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
|
|
echo "| Container | ${{ needs.publish-container.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
|
|
echo "| CLI | ${{ needs.publish-cli.result || 'skipped' }} |" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "### Registry URLs" >> $GITHUB_STEP_SUMMARY
|
|
echo "- NuGet: \`${{ env.NUGET_SOURCE }}\`" >> $GITHUB_STEP_SUMMARY
|
|
echo "- Container: \`${{ env.REGISTRY }}/stella-ops.org/${{ needs.validate.outputs.module | lower }}\`" >> $GITHUB_STEP_SUMMARY
|
|
|
|
- name: Check for failures
|
|
if: contains(needs.*.result, 'failure')
|
|
run: |
|
|
echo "::error::One or more publish jobs failed"
|
|
exit 1
|