Skip to content

v0.54.1 Dependencies versions updated #13

v0.54.1 Dependencies versions updated

v0.54.1 Dependencies versions updated #13

Workflow file for this run

name: Release Builds
on:
release:
types: [published]
permissions:
contents: write
jobs:
test-and-update-badges:
if: startsWith(github.event.release.tag_name, 'v')
runs-on: ubuntu-latest
steps:
- name: Checkout default branch
uses: actions/checkout@v6
with:
ref: ${{ github.event.repository.default_branch }}
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Install Linux test dependencies
shell: bash
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y build-essential pkg-config xorg-dev libgl1-mesa-dev
- name: Run tests with coverage
id: tests
continue-on-error: true
shell: bash
env:
CGO_ENABLED: "1"
run: |
set -euo pipefail
go test ./... -coverprofile=coverage.out -covermode=atomic
- name: Build badges and update README
id: badges
shell: bash
env:
RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
set -euo pipefail
if [[ "${{ steps.tests.outcome }}" == "success" ]]; then
test_status="Passed"
test_color="green"
else
test_status="Failed"
test_color="red"
fi
coverage="0.0"
if [[ -f coverage.out ]]; then
coverage="$(go tool cover -func=coverage.out | awk '/^total:/ {print $3}' | tr -d '%')"
fi
coverage="$(awk -v c="$coverage" 'BEGIN {printf "%.1f", c + 0}')"
if awk -v c="$coverage" 'BEGIN {exit !(c >= 70)}'; then
coverage_color="green"
elif awk -v c="$coverage" 'BEGIN {exit !(c >= 50)}'; then
coverage_color="yellow"
else
coverage_color="red"
fi
coverage_label="${coverage}%25"
test_badge="https://img.shields.io/badge/Tests-${test_status}-${test_color}?labelColor=gray&logo=github"
coverage_badge="https://img.shields.io/badge/Tests%20Coverage-${coverage_label}-${coverage_color}?labelColor=gray&logo=gitextensions"
test_line="[![Tests passed](${test_badge})](${RUN_URL})"
coverage_line=" [![Tests coverage](${coverage_badge})](${RUN_URL})"
awk -v test_line="$test_line" -v coverage_line="$coverage_line" '
{
if ($0 ~ /\[Tests passed\]/) {
print test_line
next
}
if ($0 ~ /\[Tests coverage\]/) {
print coverage_line
next
}
print
}
' README.md > README.tmp && mv README.tmp README.md
- name: Commit README badge updates
continue-on-error: true
shell: bash
run: |
set -euo pipefail
if git diff --quiet -- README.md; then
echo "README.md already up to date"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add README.md
git commit -m "docs: update release test and coverage badges"
git push
- name: Report failed tests for badges
if: steps.tests.outcome != 'success'
shell: bash
run: echo "Tests failed in badge job; badges were updated to reflect failure."
build:
strategy:
fail-fast: false
matrix:
include:
- runner: windows-latest
goos: windows
goarch: amd64
- runner: windows-latest
goos: windows
goarch: arm64
- runner: ubuntu-latest
goos: linux
goarch: amd64
- runner: ubuntu-24.04-arm
goos: linux
goarch: arm64
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Parse release version from tag
id: version
shell: pwsh
run: |
$raw = "${{ github.ref_name }}"
$version = $raw -replace '^v\.?', ''
if ($version -notmatch '^\d+\.\d+\.\d+$') {
throw "Tag '$raw' is invalid. Expected vX.Y.Z or v.X.Y.Z"
}
"version=$version" >> $env:GITHUB_OUTPUT
- name: Compute naming metadata
id: meta
shell: pwsh
run: |
$goarch = "${{ matrix.goarch }}"
if ($goarch -eq "amd64") {
$assetArch = "x86_64"
$debArch = "amd64"
} elseif ($goarch -eq "arm64") {
$assetArch = "arm64"
$debArch = "arm64"
} else {
throw "Unsupported goarch: $goarch"
}
"asset_arch=$assetArch" >> $env:GITHUB_OUTPUT
"deb_arch=$debArch" >> $env:GITHUB_OUTPUT
- name: Install Linux build dependencies
if: matrix.goos == 'linux'
shell: bash
run: |
set -euo pipefail
sudo apt-get update
if [ "${{ matrix.goarch }}" = "arm64" ]; then
sudo dpkg --add-architecture arm64
sudo apt-get update
sudo apt-get install -y \
build-essential pkg-config dpkg-dev lintian \
gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross \
libgl1-mesa-dev:arm64 libx11-dev:arm64 libxcursor-dev:arm64 \
libxinerama-dev:arm64 libxi-dev:arm64 libxrandr-dev:arm64 \
libxxf86vm-dev:arm64
else
sudo apt-get install -y build-essential pkg-config xorg-dev libgl1-mesa-dev dpkg-dev lintian
fi
- name: Install LLVM-MinGW toolchain for Windows ARM64 cross build
if: matrix.goos == 'windows' && matrix.goarch == 'arm64'
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$version = '20250114'
$zipName = "llvm-mingw-$version-ucrt-x86_64.zip"
$url = "https://github.com/mstorsjo/llvm-mingw/releases/download/$version/$zipName"
Invoke-WebRequest -Uri $url -OutFile $zipName
Expand-Archive -Path $zipName -DestinationPath . -Force
$toolchain = Join-Path $PWD "llvm-mingw-$version-ucrt-x86_64"
if (-not (Test-Path $toolchain)) {
throw "LLVM-MinGW toolchain directory not found: $toolchain"
}
"$(Join-Path $toolchain 'bin')" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Build binary
shell: pwsh
env:
CGO_ENABLED: "1"
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
VERSION: ${{ steps.version.outputs.version }}
ASSET_ARCH: ${{ steps.meta.outputs.asset_arch }}
run: |
New-Item -ItemType Directory -Force -Path dist | Out-Null
if ($env:GOOS -eq "linux" -and $env:GOARCH -eq "arm64") {
$env:CC = "aarch64-linux-gnu-gcc"
$env:CXX = "aarch64-linux-gnu-g++"
$env:PKG_CONFIG_LIBDIR = "/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig"
}
if ($env:GOOS -eq "windows" -and $env:GOARCH -eq "arm64") {
$cc = Get-Command aarch64-w64-mingw32-clang -ErrorAction SilentlyContinue
$cxx = Get-Command aarch64-w64-mingw32-clang++ -ErrorAction SilentlyContinue
if (-not $cc -or -not $cxx) {
throw "aarch64-w64-mingw32-clang/clang++ are required for Windows ARM64 build"
}
$env:CC = "aarch64-w64-mingw32-clang"
$env:CXX = "aarch64-w64-mingw32-clang++"
}
if ($env:GOOS -eq "windows") {
$out = "dist/eris_${env:VERSION}_windows_${env:ASSET_ARCH}.exe"
go build -trimpath -ldflags "-s -w -H=windowsgui" -o $out .
} else {
$out = "dist/eris_${env:VERSION}_linux_${env:ASSET_ARCH}"
go build -trimpath -buildmode=pie -ldflags "-s -w" -o $out .
}
- name: Smoke test Windows binary
if: matrix.goos == 'windows' && matrix.goarch == 'amd64'
shell: pwsh
env:
VERSION: ${{ steps.version.outputs.version }}
ASSET_ARCH: ${{ steps.meta.outputs.asset_arch }}
run: |
$ErrorActionPreference = 'Stop'
$exe = "dist/eris_${env:VERSION}_windows_${env:ASSET_ARCH}.exe"
$p = Start-Process -FilePath $exe -PassThru
Start-Sleep -Seconds 5
$alive = Get-Process -Id $p.Id -ErrorAction SilentlyContinue
if (-not $alive) {
throw "Binary exited immediately: $exe"
}
Stop-Process -Id $p.Id -Force
- name: Validate Windows ARM64 artifact exists
if: matrix.goos == 'windows' && matrix.goarch == 'arm64'
shell: pwsh
env:
VERSION: ${{ steps.version.outputs.version }}
ASSET_ARCH: ${{ steps.meta.outputs.asset_arch }}
run: |
$ErrorActionPreference = 'Stop'
$exe = "dist/eris_${env:VERSION}_windows_${env:ASSET_ARCH}.exe"
if (-not (Test-Path $exe)) {
throw "Expected artifact not found: $exe"
}
$size = (Get-Item $exe).Length
if ($size -le 0) {
throw "Artifact is empty: $exe"
}
- name: Package Linux binary archive
if: matrix.goos == 'linux'
shell: bash
env:
VERSION: ${{ steps.version.outputs.version }}
ASSET_ARCH: ${{ steps.meta.outputs.asset_arch }}
run: |
set -euo pipefail
bin="dist/eris_${VERSION}_linux_${ASSET_ARCH}"
chmod +x "${bin}"
tar -C dist -czf "dist/eris_${VERSION}_linux_${ASSET_ARCH}.tar.gz" "$(basename "${bin}")"
- name: Build Debian package
if: matrix.goos == 'linux'
shell: bash
env:
VERSION: ${{ steps.version.outputs.version }}
DEB_ARCH: ${{ steps.meta.outputs.deb_arch }}
ASSET_ARCH: ${{ steps.meta.outputs.asset_arch }}
run: |
set -euo pipefail
rendered_control="pkg/control_${DEB_ARCH}.txt"
mkdir -p pkg
sed \
-e "s/__VERSION__/${VERSION}/g" \
-e "s/__ARCH__/${DEB_ARCH}/g" \
packaging/debian/control.template > "${rendered_control}"
PKG_NAME="$(awk -F': ' '/^Package:/ {print $2}' "${rendered_control}")"
PKG_MAINTAINER="$(awk -F': ' '/^Maintainer:/ {print $2}' "${rendered_control}")"
PKG_HOMEPAGE="$(awk -F': ' '/^Homepage:/ {print $2}' "${rendered_control}")"
PKG_DESC_SHORT="$(awk -F': ' '/^Description:/ {print $2}' "${rendered_control}")"
PKG_DESC_SHORT_ESCAPED="$(printf '%s' "${PKG_DESC_SHORT}" | sed -e 's/[\\/&]/\\\\&/g')"
pkgroot="pkg/${PKG_NAME}_${VERSION}_${DEB_ARCH}"
mkdir -p "${pkgroot}/DEBIAN"
mkdir -p "${pkgroot}/usr/bin"
mkdir -p "${pkgroot}/usr/share/applications"
mkdir -p "${pkgroot}/usr/share/icons/hicolor/512x512/apps"
mkdir -p "${pkgroot}/usr/share/doc/${PKG_NAME}"
mkdir -p "${pkgroot}/usr/share/man/man1"
install -m 0755 "dist/eris_${VERSION}_linux_${ASSET_ARCH}" "${pkgroot}/usr/bin/${PKG_NAME}"
install -m 0644 icon512.png "${pkgroot}/usr/share/icons/hicolor/512x512/apps/${PKG_NAME}.png"
install -m 0644 README.md "${pkgroot}/usr/share/doc/${PKG_NAME}/README.md"
{
printf '%s\n' '.TH ERIS 1 "$(date +%Y-%m-%d)" "Eris" "User Commands"'
printf '%s\n' '.SH NAME'
printf '%s\n' 'eris - OpenPGP desktop workstation'
printf '%s\n' '.SH SYNOPSIS'
printf '%s\n' '\\fBeris\\fR'
printf '%s\n' '.SH DESCRIPTION'
printf '%s\n' 'Eris is a desktop application for encrypted vault storage and OpenPGP workflows.'
printf '%s\n' '.SH AUTHOR'
printf '%s\n' "${PKG_MAINTAINER}"
} > "${pkgroot}/usr/share/man/man1/${PKG_NAME}.1"
gzip -n -9 "${pkgroot}/usr/share/man/man1/${PKG_NAME}.1"
sed \
-e "s/__APP_NAME__/Eris/g" \
-e "s/__APP_COMMENT__/${PKG_DESC_SHORT_ESCAPED}/g" \
-e "s/__APP_BIN__/${PKG_NAME}/g" \
-e "s/__APP_ICON__/${PKG_NAME}/g" \
packaging/eris.desktop > "${pkgroot}/usr/share/applications/${PKG_NAME}.desktop"
install -m 0644 "${rendered_control}" "${pkgroot}/DEBIAN/control"
{
printf '%s\n' "${PKG_NAME} (${VERSION}) unstable; urgency=medium"
printf '\n'
printf '%s\n' " * Automated release build."
printf '\n'
printf '%s\n' " -- ${PKG_MAINTAINER} $(date -R)"
} > "${pkgroot}/usr/share/doc/${PKG_NAME}/changelog"
gzip -n -9 "${pkgroot}/usr/share/doc/${PKG_NAME}/changelog"
if [ -f LICENSE ]; then
install -m 0644 LICENSE "${pkgroot}/usr/share/doc/${PKG_NAME}/copyright"
else
{
printf '%s\n' 'MIT License'
printf '\n'
printf '%s\n' 'Copyright (c) 2026 Nicolas Altmann'
printf '\n'
printf '%s\n' 'Permission is hereby granted, free of charge, to any person obtaining a copy'
printf '%s\n' 'of this software and associated documentation files (the "Software"), to deal'
printf '%s\n' 'in the Software without restriction, including without limitation the rights'
printf '%s\n' 'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell'
printf '%s\n' 'copies of the Software, and to permit persons to whom the Software is'
printf '%s\n' 'furnished to do so, subject to the following conditions:'
printf '\n'
printf '%s\n' 'The above copyright notice and this permission notice shall be included in all'
printf '%s\n' 'copies or substantial portions of the Software.'
printf '\n'
printf '%s\n' 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR'
printf '%s\n' 'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,'
printf '%s\n' 'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE'
printf '%s\n' 'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER'
printf '%s\n' 'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,'
printf '%s\n' 'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE'
printf '%s\n' 'SOFTWARE.'
} > "${pkgroot}/usr/share/doc/${PKG_NAME}/copyright"
fi
{
printf '%s\n' 'Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/'
printf '%s\n' "Upstream-Name: ${PKG_NAME}"
printf '%s\n' "Source: ${PKG_HOMEPAGE}"
printf '\n'
printf '%s\n' 'Files: *'
printf '%s\n' 'Copyright: 2026 Nicolas Altmann'
printf '%s\n' 'License: MIT'
printf '%s\n' " See /usr/share/doc/${PKG_NAME}/copyright for full MIT license text."
} > "${pkgroot}/usr/share/doc/${PKG_NAME}/upstream"
dpkg-deb --build --root-owner-group "${pkgroot}" "dist/${PKG_NAME}_${VERSION}_linux_${ASSET_ARCH}.deb"
lintian "dist/${PKG_NAME}_${VERSION}_linux_${ASSET_ARCH}.deb"
- name: Upload release assets
uses: softprops/action-gh-release@v3
with:
files: dist/*
fail_on_unmatched_files: true
publish-winget:
name: Publish to WinGet
needs: build
runs-on: ubuntu-latest
if: ${{ !github.event.release.draft && vars.WINGET_PACKAGE_IDENTIFIER != '' }}
env:
WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }}
steps:
- name: Skip WinGet publish (missing token)
if: ${{ env.WINGET_TOKEN == '' }}
run: echo "WINGET_TOKEN is not configured; skipping WinGet publish"
- name: Publish to WinGet Community Repo
if: ${{ env.WINGET_TOKEN != '' }}
uses: vedantmgoyal9/winget-releaser@v2
with:
identifier: ${{ vars.WINGET_PACKAGE_IDENTIFIER }}
installers-regex: '_windows_(x86_64|arm64)\.exe$'
release-tag: ${{ github.event.release.tag_name }}
token: ${{ env.WINGET_TOKEN }}