Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 44 additions & 19 deletions .github/workflows/cli-release.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
name: sw-serverless CLI release

# A tag cli-v<version> (cli-v10.2.0) publishes the sw-serverless command as self-contained
# binaries on a GitHub release: nothing needs .NET installed to run them.
# Publishes the sw-serverless command as self-contained binaries on a GitHub release: nothing needs .NET
# installed to run them. Never run by hand or by a tag: the CI run that publishes this repository
# calls it with the version it computed (determine-semver: the next patch from the git tags, the
# run number for a prerelease), so the CLI carries the version of the release it ships with.
# a release, 10.0.61 cli-v10.0.61 the latest release
# a prerelease, 10.0.61-releases-r10-0-staging.121 cli-v10.0.61-stg.121 a pre-release, to try out
# Called by nuget-publish.yml, after the packages are published.
on:
push:
tags: ["cli-v*"]
workflow_dispatch:
workflow_call:
inputs:
version:
description: "Version to release, e.g. 10.2.0 (tagged cli-v<version>)"
description: "The version the calling run computed"
type: string
required: true

permissions:
contents: write

jobs:
channel:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.channel.outputs.version }}
prerelease: ${{ steps.channel.outputs.prerelease }}
steps:
- name: Channel
id: channel
env:
VERSION: ${{ inputs.version }}
run: |
v="$VERSION"
if [[ "$v" == *-* ]]; then
# A prerelease names its branch and run: 10.0.61-releases-r10-0-staging.121 is 10.0.61-stg.121.
v="${v%%-*}-stg.${v##*.}"
echo "prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "prerelease=false" >> "$GITHUB_OUTPUT"
fi
echo "version=$v" >> "$GITHUB_OUTPUT"

