mirror of
https://github.com/dani-garcia/vaultwarden.wiki.git
synced 2026-08-06 21:43:44 +03:00
* Update GHA and pre-commit Signed-off-by: BlackDex <black.dex@gmail.com> * Update admin diagnostics Added a check if the templates are overridden and return which specific folder, `admin`, `email` or `scss`. This way we could more quickly point users to possible outdated templates which they are using. Also updated the Support String to use some emojis so we should be able to quicker see if there is something wrong. Just checking `true` or `false` could be difficult sometimes, and sometimes what we had as `false` wasn't bad either. Also adjusted the eslint comments so it will work with the latest version of eslint. Signed-off-by: BlackDex <black.dex@gmail.com> * Fix updating collections for a cipher The newer clients expect a `cipherDetails` response on the `collections-admin` endpoints. Without it, the client will cause an error and stops handling the update correctly. This will fix this by returning the cipher json. Fixes #7545 Fixes #7546 Signed-off-by: BlackDex <black.dex@gmail.com> * Cache CSS file in a different way Currently we set a cache ttl of 24 hours, and users need to do a force refresh if there is anything changed to the CSS file. In the past we have had several issue reported which were related to a still cached CSS file. This commit will change the caching and also cache the generated CSS file in memory. Instead of letting the browser cache it for 24 hours we generate an ETag, this is just a hash of the contents. This ETag is returned by the browser during a request, and we can match this, and if so, just return a `304` `Not Modified`. If the ETag is not known, we return the new content. This should make simple refreshes by clients get updated settings or a new version of Vaultwarden which has other CSS entries get updated instantly. If a user does a hard refresh, we will not receive the ETag and the content will be served. The same goes if someone has the `reload_templates` feature enabled, since then we should not cache anyway. If someone adjust settings via the `/admin` interface, the cache will be invalidated and a new CSS will be generated. Signed-off-by: BlackDex <black.dex@gmail.com> * Fix showing events for a specific user Signed-off-by: BlackDex <black.dex@gmail.com> * Update crates and adjust code. - Updated opendal and adjusted code where needed. - Updated yubico_ng and adjusted code where needed. This version now supports using an own HttpClient and it pulls in no reqwest dependency anymore. Now it will use our own client which uses custom hickory DNS and other features. Signed-off-by: BlackDex <black.dex@gmail.com> * Update web-vault to v2026.7.0 Signed-off-by: BlackDex <black.dex@gmail.com> * Fix hadolint warnings Signed-off-by: BlackDex <black.dex@gmail.com> --------- Signed-off-by: BlackDex <black.dex@gmail.com>
389 lines
15 KiB
YAML
389 lines
15 KiB
YAML
name: Release
|
|
permissions: {}
|
|
|
|
concurrency:
|
|
# Apply concurrency control only on the upstream repo
|
|
group: ${{ github.repository == 'dani-garcia/vaultwarden' && format('{0}-{1}', github.workflow, github.ref) || github.run_id }}
|
|
# Don't cancel other runs when creating a tag
|
|
cancel-in-progress: ${{ github.ref_type == 'branch' }}
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
tags:
|
|
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet
|
|
- '[1-2].[0-9]+.[0-9]+'
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
# A "release" environment must be created in the repository settings
|
|
# (Settings > Environments > New environment) with the following
|
|
# variables and secrets configured as needed.
|
|
#
|
|
# Variables (only set the ones for registries you want to push to):
|
|
# DOCKERHUB_REPO: 'index.docker.io/<user>/<repo>'
|
|
# QUAY_REPO: 'quay.io/<user>/<repo>'
|
|
# GHCR_REPO: 'ghcr.io/<user>/<repo>'
|
|
#
|
|
# Secrets (only required when the corresponding *_REPO variable is set):
|
|
# DOCKERHUB_REPO => DOCKERHUB_USERNAME, DOCKERHUB_TOKEN
|
|
# QUAY_REPO => QUAY_USERNAME, QUAY_TOKEN
|
|
# GITHUB_TOKEN is provided automatically
|
|
|
|
jobs:
|
|
docker-build:
|
|
name: Build Vaultwarden containers
|
|
if: ${{ github.repository == 'dani-garcia/vaultwarden' }}
|
|
environment:
|
|
name: release
|
|
deployment: false
|
|
permissions:
|
|
packages: write # Needed to upload packages and artifacts
|
|
contents: read
|
|
attestations: write # Needed to generate an artifact attestation for a build
|
|
id-token: write # Needed to mint the OIDC token necessary to request a Sigstore signing certificate
|
|
runs-on: ${{ contains(matrix.arch, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
|
|
timeout-minutes: 120
|
|
env:
|
|
SOURCE_COMMIT: ${{ github.sha }}
|
|
SOURCE_REPOSITORY_URL: "https://github.com/${{ github.repository }}"
|
|
strategy:
|
|
matrix:
|
|
arch: ["amd64", "arm64", "arm/v7", "arm/v6"]
|
|
base_image: ["debian","alpine"]
|
|
|
|
steps:
|
|
- name: Initialize QEMU binfmt support
|
|
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
|
|
with:
|
|
platforms: "arm64,arm"
|
|
|
|
# Start Docker Buildx
|
|
- name: Setup Docker Buildx
|
|
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
|
# https://github.com/moby/buildkit/issues/3969
|
|
# Also set max parallelism to 2, the default of 4 breaks GitHub Actions and causes OOMKills
|
|
with:
|
|
cache-binary: false
|
|
buildkitd-config-inline: |
|
|
[worker.oci]
|
|
max-parallelism = 2
|
|
driver-opts: |
|
|
network=host
|
|
|
|
# Checkout the repo
|
|
- name: Checkout
|
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
# We need fetch-depth of 0 so we also get all the tag metadata
|
|
with:
|
|
persist-credentials: false
|
|
fetch-depth: 0
|
|
|
|
# Normalize the architecture string for use in paths and cache keys
|
|
- name: Normalize architecture string
|
|
env:
|
|
MATRIX_ARCH: ${{ matrix.arch }}
|
|
run: |
|
|
# Replace slashes with nothing to create a safe string for paths/cache keys
|
|
NORMALIZED_ARCH="${MATRIX_ARCH//\/}"
|
|
echo "NORMALIZED_ARCH=${NORMALIZED_ARCH}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Determine Source Version
|
|
- name: Determine Source Version
|
|
run: |
|
|
# Get the Source Version for this release
|
|
GIT_EXACT_TAG="$(git describe --tags --abbrev=0 --exact-match 2>/dev/null || true)"
|
|
if [[ -n "${GIT_EXACT_TAG}" ]]; then
|
|
echo "SOURCE_VERSION=${GIT_EXACT_TAG}" | tee -a "${GITHUB_ENV}"
|
|
else
|
|
GIT_LAST_TAG="$(git describe --tags --abbrev=0)"
|
|
echo "SOURCE_VERSION=${GIT_LAST_TAG}-${SOURCE_COMMIT:0:8}" | tee -a "${GITHUB_ENV}"
|
|
fi
|
|
|
|
# Login to Docker Hub
|
|
- name: Login to Docker Hub
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
if: ${{ vars.DOCKERHUB_REPO != '' }}
|
|
|
|
- name: Add registry for DockerHub
|
|
if: ${{ vars.DOCKERHUB_REPO != '' }}
|
|
env:
|
|
DOCKERHUB_REPO: ${{ vars.DOCKERHUB_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${DOCKERHUB_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Login to GitHub Container Registry
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
if: ${{ vars.GHCR_REPO != '' }}
|
|
|
|
- name: Add registry for ghcr.io
|
|
if: ${{ vars.GHCR_REPO != '' }}
|
|
env:
|
|
GHCR_REPO: ${{ vars.GHCR_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${CONTAINER_REGISTRIES:+${CONTAINER_REGISTRIES},}${GHCR_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Login to Quay.io
|
|
- name: Login to Quay.io
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
registry: quay.io
|
|
username: ${{ secrets.QUAY_USERNAME }}
|
|
password: ${{ secrets.QUAY_TOKEN }}
|
|
if: ${{ vars.QUAY_REPO != '' }}
|
|
|
|
- name: Add registry for Quay.io
|
|
if: ${{ vars.QUAY_REPO != '' }}
|
|
env:
|
|
QUAY_REPO: ${{ vars.QUAY_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${CONTAINER_REGISTRIES:+${CONTAINER_REGISTRIES},}${QUAY_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
- name: Configure build cache from/to
|
|
env:
|
|
GHCR_REPO: ${{ vars.GHCR_REPO }}
|
|
BASE_IMAGE: ${{ matrix.base_image }}
|
|
NORMALIZED_ARCH: ${{ env.NORMALIZED_ARCH }}
|
|
run: |
|
|
#
|
|
# Check if there is a GitHub Container Registry Login and use it for caching
|
|
if [[ -n "${GHCR_REPO}" ]]; then
|
|
echo "BAKE_CACHE_FROM=type=registry,ref=${GHCR_REPO}-buildcache:${BASE_IMAGE}-${NORMALIZED_ARCH}" | tee -a "${GITHUB_ENV}"
|
|
echo "BAKE_CACHE_TO=type=registry,ref=${GHCR_REPO}-buildcache:${BASE_IMAGE}-${NORMALIZED_ARCH},compression=zstd,mode=max" | tee -a "${GITHUB_ENV}"
|
|
else
|
|
echo "BAKE_CACHE_FROM="
|
|
echo "BAKE_CACHE_TO="
|
|
fi
|
|
#
|
|
|
|
- name: Generate tags
|
|
id: tags
|
|
env:
|
|
CONTAINER_REGISTRIES: "${{ env.CONTAINER_REGISTRIES }}"
|
|
run: |
|
|
# Convert comma-separated list to newline-separated set commands
|
|
TAGS=$(echo "${CONTAINER_REGISTRIES}" | tr ',' '\n' | sed "s|.*|*.tags=&|")
|
|
|
|
# Output for use in next step
|
|
{
|
|
echo "TAGS<<EOF"
|
|
echo "$TAGS"
|
|
echo "EOF"
|
|
} >> "$GITHUB_ENV"
|
|
|
|
- name: Bake ${{ matrix.base_image }} containers
|
|
id: bake_vw
|
|
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
|
|
env:
|
|
BASE_TAGS: "${{ steps.determine-version.outputs.BASE_TAGS }}"
|
|
SOURCE_COMMIT: "${{ env.SOURCE_COMMIT }}"
|
|
SOURCE_VERSION: "${{ env.SOURCE_VERSION }}"
|
|
SOURCE_REPOSITORY_URL: "${{ env.SOURCE_REPOSITORY_URL }}"
|
|
with:
|
|
pull: true
|
|
source: .
|
|
files: docker/docker-bake.hcl
|
|
targets: "${{ matrix.base_image }}-multi"
|
|
set: |
|
|
*.cache-from=${{ env.BAKE_CACHE_FROM }}
|
|
*.cache-to=${{ env.BAKE_CACHE_TO }}
|
|
*.platform=linux/${{ matrix.arch }}
|
|
${{ env.TAGS }}
|
|
*.output=type=local,dest=./output
|
|
*.output=type=image,push-by-digest=true,name-canonical=true,push=true
|
|
|
|
- name: Extract digest SHA
|
|
env:
|
|
BAKE_METADATA: ${{ steps.bake_vw.outputs.metadata }}
|
|
BASE_IMAGE: ${{ matrix.base_image }}
|
|
run: |
|
|
GET_DIGEST_SHA="$(jq -r --arg base "$BASE_IMAGE" '.[$base + "-multi"]."containerimage.digest"' <<< "${BAKE_METADATA}")"
|
|
echo "DIGEST_SHA=${GET_DIGEST_SHA}" | tee -a "${GITHUB_ENV}"
|
|
|
|
- name: Export digest
|
|
env:
|
|
DIGEST_SHA: ${{ env.DIGEST_SHA }}
|
|
RUNNER_TEMP: ${{ runner.temp }}
|
|
run: |
|
|
mkdir -p "${RUNNER_TEMP}"/digests
|
|
digest="${DIGEST_SHA}"
|
|
touch "${RUNNER_TEMP}/digests/${digest#sha256:}"
|
|
|
|
- name: Upload digest
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: digests-${{ env.NORMALIZED_ARCH }}-${{ matrix.base_image }}
|
|
path: ${{ runner.temp }}/digests/*
|
|
if-no-files-found: error
|
|
retention-days: 1
|
|
|
|
- name: Rename binaries to match target platform
|
|
env:
|
|
NORMALIZED_ARCH: ${{ env.NORMALIZED_ARCH }}
|
|
run: |
|
|
mv ./output/vaultwarden vaultwarden-"${NORMALIZED_ARCH}"
|
|
|
|
# Upload artifacts to Github Actions and Attest the binaries
|
|
- name: Attest binaries
|
|
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
|
with:
|
|
subject-path: vaultwarden-${{ env.NORMALIZED_ARCH }}
|
|
|
|
- name: Upload binaries as artifacts
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: vaultwarden-${{ env.SOURCE_VERSION }}-linux-${{ env.NORMALIZED_ARCH }}-${{ matrix.base_image }}
|
|
path: vaultwarden-${{ env.NORMALIZED_ARCH }}
|
|
|
|
merge-manifests:
|
|
name: Merge manifests
|
|
runs-on: ubuntu-24.04
|
|
needs: docker-build
|
|
environment:
|
|
name: release
|
|
deployment: false
|
|
permissions:
|
|
packages: write # Needed to upload packages and artifacts
|
|
attestations: write # Needed to generate an artifact attestation for a build
|
|
id-token: write # Needed to mint the OIDC token necessary to request a Sigstore signing certificate
|
|
strategy:
|
|
matrix:
|
|
base_image: ["debian","alpine"]
|
|
|
|
steps:
|
|
- name: Download digests
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
path: ${{ runner.temp }}/digests
|
|
pattern: digests-*-${{ matrix.base_image }}
|
|
merge-multiple: true
|
|
|
|
# Login to Docker Hub
|
|
- name: Login to Docker Hub
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
if: ${{ vars.DOCKERHUB_REPO != '' }}
|
|
|
|
- name: Add registry for DockerHub
|
|
if: ${{ vars.DOCKERHUB_REPO != '' }}
|
|
env:
|
|
DOCKERHUB_REPO: ${{ vars.DOCKERHUB_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${DOCKERHUB_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Login to GitHub Container Registry
|
|
- name: Login to GitHub Container Registry
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
registry: ghcr.io
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
if: ${{ vars.GHCR_REPO != '' }}
|
|
|
|
- name: Add registry for ghcr.io
|
|
if: ${{ vars.GHCR_REPO != '' }}
|
|
env:
|
|
GHCR_REPO: ${{ vars.GHCR_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${CONTAINER_REGISTRIES:+${CONTAINER_REGISTRIES},}${GHCR_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Login to Quay.io
|
|
- name: Login to Quay.io
|
|
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
with:
|
|
registry: quay.io
|
|
username: ${{ secrets.QUAY_USERNAME }}
|
|
password: ${{ secrets.QUAY_TOKEN }}
|
|
if: ${{ vars.QUAY_REPO != '' }}
|
|
|
|
- name: Add registry for Quay.io
|
|
if: ${{ vars.QUAY_REPO != '' }}
|
|
env:
|
|
QUAY_REPO: ${{ vars.QUAY_REPO }}
|
|
run: |
|
|
echo "CONTAINER_REGISTRIES=${CONTAINER_REGISTRIES:+${CONTAINER_REGISTRIES},}${QUAY_REPO}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Determine Base Tags
|
|
- name: Determine Base Tags
|
|
env:
|
|
BASE_IMAGE_TAG: "${{ matrix.base_image != 'debian' && format('-{0}', matrix.base_image) || '' }}"
|
|
REF_TYPE: ${{ github.ref_type }}
|
|
run: |
|
|
# Check which main tag we are going to build determined by ref_type
|
|
if [[ "${REF_TYPE}" == "tag" ]]; then
|
|
echo "BASE_TAGS=latest${BASE_IMAGE_TAG},${GITHUB_REF#refs/*/}${BASE_IMAGE_TAG}${BASE_IMAGE_TAG//-/,}" | tee -a "${GITHUB_ENV}"
|
|
elif [[ "${REF_TYPE}" == "branch" ]]; then
|
|
echo "BASE_TAGS=testing${BASE_IMAGE_TAG}" | tee -a "${GITHUB_ENV}"
|
|
fi
|
|
|
|
- name: Create manifest list, push it and extract digest SHA
|
|
working-directory: ${{ runner.temp }}/digests
|
|
env:
|
|
BASE_TAGS: "${{ env.BASE_TAGS }}"
|
|
CONTAINER_REGISTRIES: "${{ env.CONTAINER_REGISTRIES }}"
|
|
run: |
|
|
IFS=',' read -ra IMAGES <<< "${CONTAINER_REGISTRIES}"
|
|
IFS=',' read -ra TAGS <<< "${BASE_TAGS}"
|
|
|
|
TAG_ARGS=()
|
|
for img in "${IMAGES[@]}"; do
|
|
for tag in "${TAGS[@]}"; do
|
|
TAG_ARGS+=("-t" "${img}:${tag}")
|
|
done
|
|
done
|
|
|
|
echo "Creating manifest"
|
|
if ! OUTPUT=$(docker buildx imagetools create \
|
|
"${TAG_ARGS[@]}" \
|
|
$(printf "${IMAGES[0]}@sha256:%s " *) 2>&1); then
|
|
echo "Manifest creation failed"
|
|
echo "${OUTPUT}"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Manifest created successfully"
|
|
echo "${OUTPUT}"
|
|
|
|
# Extract digest SHA for subsequent steps
|
|
GET_DIGEST_SHA="$(echo "${OUTPUT}" | grep -oE 'sha256:[a-f0-9]{64}' | tail -1)"
|
|
echo "DIGEST_SHA=${GET_DIGEST_SHA}" | tee -a "${GITHUB_ENV}"
|
|
|
|
# Attest container images
|
|
- name: Attest - docker.io - ${{ matrix.base_image }}
|
|
if: ${{ vars.DOCKERHUB_REPO != '' && env.DIGEST_SHA != ''}}
|
|
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
|
with:
|
|
subject-name: ${{ vars.DOCKERHUB_REPO }}
|
|
subject-digest: ${{ env.DIGEST_SHA }}
|
|
push-to-registry: true
|
|
|
|
- name: Attest - ghcr.io - ${{ matrix.base_image }}
|
|
if: ${{ vars.GHCR_REPO != '' && env.DIGEST_SHA != ''}}
|
|
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
|
with:
|
|
subject-name: ${{ vars.GHCR_REPO }}
|
|
subject-digest: ${{ env.DIGEST_SHA }}
|
|
push-to-registry: true
|
|
|
|
- name: Attest - quay.io - ${{ matrix.base_image }}
|
|
if: ${{ vars.QUAY_REPO != '' && env.DIGEST_SHA != ''}}
|
|
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
|
with:
|
|
subject-name: ${{ vars.QUAY_REPO }}
|
|
subject-digest: ${{ env.DIGEST_SHA }}
|
|
push-to-registry: true
|