Skip to content

feat(auth): passwordless WebAuthn / passkey login #472

feat(auth): passwordless WebAuthn / passkey login

feat(auth): passwordless WebAuthn / passkey login #472

Workflow file for this run

name: Build and Push Docker Images
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
workflow_dispatch:
inputs:
docker:
description: 'Docker image to build'
required: false
default: 'all'
type: choice
options:
- all
- lnvps-api
- lnvps-api-admin
- lnvps-operator
- lnvps-nostr
- lnvps-host-info
env:
REGISTRY: registry.v0l.io
HOST_INFO_IMAGE: registry.v0l.io/lnvps-host-info
jobs:
# Decide, once, what tag to publish and whether to push:
# * master push -> :latest (rolling dev images)
# * tag push (v*) -> :<version> (immutable release images, e.g. 0.3.2)
# * PR / other dispatch -> build only, no push
setup:
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.image_tag }}
push: ${{ steps.meta.outputs.push }}
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Compute image tag + push flag
id: meta
run: |
if [ "${{ github.event_name }}" = "push" ] && [[ "${{ github.ref }}" == refs/tags/v* ]]; then
# Release tag: strip the leading 'v' so the image tag matches the crate version.
TAG="${GITHUB_REF_NAME#v}"
# Guard: the root workspace version MUST match the release tag, so
# the published images are never mislabelled vs their crate version.
VER=$(awk '/^\[workspace.package\]/{f=1} f&&/^version[[:space:]]*=/{gsub(/.*=[[:space:]]*"|".*/,"");print;exit}' Cargo.toml)
if [ "$VER" != "$TAG" ]; then
echo "::error::root Cargo.toml [workspace.package] version ($VER) != release tag ($TAG). Bump the version before tagging."
exit 1
fi
echo "image_tag=$TAG" >> "$GITHUB_OUTPUT"
echo "push=true" >> "$GITHUB_OUTPUT"
elif [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/master" ]; then
echo "image_tag=latest" >> "$GITHUB_OUTPUT"
echo "push=true" >> "$GITHUB_OUTPUT"
else
echo "image_tag=latest" >> "$GITHUB_OUTPUT"
echo "push=false" >> "$GITHUB_OUTPUT"
fi
# Build host-info as a multi-arch image first
build-host-info:
runs-on: ubuntu-latest
needs: setup
if: >
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.docker == 'lnvps-host-info' || github.event.inputs.docker == 'all'))
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up QEMU
if: needs.setup.outputs.push == 'true'
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Registry
if: needs.setup.outputs.push == 'true'
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 5
retry_wait_seconds: 15
# SYN drops in the AVS/GSL scrubbing path randomly kill handshakes
# under concurrent CI logins; retry to ride over transient drops.
command: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ${{ env.REGISTRY }} -u registry --password-stdin
- name: Build and push lnvps-host-info
uses: docker/build-push-action@v6
with:
context: lnvps_host_util
file: lnvps_host_util/Dockerfile
platforms: ${{ needs.setup.outputs.push == 'true' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
push: ${{ needs.setup.outputs.push == 'true' }}
tags: ${{ env.HOST_INFO_IMAGE }}:${{ needs.setup.outputs.image_tag }}
cache-from: type=gha,scope=host-info
cache-to: type=gha,mode=max,scope=host-info
# Build main images after host-info is ready
build:
runs-on: ubuntu-latest
needs: [setup, build-host-info]
if: >
always() && (
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
github.event_name == 'workflow_dispatch'
)
strategy:
fail-fast: false
# Limit concurrent registry logins/pushes so we don't trip the
# DDoS-mitigation SYN-rate limiter (AVS behind GSL) with a burst.
max-parallel: 2
matrix:
include:
- name: lnvps-api
file: lnvps_api/Dockerfile
image: registry.v0l.io/lnvps-api
- name: lnvps-api-admin
file: lnvps_api_admin/Dockerfile
image: registry.v0l.io/lnvps-api-admin
- name: lnvps-operator
file: lnvps_operator/Dockerfile
image: registry.v0l.io/lnvps-operator
- name: lnvps-nostr
file: lnvps_nostr/Dockerfile
image: registry.v0l.io/lnvps-nostr
- name: lnvps-agent
file: lnvps_agent/Dockerfile
image: registry.v0l.io/lnvps-agent
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to Docker Registry
if: needs.setup.outputs.push == 'true'
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 5
retry_wait_seconds: 15
# SYN drops in the AVS/GSL scrubbing path randomly kill handshakes
# under concurrent CI logins; retry to ride over transient drops.
command: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ${{ env.REGISTRY }} -u registry --password-stdin
- name: Build and push ${{ matrix.name }}
if: >
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && (github.event.inputs.docker == matrix.name || github.event.inputs.docker == 'all'))
uses: docker/build-push-action@v6
with:
context: .
file: ${{ matrix.file }}
push: ${{ needs.setup.outputs.push == 'true' }}
tags: ${{ matrix.image }}:${{ needs.setup.outputs.image_tag }}
cache-from: type=gha,scope=${{ matrix.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.name }}
build-args: |
HOST_INFO_IMAGE=${{ env.HOST_INFO_IMAGE }}:${{ needs.setup.outputs.image_tag }}
REGISTRY_USER=registry
REGISTRY_PASS=${{ secrets.REGISTRY_TOKEN }}