Skip to content

ci(codeql): skip analysis on generated-file-only and bot-authored pushes #36

ci(codeql): skip analysis on generated-file-only and bot-authored pushes

ci(codeql): skip analysis on generated-file-only and bot-authored pushes #36

Workflow file for this run

name: Publish SDKs
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
version_override:
description: "Override SDK version (e.g., 0.1.0-beta.1)"
required: false
permissions:
contents: read
env:
DOTNET_VERSION: "10.0.x"
NODE_VERSION: "24"
PNPM_VERSION: "10"
jobs:
generate-spec:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
sdk_version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
cache-dependency-path: src/Web/pnpm-lock.yaml
- name: Install web dependencies
working-directory: src/Web
run: pnpm install --frozen-lockfile
- name: Build bridge package
working-directory: src/Web/packages/bridge
run: pnpm run build
- name: Restore .NET dependencies
run: dotnet restore
- name: Build API and generate OpenAPI spec
working-directory: src/API/Nocturne.API
run: dotnet build -c Release
- name: Determine SDK version
id: version
run: |
if [[ -n "${{ inputs.version_override }}" ]]; then
echo "version=${{ inputs.version_override }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then
echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
else
echo "version=0.0.0-dev.${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
fi
- name: Filter spec to V4 endpoints
run: node sdk/filter-v4-spec.js src/Web/packages/app/src/lib/api/generated/openapi.json sdk/openapi-v4.json
- name: Upload V4 OpenAPI spec
uses: actions/upload-artifact@v4
with:
name: openapi-v4-spec
path: sdk/openapi-v4.json
publish-csharp:
needs: generate-spec
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Generate C# SDK
uses: docker://openapitools/openapi-generator-cli:latest
with:
args: >-
generate
-i sdk/openapi-v4.json
-c sdk/csharp/config.yaml
-o sdk/csharp/out
--additional-properties=packageVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Fix file permissions
run: sudo chown -R $USER:$USER sdk/csharp/out
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
- name: Build and pack
working-directory: sdk/csharp/out
run: |
dotnet build -c Release
dotnet pack -c Release -o ../../../nupkg
- name: NuGet login (trusted publishing)
if: startsWith(github.ref, 'refs/tags/v')
uses: NuGet/login@v1
id: nuget-login
with:
user: rcgy
- name: Publish to NuGet
if: startsWith(github.ref, 'refs/tags/v')
run: dotnet nuget push nupkg/*.nupkg --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
publish-typescript:
needs: generate-spec
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Generate TypeScript SDK
uses: docker://openapitools/openapi-generator-cli:latest
with:
args: >-
generate
-i sdk/openapi-v4.json
-c sdk/typescript/config.yaml
-o sdk/typescript/out
--additional-properties=npmVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Fix file permissions
run: sudo chown -R $USER:$USER sdk/typescript/out
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Build
working-directory: sdk/typescript/out
run: |
npm install
npm run build
- name: Publish to npm
if: startsWith(github.ref, 'refs/tags/v')
working-directory: sdk/typescript/out
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
publish-kotlin:
needs: generate-spec
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Generate Kotlin SDK
uses: docker://openapitools/openapi-generator-cli:latest
with:
args: >-
generate
-i sdk/openapi-v4.json
-c sdk/kotlin/config.yaml
-o sdk/kotlin/out
--additional-properties=artifactVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Fix file permissions
run: |
sudo chown -R $USER:$USER sdk/kotlin/out
chmod +x sdk/kotlin/out/gradlew
- name: Apply publish overlay
run: cat sdk/kotlin/publish.gradle >> sdk/kotlin/out/build.gradle
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build and publish to local
working-directory: sdk/kotlin/out
run: ./gradlew build publishToMavenLocal
env:
SIGNING_KEY: ${{ secrets.MAVEN_SIGNING_KEY }}
SIGNING_PASSWORD: ${{ secrets.MAVEN_SIGNING_PASSWORD }}
- name: Upload to Maven Central
if: startsWith(github.ref, 'refs/tags/v')
run: |
cd ~/.m2/repository
# Generate MD5 and SHA1 checksums required by Maven Central
find org/nightscoutfoundation/nocturne -type f ! -name '*.md5' ! -name '*.sha1' ! -name 'maven-metadata-local.xml' ! -name '_remote.repositories' | while read f; do
md5sum "$f" | awk '{print $1}' > "$f.md5"
sha1sum "$f" | awk '{print $1}' > "$f.sha1"
done
zip -r $GITHUB_WORKSPACE/kotlin-bundle.zip org/nightscoutfoundation/nocturne/ -x '*/maven-metadata-local.xml' '*/_remote.repositories'
cd $GITHUB_WORKSPACE
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" \
-u "$MAVEN_USERNAME:$MAVEN_PASSWORD" \
-F "bundle=@kotlin-bundle.zip" \
"https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC")
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -1)
BODY=$(echo "$UPLOAD_RESPONSE" | head -n -1)
echo "Response: $BODY (HTTP $HTTP_CODE)"
if [ "$HTTP_CODE" -ge 400 ]; then exit 1; fi
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
publish-swift:
needs: generate-spec
runs-on: macos-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Install OpenAPI Generator
run: brew install openapi-generator
- name: Generate Swift SDK
run: |
openapi-generator generate \
-i sdk/openapi-v4.json \
-c sdk/swift/config.yaml \
-o sdk/swift/out \
--ignore-file-override sdk/swift/.openapi-generator-ignore \
--additional-properties=podVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Build
working-directory: sdk/swift/out
run: swift build
- name: Publish to nocturne-swift repo
if: startsWith(github.ref, 'refs/tags/v')
env:
SDK_DEPLOY_KEY: ${{ secrets.SWIFT_SDK_DEPLOY_KEY }}
SDK_VERSION: ${{ needs.generate-spec.outputs.sdk_version }}
run: |
# Configure SSH for the deploy key
mkdir -p ~/.ssh
echo "$SDK_DEPLOY_KEY" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
export GIT_SSH_COMMAND="ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=accept-new"
# Clone the target repo
git clone git@github.com:nightscout/nocturne-swift.git /tmp/nocturne-swift
# Replace contents with generated SDK (preserve .git)
find /tmp/nocturne-swift -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} +
cp -r sdk/swift/out/Package.swift /tmp/nocturne-swift/
cp -r sdk/swift/out/Sources /tmp/nocturne-swift/
cp -r sdk/swift/out/README.md /tmp/nocturne-swift/
# Commit and tag
cd /tmp/nocturne-swift
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
git diff --cached --quiet && echo "No changes" || git commit -m "Update SDK to v${SDK_VERSION}"
git tag -f "${SDK_VERSION}"
git push origin main
git push origin "${SDK_VERSION}"
# Cleanup
rm -f ~/.ssh/deploy_key
publish-python:
needs: generate-spec
runs-on: ubuntu-latest
environment: pypi
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Generate Python SDK
uses: docker://openapitools/openapi-generator-cli:latest
with:
args: >-
generate
-i sdk/openapi-v4.json
-c sdk/python/config.yaml
-o sdk/python/out
--additional-properties=packageVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Fix file permissions
run: sudo chown -R $USER:$USER sdk/python/out
- name: Fix package name
run: sed -i 's/^name = "nocturne_sdk"/name = "nocturne-py"/' sdk/python/out/pyproject.toml
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install and build
working-directory: sdk/python/out
run: |
pip install build
python -m build
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: sdk/python/out/dist/
publish-java:
needs: generate-spec
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download V4 spec
uses: actions/download-artifact@v4
with:
name: openapi-v4-spec
path: sdk/
- name: Generate Java SDK
uses: docker://openapitools/openapi-generator-cli:latest
with:
args: >-
generate
-i sdk/openapi-v4.json
-c sdk/java/config.yaml
-o sdk/java/out
--additional-properties=artifactVersion=${{ needs.generate-spec.outputs.sdk_version }}
- name: Fix file permissions
run: |
sudo chown -R $USER:$USER sdk/java/out
chmod +x sdk/java/out/gradlew
- name: Apply publish overlay
run: |
cat sdk/java/publish.gradle >> sdk/java/out/build.gradle
# Remove API files with multipart upload bugs (OpenAPI Generator native library issue)
rm -f sdk/java/out/src/main/java/org/nightscoutfoundation/nocturne/api/AlertCustomSoundsApi.java
rm -f sdk/java/out/src/test/java/org/nightscoutfoundation/nocturne/api/AlertCustomSoundsApiTest.java
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Build and publish to local
working-directory: sdk/java/out
run: ./gradlew build publishToMavenLocal
env:
SIGNING_KEY: ${{ secrets.MAVEN_SIGNING_KEY }}
SIGNING_PASSWORD: ${{ secrets.MAVEN_SIGNING_PASSWORD }}
- name: Upload to Maven Central
if: startsWith(github.ref, 'refs/tags/v')
run: |
cd ~/.m2/repository
# Generate MD5 and SHA1 checksums required by Maven Central
find org/nightscoutfoundation/nocturne-java -type f ! -name '*.md5' ! -name '*.sha1' ! -name 'maven-metadata-local.xml' ! -name '_remote.repositories' | while read f; do
md5sum "$f" | awk '{print $1}' > "$f.md5"
sha1sum "$f" | awk '{print $1}' > "$f.sha1"
done
zip -r $GITHUB_WORKSPACE/java-bundle.zip org/nightscoutfoundation/nocturne-java/ -x '*/maven-metadata-local.xml' '*/_remote.repositories'
cd $GITHUB_WORKSPACE
UPLOAD_RESPONSE=$(curl -s -w "\n%{http_code}" \
-u "$MAVEN_USERNAME:$MAVEN_PASSWORD" \
-F "bundle=@java-bundle.zip" \
"https://central.sonatype.com/api/v1/publisher/upload?publishingType=AUTOMATIC")
HTTP_CODE=$(echo "$UPLOAD_RESPONSE" | tail -1)
BODY=$(echo "$UPLOAD_RESPONSE" | head -n -1)
echo "Response: $BODY (HTTP $HTTP_CODE)"
if [ "$HTTP_CODE" -ge 400 ]; then exit 1; fi
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}