ci: add multi-platform release workflow

Implements automated build and release pipeline:
- Create GitHub releases on version tags
- Build .NET host for Windows (x64), Linux (x64), and macOS (x64/arm64)
- Package platform-specific host binaries
- Upload release artifacts via Gitea API

Supports both tag-triggered and manual workflow dispatch.
This commit is contained in:
2026-01-18 14:57:39 -05:00
parent e79fd3f281
commit a9da086587

View File

@@ -0,0 +1,297 @@
name: Build and Release Addon
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
create-release:
name: Create Release
runs-on: linux-latest
outputs:
release_id: ${{ steps.create.outputs.release_id }}
version: ${{ steps.version.outputs.version }}
steps:
- name: Get Version
id: version
run: |
TAG="${{ github.ref_name }}"
VERSION="${TAG#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Create or Get Release
id: create
run: |
TAG="${{ github.ref_name }}"
echo "Processing tag: $TAG"
# Try to get existing release
EXISTING=$(curl -s \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/tags/$TAG")
if echo "$EXISTING" | grep -q '"id":[0-9]'; then
RELEASE_ID=$(echo "$EXISTING" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
echo "Found existing release with ID: $RELEASE_ID"
else
echo "Creating new release..."
RESPONSE=$(curl -s -X POST \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"tag_name":"'"$TAG"'","name":"My First Addon '"$TAG"'","body":"My First Addon release - a demo addon showcasing GitCaddy addon features.","draft":false,"prerelease":false}' \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases")
if echo "$RESPONSE" | grep -q '"id":[0-9]'; then
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -1 | cut -d: -f2)
echo "Created release with ID: $RELEASE_ID"
else
echo "ERROR: Failed to create release"
echo "$RESPONSE"
exit 1
fi
fi
echo "release_id=$RELEASE_ID" >> $GITHUB_OUTPUT
build-host-windows:
name: Build Host (Windows x64)
needs: create-release
runs-on: windows-latest
steps:
- name: Checkout
shell: pwsh
run: |
git clone ${{ github.server_url }}/${{ github.repository }}.git .
git checkout ${{ github.sha }}
- name: Setup .NET
shell: pwsh
run: |
dotnet --version || choco install dotnet-sdk -y
- name: Build Host
shell: pwsh
run: |
cd host
dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true -o ../dist/win-x64
- name: Package Host
shell: pwsh
run: |
Compress-Archive -Path dist/win-x64/* -DestinationPath myfirst-addon-host-win-x64-${{ needs.create-release.outputs.version }}.zip
- name: Upload Host Artifact
shell: pwsh
run: |
$releaseId = "${{ needs.create-release.outputs.release_id }}"
$file = "myfirst-addon-host-win-x64-${{ needs.create-release.outputs.version }}.zip"
curl --http1.1 `
--connect-timeout 60 `
--max-time 600 `
-X POST `
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" `
-F "attachment=@$file" `
"https://direct.git.marketally.com/api/v1/repos/${{ github.repository }}/releases/$releaseId/assets?name=$file"
build-host-linux:
name: Build Host (Linux x64)
needs: create-release
runs-on: linux-latest
steps:
- name: Checkout
run: |
git clone ${{ github.server_url }}/${{ github.repository }}.git .
git checkout ${{ github.sha }}
- name: Setup .NET
run: |
wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh --channel 10.0
export PATH="$HOME/.dotnet:$PATH"
echo "PATH=$HOME/.dotnet:$PATH" >> $GITHUB_ENV
- name: Build Host
run: |
export PATH="$HOME/.dotnet:$PATH"
cd host
dotnet publish -c Release -r linux-x64 --self-contained -p:PublishSingleFile=true -o ../dist/linux-x64
- name: Package Host
run: |
chmod +x dist/linux-x64/MyFirstAddon.Host
tar -czvf myfirst-addon-host-linux-x64-${{ needs.create-release.outputs.version }}.tar.gz -C dist/linux-x64 .
- name: Upload Host Artifact
run: |
RELEASE_ID="${{ needs.create-release.outputs.release_id }}"
FILE="myfirst-addon-host-linux-x64-${{ needs.create-release.outputs.version }}.tar.gz"
curl --http1.1 \
--connect-timeout 60 \
--max-time 600 \
-X POST \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-F "attachment=@$FILE" \
"https://direct.git.marketally.com/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$FILE"
build-host-macos:
name: Build Host (macOS ${{ matrix.arch }})
needs: create-release
runs-on: macos-latest
strategy:
matrix:
include:
- arch: x64
rid: osx-x64
artifact: darwin-x64
- arch: arm64
rid: osx-arm64
artifact: darwin-arm64
steps:
- name: Checkout
run: |
git clone ${{ github.server_url }}/${{ github.repository }}.git .
git checkout ${{ github.sha }}
- name: Setup .NET
run: |
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
brew install dotnet@10 || brew upgrade dotnet@10 || true
echo "PATH=/opt/homebrew/opt/dotnet@10/bin:$PATH" >> $GITHUB_ENV
- name: Build Host
run: |
cd host
dotnet publish -c Release -r ${{ matrix.rid }} --self-contained -p:PublishSingleFile=true -o ../dist/${{ matrix.artifact }}
- name: Package Host
run: |
chmod +x dist/${{ matrix.artifact }}/MyFirstAddon.Host
tar -czvf myfirst-addon-host-${{ matrix.artifact }}-${{ needs.create-release.outputs.version }}.tar.gz -C dist/${{ matrix.artifact }} .
- name: Upload Host Artifact
run: |
RELEASE_ID="${{ needs.create-release.outputs.release_id }}"
FILE="myfirst-addon-host-${{ matrix.artifact }}-${{ needs.create-release.outputs.version }}.tar.gz"
curl --http1.1 \
--connect-timeout 60 \
--max-time 600 \
-X POST \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-F "attachment=@$FILE" \
"https://direct.git.marketally.com/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$FILE"
package-addon:
name: Package Addon
needs: [create-release, build-host-windows, build-host-linux, build-host-macos]
runs-on: linux-latest
steps:
- name: Checkout
run: |
git clone ${{ github.server_url }}/${{ github.repository }}.git .
git checkout ${{ github.sha }}
- name: Download All Host Packages
run: |
RELEASE_ID="${{ needs.create-release.outputs.release_id }}"
VERSION="${{ needs.create-release.outputs.version }}"
mkdir -p hosts
# Download each host package
for platform in win-x64 linux-x64 darwin-x64 darwin-arm64; do
if [ "$platform" = "win-x64" ]; then
EXT="zip"
else
EXT="tar.gz"
fi
echo "Downloading host for $platform..."
curl -L -o "hosts/myfirst-addon-host-$platform-$VERSION.$EXT" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
"${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets/myfirst-addon-host-$platform-$VERSION.$EXT"
done
ls -la hosts/
- name: Create Base Package (no hosts)
run: |
VERSION="${{ needs.create-release.outputs.version }}"
mkdir -p package-base
cp addon.json package-base/
cp -r main package-base/
cp -r renderer package-base/ 2>/dev/null || true
cp -r views package-base/
cp -r shared package-base/ 2>/dev/null || true
cd package-base
zip -r ../myfirst-addon-base-$VERSION.gcaddon .
- name: Create Full Package (all platforms)
run: |
VERSION="${{ needs.create-release.outputs.version }}"
mkdir -p package-full/host
cp addon.json package-full/
cp -r main package-full/
cp -r renderer package-full/ 2>/dev/null || true
cp -r views package-full/
cp -r shared package-full/ 2>/dev/null || true
# Extract all hosts
cd hosts
# Windows
mkdir -p ../package-full/host/win-x64
unzip -o myfirst-addon-host-win-x64-$VERSION.zip -d ../package-full/host/win-x64/
# Linux
mkdir -p ../package-full/host/linux-x64
tar -xzf myfirst-addon-host-linux-x64-$VERSION.tar.gz -C ../package-full/host/linux-x64/
# macOS x64
mkdir -p ../package-full/host/darwin-x64
tar -xzf myfirst-addon-host-darwin-x64-$VERSION.tar.gz -C ../package-full/host/darwin-x64/
# macOS ARM64
mkdir -p ../package-full/host/darwin-arm64
tar -xzf myfirst-addon-host-darwin-arm64-$VERSION.tar.gz -C ../package-full/host/darwin-arm64/
cd ../package-full
zip -r ../myfirst-addon-full-$VERSION.gcaddon .
- name: Upload Packages
run: |
RELEASE_ID="${{ needs.create-release.outputs.release_id }}"
VERSION="${{ needs.create-release.outputs.version }}"
upload_file() {
local file=$1
echo "Uploading $file..."
curl --http1.1 \
--connect-timeout 60 \
--max-time 1800 \
-X POST \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-F "attachment=@$file" \
"https://direct.git.marketally.com/api/v1/repos/${{ github.repository }}/releases/$RELEASE_ID/assets?name=$(basename $file)"
}
upload_file "myfirst-addon-base-$VERSION.gcaddon"
upload_file "myfirst-addon-full-$VERSION.gcaddon"
echo "Release complete!"
echo "Files uploaded:"
echo " - myfirst-addon-full-$VERSION.gcaddon (all platforms)"
echo " - myfirst-addon-base-$VERSION.gcaddon (no hosts)"
echo " - myfirst-addon-host-win-x64-$VERSION.zip"
echo " - myfirst-addon-host-linux-x64-$VERSION.tar.gz"
echo " - myfirst-addon-host-darwin-x64-$VERSION.tar.gz"
echo " - myfirst-addon-host-darwin-arm64-$VERSION.tar.gz"