Merge feat/ultra-vpn into main
Some checks failed
Release / release (push) Failing after 0s
Release / docker (push) Has been skipped
Release / virustotal (push) Failing after 0s

VPN split-tunnel, signed self-update, security hardening, IPFS mirror
fallback, container CVE scan gate, and 0.9.1 release prep.
This commit is contained in:
Deivid Soto 2026-05-21 17:08:34 +02:00
commit d0094e84bb
39 changed files with 2099 additions and 234 deletions

52
.github/workflows/docker-rebuild.yml vendored Normal file
View file

@ -0,0 +1,52 @@
# Rebuilds and re-pushes the `latest` image without a version bump so newly
# *fixed* Alpine / ffmpeg / Go patches land between tagged releases. Versioned
# tags are immutable and never touched here. Runs weekly and on demand.
name: Docker rebuild
on:
schedule:
# Mondays 04:17 UTC (off the hour to avoid the scheduler rush)
- cron: "17 4 * * 1"
workflow_dispatch:
jobs:
rebuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
# Stamp the binary with the most recent release tag (not "dev").
- name: Resolve version
id: ver
run: echo "version=$(git describe --tags --abbrev=0 2>/dev/null || echo dev)" >> "$GITHUB_OUTPUT"
- uses: docker/setup-qemu-action@v4
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/build-push-action@v7
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
# Refresh the floating tag only — never overwrite a versioned release.
tags: torrentclaw/unarr:latest
build-args: |
VERSION=${{ steps.ver.outputs.version }}
# Force a fresh base pull so apk upgrade picks up new patches.
no-cache: true
- name: Scan image for fixable CVEs (gate)
uses: docker/scout-action@v1
with:
command: cves
image: torrentclaw/unarr:latest
only-severities: critical,high
only-fixed: true
exit-code: true

View file

@ -27,6 +27,28 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
# Empty when RELEASE_SIGNING_PUBKEY variable is unset — goreleaser
# accepts it and the resulting binary disables signature checks
# (back-compat: pre-signing releases continue to update). Set
# RELEASE_SIGNING_PUBKEY (variable) + RELEASE_SIGNING_KEY (secret)
# to turn verification on.
RELEASE_SIGNING_PUBKEY: ${{ vars.RELEASE_SIGNING_PUBKEY }}
- name: Sign checksums.txt with ed25519
# Reference secrets.X directly — step-level env defined in this same
# step is unreliable to read from this step's own if: expression.
if: ${{ vars.RELEASE_SIGNING_PUBKEY != '' && secrets.RELEASE_SIGNING_KEY != '' }}
env:
RELEASE_SIGNING_KEY: ${{ secrets.RELEASE_SIGNING_KEY }}
RELEASE_TAG: ${{ github.ref_name }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
go run ./scripts/sign-checksums \
-key "$RELEASE_SIGNING_KEY" \
-in dist/checksums.txt \
-out dist/checksums.txt.sig
gh release upload "$RELEASE_TAG" dist/checksums.txt.sig --clobber
docker:
needs: release
@ -62,6 +84,31 @@ jobs:
build-args: |
VERSION=${{ github.ref_name }}
# CVE gate. Fails the release on FIXABLE critical/high only — unfixed
# upstream ffmpeg codec CVEs are accepted (see SECURITY.md), so the
# codec noise does not block. Runs post-push (image already published);
# a failure here flags that a fixable CVE slipped through.
- name: Scan image for fixable CVEs (gate)
uses: docker/scout-action@v1
with:
command: cves
image: torrentclaw/unarr:latest
only-severities: critical,high
only-fixed: true
exit-code: true
# Sync the Docker Hub repo description from DOCKERHUB.md. Non-fatal: a
# description-API auth hiccup must not undo a successful image push.
- name: Update Docker Hub description
uses: peter-evans/dockerhub-description@v4
continue-on-error: true
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: torrentclaw/unarr
readme-filepath: ./DOCKERHUB.md
short-description: "unarr — the single binary that replaces your *arr stack"
virustotal:
needs: release