build:
needs: channel
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -25,17 +51,11 @@ jobs:
- uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"
- name: Version
id: version
run: |
v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="${GITHUB_REF_NAME#cli-v}"
echo "value=$v" >> "$GITHUB_OUTPUT"
- name: Publish
run: >
dotnet publish SW.Serverless.Installer -c Release -r ${{ matrix.rid }} --self-contained
-p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:DebugType=none
-p:Version=${{ steps.version.outputs.value }} -o out
-p:Version=${{ needs.channel.outputs.version }} -o out
- name: Package
run: |
mkdir -p dist
Expand All @@ -51,10 +71,9 @@ jobs:
path: dist/*

release:
needs: build
needs: [channel, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
path: dist
Expand All @@ -64,8 +83,14 @@ jobs:
- name: Release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: |
v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="${GITHUB_REF_NAME#cli-v}"
gh release create "cli-v$v" dist/* --title "sw-serverless $v" --target "${{ github.sha }}" \
--notes "The sw-serverless command, self-contained for each platform. Install: curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/${{ github.event.repository.default_branch }}/scripts/install-cli.sh | sh — or download the archive for your platform and check it against SHA256SUMS."
v="${{ needs.channel.outputs.version }}"
install="curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install-cli.sh"
if [ "${{ needs.channel.outputs.prerelease }}" = "true" ]; then
gh release create "cli-v$v" dist/* --title "sw-serverless CLI $v (pre-release)" --target "${{ github.sha }}" --prerelease \
--notes "A pre-release of the sw-serverless command, built from ${{ github.ref_name }}, to try out. Install: $install | SW_SERVERLESS_VERSION=$v sh — or download the archive for your platform and check it against SHA256SUMS."
else
gh release create "cli-v$v" dist/* --title "sw-serverless CLI $v" --target "${{ github.sha }}" --latest \
--notes "The sw-serverless command, self-contained for each platform. Install: $install | sh — or download the archive for your platform and check it against SHA256SUMS."
fi
20 changes: 20 additions & 0 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,23 @@ jobs:
secrets:
nuget-api-key: ${{ secrets.SWNUGETKEY }}
dependabot-alerts-token: ${{ secrets.DEPENDABOT_ALERTS_TOKEN }}

# The sw-serverless CLI and the Python and Node SDKs carry the version the packages were just
# published with, so nothing is tagged by hand. From main that is a release; a run by hand on
# another branch publishes a prerelease, which releases the CLI as a pre-release and skips the SDKs.
CLI:
needs: Publish
permissions:
contents: write # creates the GitHub release
uses: ./.github/workflows/cli-release.yml
with:
version: ${{ needs.Publish.outputs.version }}

SDKs:
needs: Publish
permissions:
contents: read
uses: ./.github/workflows/sdk-release.yml
with:
version: ${{ needs.Publish.outputs.version }}
secrets: inherit
30 changes: 19 additions & 11 deletions .github/workflows/sdk-release.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
name: SDK release

# A tag sdk-v<version> (sdk-v10.2.0) publishes the Python SDK to PyPI as sw-serverless and the
# Node SDK to npm as @simplyworks/sw-serverless, at that version. Each is tested first, and a
# version already on its registry is left alone, so a failed run can simply be run again.
# Publishes the Python SDK to PyPI as sw-serverless and the Node SDK to npm as
# @simplyworks/sw-serverless. Never run by hand or by a tag: nuget-publish.yml calls it with the
# version it computed, so the SDKs carry the version of the packages they ship with. Only a release
# version is published; a prerelease (a branch build) isn't, since PyPI and npm consumers on a plain
# version range would pick it up. Each is tested first, and a version already on its registry is
# left alone, so a failed run can simply be run again.
on:
push:
tags: ["sdk-v*"]
workflow_dispatch:
workflow_call:
inputs:
version:
description: "Version to publish, e.g. 10.2.0"
description: "The version the calling run computed"
type: string
required: true

permissions:
contents: read

jobs:
python:
if: ${{ !contains(inputs.version, '-') }}
runs-on: ubuntu-latest
defaults:
run:
Expand All @@ -28,10 +31,12 @@ jobs:
python-version: "3.12"
- name: Version
id: version
env:
VERSION: ${{ inputs.version }}
run: |
v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="${GITHUB_REF_NAME#sdk-v}"
v="$VERSION"
sed -i -E "s/^version = \".*\"/version = \"$v\"/" pyproject.toml
sed -i -E "s/^SDK_VERSION = \".*\"/SDK_VERSION = \"$v\"/" src/sw_serverless/_runner.py
echo "value=$v" >> "$GITHUB_OUTPUT"
- name: Test
run: PYTHONPATH=src python -m unittest discover -s tests
Expand All @@ -46,6 +51,7 @@ jobs:
skip-existing: true

node:
if: ${{ !contains(inputs.version, '-') }}
runs-on: ubuntu-latest
defaults:
run:
Expand All @@ -58,10 +64,12 @@ jobs:
registry-url: "https://registry.npmjs.org"
- name: Version
id: version
env:
VERSION: ${{ inputs.version }}
run: |
v="${{ github.event.inputs.version }}"
[ -z "$v" ] && v="${GITHUB_REF_NAME#sdk-v}"
v="$VERSION"
npm version "$v" --no-git-tag-version --allow-same-version
sed -i -E "s/^const SDK_VERSION = \".*\";/const SDK_VERSION = \"$v\";/" src/index.js
echo "value=$v" >> "$GITHUB_OUTPUT"
- name: Test
run: node --test
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ multi-node scheduler: adapters run on the machine that runs the host.
| Tooling | NuGet `SimplyWorks.Serverless.Tooling` (`SW.Serverless.Tooling`) | What the CLI does, as a library: build, conformance tests, scaffolding, publishing. For an application that builds its own tools. |
| CLI | `sw-serverless` (project `SW.Serverless.Installer`) | `init`, `build`, `test`, `run`, `manifest validate`, `publish`, `promote`, `versions`, `withdraw`. |

The Python and Node SDKs are not on PyPI or npm yet. You do not need them there:
`sw-serverless build` copies the SDK into every Python and Node package it builds. They will be
published to PyPI and npm later.
The Python and Node SDKs are published to PyPI (`sw-serverless`) and npm (`@simplyworks/sw-serverless`)
with each release, at the packages' version. You do not need them from there: `sw-serverless build`
copies the SDK into every Python and Node package it builds.

## Install the CLI

Self-contained binaries are published on the
[GitHub releases](https://github.com/simplify9/SW-Serverless/releases) tagged `cli-v<version>`, one
[GitHub releases](https://github.com/simplify9/SW-Serverless/releases) as `cli-v<version>`, released with each version of the packages, one
per platform: `sw-serverless-<rid>.tar.gz` for `linux-x64`, `linux-arm64`, `linux-musl-x64`, `linux-musl-arm64`,
`osx-x64` and `osx-arm64`, and `sw-serverless-win-x64.zip`, with a `SHA256SUMS` file. On Linux or
macOS, the install script picks your platform, checks the download and installs to `~/.local/bin`:
Expand Down
2 changes: 1 addition & 1 deletion docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ manages published versions.
## Installing

Self-contained binaries are published on the
[GitHub releases](https://github.com/simplify9/SW-Serverless/releases) tagged `cli-v<version>`:
[GitHub releases](https://github.com/simplify9/SW-Serverless/releases) as `cli-v<version>`, released with each version of the packages:

| Platform | Asset |
|---|---|
Expand Down
3 changes: 2 additions & 1 deletion scripts/install-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ case "$arch" in
esac
rid="$os-$arch"

# The newest release; a pre-release (-stg) only when named.
if [ -n "${SW_SERVERLESS_VERSION:-}" ]; then tag="cli-v$SW_SERVERLESS_VERSION"
else tag=$(curl -fsSL "https://api.github.com/repos/$repo/releases" | grep -o '"tag_name": *"cli-v[^"]*"' | head -1 | sed 's/.*"\(cli-v[^"]*\)"/\1/'); fi
else tag=$(curl -fsSL "https://api.github.com/repos/$repo/releases" | grep -o '"tag_name": *"cli-v[^"]*"' | sed 's/.*"\(cli-v[^"]*\)"/\1/' | grep -E '^cli-v[0-9.]+$' | head -1); fi
[ -n "$tag" ] || { echo "No sw-serverless release found" >&2; exit 1; }

work=$(mktemp -d); trap 'rm -rf "$work"' EXIT
Expand Down
Loading