Skip to content

Commit 88875cd

Browse files
Nick Ficanoclaude
andcommitted
ci: add NuGet publish workflow
Publishes ARCP.FSharp (lib) and ARCP.FSharp.Cli (global tool) to nuget.org on v* tag push (or manual dispatch). Backfills license, copyright, RepositoryUrl, and PackageTags in Directory.Build.props, enables snupkg symbols and SourceLink, and packs the README into both packages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 646751f commit 88875cd

5 files changed

Lines changed: 145 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Publishes the ARCP.FSharp and ARCP.FSharp.Cli NuGet packages to nuget.org.
2+
#
3+
# Triggers:
4+
# - push of a tag matching `v*` (version is derived from the tag, minus the `v`)
5+
# - workflow_dispatch (version supplied as input)
6+
#
7+
# Required repository secret:
8+
# - NUGET_API_KEY — an API key from https://www.nuget.org/account/apikeys
9+
#
10+
# Action pinning policy:
11+
# - First-party `actions/*` actions are pinned to a major version tag (e.g. @v4).
12+
# - Any third-party action must be pinned to a full commit SHA with a
13+
# version comment. (None are currently used.)
14+
name: publish
15+
16+
on:
17+
push:
18+
tags: ["v*"]
19+
workflow_dispatch:
20+
inputs:
21+
version:
22+
description: "Package version (e.g. 0.1.0). Required for manual runs."
23+
required: true
24+
type: string
25+
26+
concurrency:
27+
group: publish-${{ github.ref }}
28+
cancel-in-progress: false
29+
30+
permissions:
31+
contents: read
32+
33+
jobs:
34+
publish:
35+
runs-on: ubuntu-latest
36+
env:
37+
DOTNET_NOLOGO: "true"
38+
DOTNET_CLI_TELEMETRY_OPTOUT: "true"
39+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "true"
40+
NUGET_XMLDOC_MODE: skip
41+
42+
steps:
43+
- name: Checkout
44+
uses: actions/checkout@v4
45+
with:
46+
# Sourcelink embeds the commit; full history isn't required but
47+
# fetch-depth: 0 makes git describe usable if we want it later.
48+
fetch-depth: 0
49+
50+
- name: Setup .NET (from global.json)
51+
uses: actions/setup-dotnet@v4
52+
with:
53+
global-json-file: global.json
54+
55+
- name: Resolve version
56+
id: version
57+
run: |
58+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
59+
VERSION="${{ inputs.version }}"
60+
else
61+
VERSION="${GITHUB_REF_NAME#v}"
62+
fi
63+
if ! printf '%s' "$VERSION" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
64+
echo "Invalid version: '$VERSION'" >&2
65+
exit 1
66+
fi
67+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
68+
echo "Publishing version: $VERSION"
69+
70+
- name: Cache NuGet packages
71+
uses: actions/cache@v4
72+
with:
73+
path: ~/.nuget/packages
74+
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.fsproj', '**/Directory.Packages.props', '**/global.json', '**/nuget.config') }}
75+
restore-keys: |
76+
${{ runner.os }}-nuget-
77+
78+
- name: Restore
79+
run: |
80+
dotnet restore src/ARCP/ARCP.fsproj
81+
dotnet restore src/ARCP.Cli/ARCP.Cli.fsproj
82+
83+
- name: Build
84+
run: |
85+
dotnet build src/ARCP/ARCP.fsproj \
86+
--configuration Release --no-restore \
87+
-p:Version=${{ steps.version.outputs.version }}
88+
dotnet build src/ARCP.Cli/ARCP.Cli.fsproj \
89+
--configuration Release --no-restore \
90+
-p:Version=${{ steps.version.outputs.version }}
91+
92+
- name: Pack
93+
run: |
94+
dotnet pack src/ARCP/ARCP.fsproj \
95+
--configuration Release --no-build \
96+
--output "${{ github.workspace }}/artifacts" \
97+
-p:Version=${{ steps.version.outputs.version }} \
98+
-p:ContinuousIntegrationBuild=true
99+
dotnet pack src/ARCP.Cli/ARCP.Cli.fsproj \
100+
--configuration Release --no-build \
101+
--output "${{ github.workspace }}/artifacts" \
102+
-p:Version=${{ steps.version.outputs.version }} \
103+
-p:ContinuousIntegrationBuild=true
104+
105+
- name: Upload packages
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: nuget-packages-${{ steps.version.outputs.version }}
109+
path: ${{ github.workspace }}/artifacts/*.*nupkg
110+
if-no-files-found: error
111+
retention-days: 30
112+
113+
- name: Push to nuget.org
114+
env:
115+
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
116+
run: >
117+
dotnet nuget push "${{ github.workspace }}/artifacts/*.nupkg"
118+
--source https://api.nuget.org/v3/index.json
119+
--api-key "$NUGET_API_KEY"
120+
--skip-duplicate

Directory.Build.props

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,22 @@
1010
<NoWarn>$(NoWarn);CS1591;FS0044</NoWarn>
1111
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
1212
<Authors>ARCP Contributors</Authors>
13+
<Company>ARCP</Company>
1314
<Product>ARCP F# SDK</Product>
1415
<Version>0.1.0</Version>
16+
<Copyright>(c) ARCP Contributors. Licensed under Apache-2.0.</Copyright>
17+
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
18+
<RepositoryUrl>https://github.com/agentruntimecontrolprotocol/fsharp-sdk</RepositoryUrl>
1519
<RepositoryType>git</RepositoryType>
20+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1621
<Description>F# reference implementation of the Agent Runtime Control Protocol (ARCP) v1.0.</Description>
22+
<PackageTags>arcp;agent;protocol;runtime;mcp;fsharp</PackageTags>
23+
<IncludeSymbols>true</IncludeSymbols>
24+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
25+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
1726
</PropertyGroup>
27+
28+
<ItemGroup>
29+
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="all" />
30+
</ItemGroup>
1831
</Project>

Directory.Packages.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
2828
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
2929
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.5.0" />
30+
<!-- Build -->
31+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
3032
</ItemGroup>
3133
</Project>

src/ARCP.Cli/ARCP.Cli.fsproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
<RootNamespace>ARCP.Cli</RootNamespace>
99
<AssemblyName>ARCP.Cli</AssemblyName>
1010
<Description>Command-line frontend for the ARCP F# SDK runtime.</Description>
11+
<PackageTags>arcp;agent;protocol;cli;dotnet-tool;fsharp</PackageTags>
12+
<PackageReadmeFile>README.md</PackageReadmeFile>
1113
</PropertyGroup>
14+
<ItemGroup>
15+
<None Include="../../README.md" Pack="true" PackagePath="\" Condition="Exists('../../README.md')" />
16+
</ItemGroup>
1217
<ItemGroup>
1318
<Compile Include="Program.fs" />
1419
</ItemGroup>

src/ARCP/ARCP.fsproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
<Description>F# reference implementation of the Agent Runtime Control Protocol (ARCP) v1.0.</Description>
66
<RootNamespace>ARCP</RootNamespace>
77
<AssemblyName>ARCP</AssemblyName>
8+
<IsPackable>true</IsPackable>
9+
<PackageReadmeFile>README.md</PackageReadmeFile>
810
</PropertyGroup>
911
<ItemGroup>
1012
<FrameworkReference Include="Microsoft.AspNetCore.App" />
1113
</ItemGroup>
1214
<ItemGroup>
1315
<EmbeddedResource Include="Resources/Schema.sql" />
1416
</ItemGroup>
17+
<ItemGroup>
18+
<None Include="../../README.md" Pack="true" PackagePath="\" Condition="Exists('../../README.md')" />
19+
</ItemGroup>
1520
<!--
1621
File order matters in F#. A file may only reference types defined earlier.
1722
The order below is the canonical dependency-first order documented in PLAN.md.

0 commit comments

Comments
 (0)