Merge pull request 'publish the plugin zip to artifactapi on tag' (#4) from benvin/release-pipeline into main
ci/woodpecker/tag/release Pipeline was successful

Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
2026-09-19 23:52:47 +10:00
2 changed files with 105 additions and 15 deletions
+74
View File
@@ -0,0 +1,74 @@
when:
- event: tag
ref: refs/tags/v*
steps:
# Everything runs on almalinux9-base: JPRM installs from the artifactapi pypi
# remote and the publish below PUTs to artifactapi, both over https against
# the internal CA. The Microsoft SDK image does not trust that CA (curl 60),
# so the dotnet build has to come to the image that does rather than the
# other way round.
- name: package
image: git.unkin.net/unkin/almalinux9-base:20260606
environment:
DOTNET_CLI_TELEMETRY_OPTOUT: "1"
DOTNET_NOLOGO: "1"
commands:
- |
set -eu
VERSION=$$(sed -n 's/^version: *"\([0-9.]*\)".*/\1/p' build.yaml | head -1)
if [ "v$$VERSION" != "$$CI_COMMIT_TAG" ]; then
echo "tag $$CI_COMMIT_TAG does not match build.yaml version $$VERSION; use make patch/minor/major/hotfix"
exit 1
fi
dnf -y -q install dotnet-sdk-10.0 python3-pip zip
pip3 install --quiet --index-url https://artifactapi.k8s.syd1.au.unkin.net/api/v1/remote/pypi/simple "jprm==1.1.0"
mkdir -p dist
jprm plugin build . --output ./dist --version "$$VERSION" --dotnet-configuration Release --dotnet-framework net10.0
ls -l dist
backend_options:
kubernetes:
serviceAccountName: jellyfin-plugin-sso
resources:
requests:
memory: 2Gi
cpu: 1
limits:
memory: 4Gi
cpu: 2
# Uploads are immutable (409 on overwrite) and artifactapi has no HEAD route,
# so probe with GET and treat an existing object as a no-op re-run.
- name: publish
image: git.unkin.net/unkin/almalinux9-base:20260606
commands:
- |
set -eu
HOST="https://artifactapi.k8s.syd1.au.unkin.net"
REPO="jellyfin-plugins"
ZIP=$$(ls dist/sso-authentication_*.zip | head -1)
VERSION=$$(echo "$$CI_COMMIT_TAG" | sed 's/^v//')
PATH_IN_REPO="unkin/jellyfin-plugin-sso/$$VERSION/$$(basename "$$ZIP")"
code=$$(curl -s -o /dev/null -w '%{http_code}' "$$HOST/api/v2/remotes/$$REPO/files/$$PATH_IN_REPO" || true)
if [ "$$code" = "200" ]; then
echo "$$PATH_IN_REPO already published (HTTP $$code); skipping upload"
exit 0
fi
echo "Uploading $$ZIP to $$REPO/$$PATH_IN_REPO (existence probe returned $$code)"
curl -f -X PUT \
"$$HOST/api/v2/remotes/$$REPO/files/$$PATH_IN_REPO" \
-H "Content-Type: application/zip" \
--data-binary @"$$ZIP"
echo
sha256sum "$$ZIP"
depends_on: [package]
backend_options:
kubernetes:
serviceAccountName: jellyfin-plugin-sso
resources:
requests:
memory: 256Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 1
+31 -15
View File
@@ -1,4 +1,4 @@
.PHONY: build test lint clean patch minor major
.PHONY: build test lint clean patch minor major hotfix
SLN ?= SSO-Auth.sln
@@ -16,20 +16,36 @@ clean:
dotnet clean $(SLN) -c Release || true
rm -rf SSO-Auth/bin SSO-Auth/obj tests/SSO-Auth.Tests/bin tests/SSO-Auth.Tests/obj
_LATEST := $(shell git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$$' | head -1)
_BASE := $(if $(_LATEST),$(_LATEST),v0.0.0)
_MAJ := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f1)
_MIN := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f2)
_PAT := $(shell echo $(_BASE) | sed 's/^v//' | cut -d. -f3)
# Jellyfin plugin versions are 4-part (System.Version in the plugin manifest),
# so build.yaml holds the version and the release tag must be exactly
# v<that version>; .woodpecker/release.yaml fails the build if they diverge.
_CUR := $(shell sed -n 's/^version: *"\([0-9.]*\)".*/\1/p' build.yaml | head -1)
_A := $(or $(word 1,$(subst ., ,$(_CUR))),0)
_B := $(or $(word 2,$(subst ., ,$(_CUR))),0)
_C := $(or $(word 3,$(subst ., ,$(_CUR))),0)
_D := $(or $(word 4,$(subst ., ,$(_CUR))),0)
patch:
@NEW=v$(_MAJ).$(_MIN).$(shell expr $(_PAT) + 1); \
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
minor:
@NEW=v$(_MAJ).$(shell expr $(_MIN) + 1).0; \
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
define release
@test -n "$(_CUR)" || { echo "cannot parse version from build.yaml"; exit 1; }
@test -z "$$(git status --porcelain)" || { echo "working tree is dirty"; exit 1; }
@sed -i 's|^version: .*|version: "$(1)"|' build.yaml
@sed -i 's|<AssemblyVersion>[^<]*</AssemblyVersion>|<AssemblyVersion>$(1)</AssemblyVersion>|' SSO-Auth/SSO-Auth.csproj
@sed -i 's|<FileVersion>[^<]*</FileVersion>|<FileVersion>$(1)</FileVersion>|' SSO-Auth/SSO-Auth.csproj
@git commit -qam "release $(1)"
@git tag v$(1)
@git push origin HEAD v$(1)
@echo "Released v$(1)"
endef
major:
@NEW=v$(shell expr $(_MAJ) + 1).0.0; \
git tag $$NEW && echo "Tagged $$NEW" && git push origin $$NEW
$(call release,$(shell expr $(_A) + 1).0.0.0)
minor:
$(call release,$(_A).$(shell expr $(_B) + 1).0.0)
patch:
$(call release,$(_A).$(_B).$(shell expr $(_C) + 1).0)
# Fourth component: a rebuild of an existing patch (upstream's 3.5.2.1 shape).
hotfix:
$(call release,$(_A).$(_B).$(_C).$(shell expr $(_D) + 1))