256 lines
10 KiB
YAML
256 lines
10 KiB
YAML
name: release
|
|
|
|
on:
|
|
push:
|
|
tags: ["v*"]
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
|
|
|
jobs:
|
|
create-release:
|
|
runs-on: linux
|
|
outputs:
|
|
version: ${{ steps.meta.outputs.version }}
|
|
tag: ${{ steps.meta.outputs.tag }}
|
|
release_id: ${{ steps.release.outputs.id }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- id: meta
|
|
name: Версия из CMakeLists.txt и сверка с тегом
|
|
run: |
|
|
version=$(sed -nE 's/^project\(BiLauncher VERSION ([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' CMakeLists.txt)
|
|
[ -n "$version" ] || { echo "Не нашёл project(BiLauncher VERSION ...)"; exit 1; }
|
|
tag=""
|
|
if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
|
|
tag="${GITHUB_REF_NAME}"
|
|
base="${tag#v}"; base="${base%%-*}"
|
|
if [ "$base" != "$version" ]; then
|
|
echo "Тег $tag не совпадает с версией $version в CMakeLists.txt"; exit 1
|
|
fi
|
|
version="${tag#v}"
|
|
fi
|
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
echo "tag=$tag" >> "$GITHUB_OUTPUT"
|
|
echo "Версия: $version, тег: ${tag:-нет}"
|
|
|
|
- id: release
|
|
name: Черновик релиза
|
|
if: steps.meta.outputs.tag != ''
|
|
env:
|
|
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
TAG: ${{ steps.meta.outputs.tag }}
|
|
run: |
|
|
base="${TAG#v}"; base="${base%%-*}"
|
|
notes=$(awk -v v="$base" '
|
|
/^## \[/ { if (on) exit; if (index($0, "[" v "]")) { on=1; next } }
|
|
on' CHANGELOG.md)
|
|
prerelease=false; case "$TAG" in *-*) prerelease=true;; esac
|
|
body=$(python3 -c 'import json,sys; print(json.dumps({"tag_name":sys.argv[1],"name":"BiLauncher "+sys.argv[1],"body":sys.argv[2],"draft":True,"prerelease":sys.argv[3]=="true"}))' \
|
|
"$TAG" "$notes" "$prerelease")
|
|
id=$(curl -fsS -X POST "$API/releases" \
|
|
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
|
-d "$body" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
|
|
echo "id=$id" >> "$GITHUB_OUTPUT"
|
|
echo "Создан черновик релиза $TAG (id $id)"
|
|
|
|
build-linux:
|
|
needs: create-release
|
|
runs-on: linux
|
|
env:
|
|
VERSION: ${{ needs.create-release.outputs.version }}
|
|
RELEASE_ID: ${{ needs.create-release.outputs.release_id }}
|
|
outputs:
|
|
sums: ${{ steps.pack.outputs.sums }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Сборка
|
|
run: |
|
|
export PATH="$QT_TOOLS/CMake/bin:$QT_TOOLS/Ninja:$PATH"
|
|
rm -rf build AppDir dist
|
|
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_PREFIX_PATH="$QT_ROOT" \
|
|
-DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib
|
|
cmake --build build -j 8
|
|
cmake --install build --prefix "$PWD/AppDir/usr"
|
|
|
|
- id: pack
|
|
name: AppImage и tar.gz
|
|
run: |
|
|
mkdir -p dist
|
|
cp AppDir/usr/share/applications/bilauncher.desktop AppDir/
|
|
cp AppDir/usr/share/icons/hicolor/256x256/apps/bilauncher.png AppDir/
|
|
ln -sf usr/bin/BiLauncher AppDir/AppRun
|
|
ARCH=x86_64 appimagetool --no-appstream AppDir "dist/BiLauncher-$VERSION-x86_64.AppImage"
|
|
cp -a AppDir/usr "BiLauncher-$VERSION"
|
|
tar -czf "dist/BiLauncher-$VERSION-linux-x86_64.tar.gz" "BiLauncher-$VERSION"
|
|
rm -rf "BiLauncher-$VERSION"
|
|
ls -lh dist
|
|
echo "sums=$(cd dist && sha256sum * | base64 -w0)" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Загрузка в релиз
|
|
if: env.RELEASE_ID != ''
|
|
env:
|
|
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
run: |
|
|
for f in dist/*; do
|
|
curl -fsS -X POST -H "Authorization: token $TOKEN" \
|
|
-F "attachment=@$f" "$API/releases/$RELEASE_ID/assets?name=$(basename "$f")" > /dev/null
|
|
echo "Загружен $(basename "$f")"
|
|
done
|
|
|
|
- name: Артефакты прогона
|
|
if: env.RELEASE_ID == ''
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: linux
|
|
path: dist/
|
|
|
|
build-windows:
|
|
needs: create-release
|
|
runs-on: windows
|
|
env:
|
|
VERSION: ${{ needs.create-release.outputs.version }}
|
|
RELEASE_ID: ${{ needs.create-release.outputs.release_id }}
|
|
outputs:
|
|
sums: ${{ steps.build.outputs.sums }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- id: build
|
|
name: Сборка, установщик и portable-архив
|
|
shell: powershell
|
|
run: |
|
|
$ErrorActionPreference = "Stop"
|
|
$build = "C:\r\bl-build"; $stage = "C:\r\bl-stage"; $dist = "$PWD\dist"
|
|
Remove-Item -Recurse -Force $build, $stage, $dist -ErrorAction SilentlyContinue
|
|
|
|
$vs = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * `
|
|
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
|
Import-Module "$vs\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
|
|
Enter-VsDevShell -VsInstallPath $vs -SkipAutomaticLocation -DevCmdArguments "-arch=x64 -host_arch=x64"
|
|
$env:PATH = "$env:QT_TOOLS\CMake_64\bin;$env:QT_TOOLS\Ninja;$env:PATH"
|
|
|
|
cmake -S . -B $build -G Ninja -DCMAKE_BUILD_TYPE=Release "-DCMAKE_PREFIX_PATH=$env:QT_ROOT"
|
|
if ($LASTEXITCODE) { throw "cmake configure" }
|
|
cmake --build $build
|
|
if ($LASTEXITCODE) { throw "cmake build" }
|
|
cmake --install $build --prefix $stage
|
|
if ($LASTEXITCODE) { throw "cmake install" }
|
|
|
|
New-Item -ItemType Directory -Force $dist | Out-Null
|
|
& "$env:ISCC_DIR\ISCC.exe" /Q "/DAppVersion=$env:VERSION" "/DSourceDir=$stage" "/DOutputDir=$dist" packaging\windows\BiLauncher.iss
|
|
if ($LASTEXITCODE) { throw "iscc" }
|
|
|
|
Remove-Item "$stage\bin\vc_redist.x64.exe" -ErrorAction SilentlyContinue
|
|
$portable = "C:\r\BiLauncher-$env:VERSION"
|
|
Remove-Item -Recurse -Force $portable -ErrorAction SilentlyContinue
|
|
Move-Item $stage $portable
|
|
& "$env:SystemRoot\System32\tar.exe" -a -c -f "$dist\BiLauncher-$env:VERSION-win64-portable.zip" -C C:\r "BiLauncher-$env:VERSION"
|
|
if ($LASTEXITCODE) { throw "zip" }
|
|
Remove-Item -Recurse -Force $portable
|
|
|
|
Get-ChildItem $dist | Format-Table Name, Length
|
|
$sums = Get-ChildItem $dist | ForEach-Object {
|
|
"{0} {1}" -f (Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower(), $_.Name }
|
|
$b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes(($sums -join "`n") + "`n"))
|
|
[IO.File]::AppendAllText($env:GITHUB_OUTPUT, "sums=$b64`n")
|
|
|
|
- name: Загрузка в релиз
|
|
if: env.RELEASE_ID != ''
|
|
shell: powershell
|
|
env:
|
|
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
run: |
|
|
foreach ($f in Get-ChildItem dist) {
|
|
curl.exe -fsS -X POST -H "Authorization: token $env:TOKEN" `
|
|
-F "attachment=@$($f.FullName)" "$env:API/releases/$env:RELEASE_ID/assets?name=$($f.Name)" | Out-Null
|
|
if ($LASTEXITCODE) { throw "Не удалось загрузить $($f.Name)" }
|
|
"Загружен $($f.Name)"
|
|
}
|
|
|
|
- name: Артефакты прогона
|
|
if: env.RELEASE_ID == ''
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: windows
|
|
path: dist/
|
|
|
|
build-macos:
|
|
needs: create-release
|
|
runs-on: macos
|
|
env:
|
|
VERSION: ${{ needs.create-release.outputs.version }}
|
|
RELEASE_ID: ${{ needs.create-release.outputs.release_id }}
|
|
outputs:
|
|
sums: ${{ steps.pack.outputs.sums }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Сборка (universal, arm64 + x86_64)
|
|
run: |
|
|
export PATH="$QT_TOOLS/CMake/CMake.app/Contents/bin:$QT_TOOLS/Ninja:$PATH"
|
|
rm -rf build stage dist dmgroot
|
|
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_PREFIX_PATH="$QT_ROOT" \
|
|
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
|
cmake --build build
|
|
cmake --install build --prefix "$PWD/stage"
|
|
|
|
- id: pack
|
|
name: Ad-hoc подпись и DMG
|
|
run: |
|
|
codesign --force --deep --sign - stage/BiLauncher.app
|
|
codesign --verify --deep --strict stage/BiLauncher.app
|
|
mkdir -p dmgroot dist
|
|
cp -R stage/BiLauncher.app dmgroot/
|
|
ln -s /Applications dmgroot/Applications
|
|
hdiutil create -volname "BiLauncher" -srcfolder dmgroot -ov -format UDZO \
|
|
"dist/BiLauncher-$VERSION-macOS-universal.dmg"
|
|
rm -rf dmgroot
|
|
ls -lh dist
|
|
echo "sums=$(cd dist && shasum -a 256 * | base64 | tr -d '\n')" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Загрузка в релиз
|
|
if: env.RELEASE_ID != ''
|
|
env:
|
|
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
run: |
|
|
for f in dist/*; do
|
|
curl -fsS -X POST -H "Authorization: token $TOKEN" \
|
|
-F "attachment=@$f" "$API/releases/$RELEASE_ID/assets?name=$(basename "$f")" > /dev/null
|
|
echo "Загружен $(basename "$f")"
|
|
done
|
|
|
|
- name: Артефакты прогона
|
|
if: env.RELEASE_ID == ''
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: macos
|
|
path: dist/
|
|
|
|
publish:
|
|
needs: [create-release, build-linux, build-windows, build-macos]
|
|
if: needs.create-release.outputs.release_id != ''
|
|
runs-on: linux
|
|
env:
|
|
RELEASE_ID: ${{ needs.create-release.outputs.release_id }}
|
|
TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
steps:
|
|
- name: SHA256SUMS.txt и публикация
|
|
run: |
|
|
{
|
|
echo "${{ needs.build-windows.outputs.sums }}" | base64 -d
|
|
echo "${{ needs.build-linux.outputs.sums }}" | base64 -d
|
|
echo "${{ needs.build-macos.outputs.sums }}" | base64 -d
|
|
} | tr -d '\r' | sed '/^$/d' > SHA256SUMS.txt
|
|
cat SHA256SUMS.txt
|
|
curl -fsS -X POST -H "Authorization: token $TOKEN" \
|
|
-F "attachment=@SHA256SUMS.txt" "$API/releases/$RELEASE_ID/assets?name=SHA256SUMS.txt" > /dev/null
|
|
curl -fsS -X PATCH -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
|
-d '{"draft": false}' "$API/releases/$RELEASE_ID" > /dev/null
|
|
echo "Релиз опубликован"
|