-
Notifications
You must be signed in to change notification settings - Fork 0
Add CI, packaging, and tag-driven NuGet release pipeline #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| pull_request: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| build-and-test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: 10.0.x | ||
|
|
||
| - name: Restore library | ||
| run: dotnet restore src/Community.Microsoft.Extensions.AI.CoreML/Community.Microsoft.Extensions.AI.CoreML.csproj | ||
|
|
||
| - name: Restore tests | ||
| run: dotnet restore src/Community.Microsoft.Extensions.AI.CoreML.Tests/Community.Microsoft.Extensions.AI.CoreML.Tests.csproj | ||
|
|
||
| - name: Build library | ||
| run: dotnet build src/Community.Microsoft.Extensions.AI.CoreML/Community.Microsoft.Extensions.AI.CoreML.csproj --configuration Release --no-restore | ||
|
|
||
| - name: Test | ||
| run: dotnet test src/Community.Microsoft.Extensions.AI.CoreML.Tests/Community.Microsoft.Extensions.AI.CoreML.Tests.csproj --configuration Release --no-restore | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| name: Package | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| version: | ||
| description: Package version override (for example: 1.2.3 or 1.2.3-preview1) | ||
| required: false | ||
| type: string | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: Package version override (for example: 1.2.3 or 1.2.3-preview1) | ||
| required: false | ||
| type: string | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| package: | ||
| runs-on: macos-latest-xlarge | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: 10.0.x | ||
|
|
||
| - name: Build native bridge | ||
| run: make bridge | ||
|
|
||
| - name: Pack NuGet package | ||
| shell: bash | ||
| run: | | ||
| mkdir -p artifacts/nuget | ||
| PACK_ARGS=( | ||
| "-c" "Release" | ||
| "-o" "artifacts/nuget" | ||
| "-p:ContinuousIntegrationBuild=true" | ||
| ) | ||
|
|
||
| if [ -n "${{ inputs.version }}" ]; then | ||
| PACK_ARGS+=("-p:Version=${{ inputs.version }}") | ||
|
Comment on lines
+45
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When this reusable workflow is invoked from Useful? React with 👍 / 👎. |
||
| fi | ||
|
|
||
| dotnet pack src/Community.Microsoft.Extensions.AI.CoreML/Community.Microsoft.Extensions.AI.CoreML.csproj "${PACK_ARGS[@]}" | ||
|
|
||
| - name: Upload NuGet artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: nuget-packages | ||
| path: artifacts/nuget/* | ||
| if-no-files-found: error | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| name: Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - "v*" | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| jobs: | ||
| derive-version: | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| version: ${{ steps.version.outputs.value }} | ||
| steps: | ||
| - name: Derive version from tag | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| TAG="${GITHUB_REF_NAME}" | ||
| VERSION="${TAG#v}" | ||
| if [ -z "$VERSION" ] || [ "$VERSION" = "$TAG" ]; then | ||
| echo "Tag must start with 'v' and include a version (example: v1.2.3)." >&2 | ||
| exit 1 | ||
| fi | ||
| echo "value=$VERSION" >> "$GITHUB_OUTPUT" | ||
|
|
||
| package: | ||
| needs: derive-version | ||
| uses: ./.github/workflows/package.yml | ||
| with: | ||
| version: ${{ needs.derive-version.outputs.version }} | ||
|
|
||
| publish: | ||
| needs: | ||
| - derive-version | ||
| - package | ||
| runs-on: ubuntu-latest | ||
| environment: release | ||
| steps: | ||
| - name: Download package artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: nuget-packages | ||
| path: artifacts/nuget | ||
|
|
||
| - name: Setup .NET | ||
| uses: actions/setup-dotnet@v4 | ||
| with: | ||
| dotnet-version: 10.0.x | ||
|
|
||
| - name: Publish to NuGet | ||
| shell: bash | ||
| env: | ||
| NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} | ||
| run: | | ||
| if [ -z "$NUGET_API_KEY" ]; then | ||
| echo "NUGET_API_KEY secret is required." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| shopt -s nullglob | ||
|
|
||
| for pkg in artifacts/nuget/*.nupkg; do | ||
| if [[ "$pkg" == *.snupkg ]]; then | ||
| continue | ||
| fi | ||
| dotnet nuget push "$pkg" \ | ||
| --source "https://api.nuget.org/v3/index.json" \ | ||
| --api-key "$NUGET_API_KEY" \ | ||
| --skip-duplicate | ||
| done | ||
|
|
||
| for sym in artifacts/nuget/*.snupkg; do | ||
| dotnet nuget push "$sym" \ | ||
| --source "https://api.nuget.org/v3/index.json" \ | ||
| --api-key "$NUGET_API_KEY" \ | ||
| --skip-duplicate | ||
| done | ||
|
|
||
| - name: Attach artifacts to GitHub release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| files: artifacts/nuget/* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Releasing | ||
|
|
||
| This repository ships three workflows: | ||
|
|
||
| - `CI` (`.github/workflows/ci.yml`) for restore/build/test on push and pull request. | ||
| - `Package` (`.github/workflows/package.yml`) for building the native bridge and packing NuGet artifacts. | ||
| - `Release` (`.github/workflows/release.yml`) for tag-triggered publication to NuGet. | ||
|
|
||
| ## Tagging convention | ||
|
|
||
| Release tags must start with `v` and the remainder is used as package version: | ||
|
|
||
| - `v1.2.3` -> `1.2.3` | ||
| - `v1.2.3-preview1` -> `1.2.3-preview1` | ||
|
|
||
| ## Required repository configuration | ||
|
|
||
| ### Secrets | ||
|
|
||
| - `NUGET_API_KEY` (repository or environment secret): API key with permission to publish `Community.Microsoft.Extensions.AI.CoreML` on NuGet.org. | ||
|
|
||
| ### Environment | ||
|
|
||
| - Environment name: `release` (used by `release.yml`). | ||
| - Recommended: configure required reviewers on the `release` environment for gated production publishes. | ||
|
|
||
| ### Runner requirement | ||
|
|
||
| The package/release flow requires an Apple Silicon macOS runner label: `macos-latest-xlarge`. | ||
|
|
||
| ## How to cut a release | ||
|
|
||
| 1. Ensure `CI` is green on `main`. | ||
| 2. Create and push a tag using the release version format (`vX.Y.Z` or `vX.Y.Z-suffix`). | ||
| 3. Wait for the `Release` workflow to finish. | ||
| 4. Verify: | ||
| - NuGet package and symbols are published. | ||
| - Artifacts are attached to the GitHub release. |
Uh oh!
There was an error while loading. Please reload this page.