Skip to content

Publish Packages

Publish Packages #20

Workflow file for this run

name: Publish Packages
on:
release:
types: [published]
workflow_dispatch:
inputs:
package:
description: "Package to publish"
required: true
type: choice
options:
- agent-os
- agent-mesh
- agent-hypervisor
- agent-sre
- agent-compliance
- agent-runtime
- agent-lightning
- agent-governance-dotnet
- all
permissions:
contents: read
id-token: write
attestations: write
jobs:
# -------------------------------------------------------------------
# Build Python packages and attest provenance.
#
# IMPORTANT: Actual PyPI publishing is done via the ADO pipeline
# (pipelines/pypi-publish.yml) using ESRP Release. GitHub Actions
# Trusted Publishers are NOT compliant for Microsoft PyPI publishing.
# See: docs/internal/pypi-publishing.md
# -------------------------------------------------------------------
build-python:
if: ${{ github.event_name == 'release' || github.event.inputs.package != 'agent-governance-dotnet' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package:
- agent-os
- agent-mesh
- agent-hypervisor
- agent-sre
- agent-compliance
- agent-runtime
- agent-lightning
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"
- name: Install build tools
run: |
# Require hash verification — no fallback to unverified install (CWE-295)
pip install --no-cache-dir --require-hashes \
build==1.2.1 --hash=sha256:75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4
- name: Build ${{ matrix.package }}
working-directory: packages/${{ matrix.package }}
run: python -m build
- name: Validate build artifacts
working-directory: packages/${{ matrix.package }}
run: |
echo "=== Built artifacts for ${{ matrix.package }} ==="
ls -la dist/
# At least one wheel is required by Microsoft Python team policy
if ! ls dist/*.whl 1>/dev/null 2>&1; then
echo "::error::No wheel (.whl) found for ${{ matrix.package }} — at least one wheel is required"
exit 1
fi
- name: Sign release artifacts with sigstore
uses: sigstore/gh-action-sigstore-python@a5caf349bc536fbef3668a10ed7f5cd309a4b53d # v3.2.0
with:
inputs: packages/${{ matrix.package }}/dist/*
- name: Attest build provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: packages/${{ matrix.package }}/dist/*
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: pypi-${{ matrix.package }}
path: packages/${{ matrix.package }}/dist/
retention-days: 30
# -------------------------------------------------------------------
# Build npm packages, pack .tgz, and upload artifacts.
#
# IMPORTANT: Actual npm publishing is done via the ADO pipeline
# (pipelines/npm-publish.yml) using ESRP Release. GitHub Actions
# is NOT compliant for Microsoft npm publishing.
# See: PUBLISHING.md
# -------------------------------------------------------------------
build-npm:
if: ${{ github.event_name == 'release' || github.event.inputs.package == 'all' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: agentmesh-copilot-governance
path: packages/agentmesh-integrations/copilot-governance
- name: agentmesh-mastra
path: packages/agentmesh-integrations/mastra-agentmesh
- name: agentmesh-api
path: packages/agent-mesh/services/api
- name: agentmesh-mcp-proxy
path: packages/agent-mesh/packages/mcp-proxy
- name: agentmesh-sdk
path: packages/agent-mesh/sdks/typescript
- name: agent-os-copilot-extension
path: packages/agent-os/extensions/copilot
- name: agentos-mcp-server
path: packages/agent-os/extensions/mcp-server
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: "20"
- name: Install dependencies
working-directory: ${{ matrix.path }}
run: npm ci --ignore-scripts 2>/dev/null || npm install
- name: Build ${{ matrix.name }}
working-directory: ${{ matrix.path }}
run: npm run build
- name: Pack ${{ matrix.name }}
working-directory: ${{ matrix.path }}
run: |
mkdir -p tgz-output
npm pack --pack-destination tgz-output
echo "=== Packed ==="
ls -la tgz-output/
- name: Attest build provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: ${{ matrix.path }}/tgz-output/*.tgz
- name: Upload build artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: npm-${{ matrix.name }}
path: ${{ matrix.path }}/tgz-output/*.tgz
retention-days: 30
publish-nuget:
if: ${{ github.event_name == 'release' || github.event.inputs.package == 'agent-governance-dotnet' || github.event.inputs.package == 'all' }}
runs-on: ubuntu-latest
environment: nuget
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: "8.0.x"
- name: Install NuGet CLI
run: |
# Pin to specific version with SHA-256 verification (CWE-494)
NUGET_VERSION="v6.12.2"
NUGET_URL="https://dist.nuget.org/win-x86-commandline/${NUGET_VERSION}/nuget.exe"
NUGET_SHA256="64f467376f2ee364ba389461df4a29a8f8dd9aa38120d29046e70b9c82045d97"
curl -fsSL -o /usr/local/bin/nuget.exe "$NUGET_URL"
echo "${NUGET_SHA256} /usr/local/bin/nuget.exe" | sha256sum -c -
echo 'alias nuget="mono /usr/local/bin/nuget.exe"' >> ~/.bashrc
- name: Build .NET SDK
working-directory: packages/agent-governance-dotnet
run: dotnet build --configuration Release
- name: Test .NET SDK
working-directory: packages/agent-governance-dotnet
run: dotnet test --configuration Release --no-build
- name: Pack NuGet package
working-directory: packages/agent-governance-dotnet
run: dotnet pack src/AgentGovernance/AgentGovernance.csproj --configuration Release --no-build --output ./nupkg
# ----------------------------------------------------------------
# ESRP Signing — Authenticode sign DLLs + NuGet package signing
# All config sourced from GitHub Secrets:
# ESRP_AAD_ID, ESRP_KEYVAULT_NAME, ESRP_CERT_IDENTIFIER
# Key code CP-401405 is the Microsoft NuGet signing certificate.
# ESRP signing — activate when PRSS certificates are generated and uploaded to Key Vault
# ----------------------------------------------------------------
- name: Authenticode sign assemblies (ESRP)
if: ${{ env.ESRP_AAD_ID != '' }}
env:
ESRP_AAD_ID: ${{ secrets.ESRP_AAD_ID }}
ESRP_KEYVAULT_NAME: ${{ secrets.ESRP_KEYVAULT_NAME }}
run: |
echo "Submitting DLLs for Authenticode signing via ESRP..."
find packages/agent-governance-dotnet -name '*.dll' -path '*/Release/*' | head -20
echo "::warning::ESRP Authenticode signing configured — activate when PRSS certs are generated."
- name: Sign NuGet package (ESRP)
if: ${{ env.ESRP_AAD_ID != '' }}
env:
ESRP_AAD_ID: ${{ secrets.ESRP_AAD_ID }}
ESRP_KEYVAULT_NAME: ${{ secrets.ESRP_KEYVAULT_NAME }}
run: |
echo "Submitting NuGet packages for signing via ESRP..."
# ESRP signing — activate when PRSS certificates are generated and uploaded to Key Vault
# KeyCode: CP-401405
# OperationCode: NuGetSign + NuGetVerify
echo "::warning::ESRP NuGet signing configured — activate when PRSS certs are generated."
- name: Validate NuGet package metadata
working-directory: packages/agent-governance-dotnet
run: |
echo "=== Validating Microsoft NuGet compliance ==="
for pkg in ./nupkg/*.nupkg; do
echo "--- Package: $pkg ---"
dotnet nuget verify "$pkg" --all 2>/dev/null || echo "(Unsigned package — signing required before production publish)"
# Inspect package metadata
unzip -p "$pkg" '*.nuspec' | head -30
done
- name: Attest build provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: packages/agent-governance-dotnet/nupkg/*.nupkg
- name: Attest symbol package provenance
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
with:
subject-path: packages/agent-governance-dotnet/nupkg/*.snupkg
continue-on-error: true
- name: Publish to NuGet
working-directory: packages/agent-governance-dotnet
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
if [ -z "$NUGET_API_KEY" ]; then
echo "::warning::NUGET_API_KEY not set, skipping NuGet publish"
exit 0
fi
# Push both .nupkg and .snupkg (symbol package)
dotnet nuget push ./nupkg/*.nupkg --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json --skip-duplicate
echo "=== Verifying published package signature ==="
echo "Run: NuGet.exe verify -Signatures <pkg> -CertificateFingerprint 3F9001EA83C560D712C24CF213C3D312CB3BFF51EE89435D3430BD06B5D0EECE;AA12DA22A49BCE7D5C1AE64CC1F3D892F150DA76140F210ABD2CBFFCA2C18A27;566A31882BE208BE4422F7CFD66ED09F5D4524A5994F50CCC8B05EC0528C1353"