Misc changes

Some misc changes.
- Moved old patch files to a `legacy` sub-folder
- If a legacy patch is used, show a warning and pause for 10 seconds
- Updated the checkout and Dockerfile so both use the same way of
  cloning the Bitwarden/client repo
- Updated the `patch_web_vault.sh` script to try and detect the vault version
- Added two new make commands to prepare and release a new version
- Added a `.env` feature for the `Makefile` to set some defaults
  Mainly used for using either `docker` or `podman` and for the GitHub
  Release script to have a predefined GPG user/key
This commit is contained in:
BlackDex 2023-12-18 17:09:47 +01:00
parent 09c7f41979
commit 0277844cf9
No known key found for this signature in database
GPG Key ID: 58C80A2AA6C765E1
47 changed files with 326 additions and 58 deletions

View File

@ -1,6 +1,7 @@
# Local build artifacts
builds
docker_builds
container_builds
web-vault
# Documentation
@ -8,6 +9,13 @@ web-vault
*.txt
# Other
.env
.github
Makefile
.vscode
# Release files
*.tar.gz
*.tar.gz.asc
*.tar.gz.text
sha256sums.txt

15
.env.template Normal file
View File

@ -0,0 +1,15 @@
# shellcheck disable=SC2034,SC2148
# ###
# Do not use quotes for these variables!
# ###
# To use either docker or podman
# The default is docker
# CONTAINER_CMD=docker
# This is only used for the gh-release command
# Which Key or User to use to signing the web-vault tar.gz file
# GPG_SIGNING_USER=user@domain.tld
# GPG_SIGNING_USER=MY_LONG_UNIQUE_GPG_KEY_IDENTIFIER
# vim: syntax=ini

View File

@ -9,6 +9,8 @@ jobs:
docker-build:
runs-on: ubuntu-latest
env:
# Force docker to output the progress in plain
BUILDKIT_PROGRESS: plain
# vars.DOCKERHUB_REPO needs to be '<user>/<repo>', for example 'vaultwarden/web-vault'
# Check for Docker hub credentials in secrets
HAVE_DOCKERHUB_LOGIN: ${{ vars.DOCKERHUB_REPO != '' && secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }}
@ -17,7 +19,7 @@ jobs:
HAVE_GHCR_LOGIN: ${{ vars.GHCR_REPO != '' && github.repository_owner != '' && secrets.GITHUB_TOKEN != '' }}
steps:
- name: Checkout
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Determine Docker Tag
- name: Init Variables
@ -32,7 +34,7 @@ jobs:
# Login to Docker Hub
- name: Login to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@ -47,7 +49,7 @@ jobs:
# Login to GitHub Container Registry
- name: Login to GitHub Container Registry
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
@ -62,7 +64,7 @@ jobs:
| tee -a "${GITHUB_ENV}"
- name: Build and push
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 # v4.0.0
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
with:
context: .
push: true

9
.gitignore vendored
View File

@ -1,6 +1,15 @@
# Local build artifacts
builds/
docker_builds/
container_builds/
web-vault/
# Other
.env
.vscode
# Release files
*.tar.gz
*.tar.gz.asc
*.tar.gz.text
sha256sums.txt

View File

@ -1,21 +1,19 @@
# Compile the web vault using docker
# Usage:
# Quick and easy:
# `make docker-extract`
# `make container-extract`
# or, if you just want to build
# `make docker`
# `make container`
# The default is to use `docker` you can also configure `podman` via a `.env` file
# See the `.env.template` file for more details
#
# docker build -t web_vault_build .
# image_id=$(docker create web_vault_build)
# docker cp $image_id:/bw_web_vault.tar.gz .
# docker rm $image_id
# docker create --name bw_web_vault_extract web_vault_build
# docker cp bw_web_vault_extract:/bw_web_vault.tar.gz .
# docker rm bw_web_vault_extract
#
# Note: you can use --build-arg to specify the version to build:
# docker build -t web_vault_build --build-arg VAULT_VERSION=master .
# image_id=$(docker create bitwardenrs/web-vault@sha256:feb3f46d15738191b9043be4cdb1be2c0078ed411e7b7be73a2f4fcbca01e13c)
# docker cp $image_id:/bw_web_vault.tar.gz .
# docker rm $image_id
# docker build -t web_vault_build --build-arg VAULT_VERSION=main .
FROM node:18-bookworm as build
RUN node --version && npm --version
@ -32,10 +30,10 @@ USER node
ARG VAULT_VERSION=8d90085607341deab976952bce8d8937cf3eefb1
WORKDIR /vault
RUN git init
RUN git remote add origin https://github.com/bitwarden/clients.git
RUN git fetch --depth 1 origin "${VAULT_VERSION}"
RUN git -c advice.detachedHead=false checkout FETCH_HEAD
RUN git -c init.defaultBranch=main init && \
git remote add origin https://github.com/bitwarden/clients.git && \
git fetch --depth 1 origin "${VAULT_VERSION}" && \
git -c advice.detachedHead=false checkout FETCH_HEAD
COPY --chown=node:node patches /patches
COPY --chown=node:node resources /resources
@ -62,6 +60,9 @@ RUN printf '{"version":"%s"}' \
RUN mv build web-vault
RUN tar -czvf "bw_web_vault.tar.gz" web-vault --owner=0 --group=0
# Output the sha256sum here so people are able to match the sha256sum from the CI with the assets and the downloaded version if needed
RUN echo "sha256sum: $(sha256sum "bw_web_vault.tar.gz")"
# We copy the final result as a separate empty image so there's no need to download all the intermediate steps
# The result is included both uncompressed and as a tar.gz, to be able to use it in the docker images and the github releases directly
FROM scratch

View File

@ -5,13 +5,35 @@ SHELL := bash
help:
@echo "Use either: clean, checkout, patch-web-vault, generate-patch, build, tar, or full"
@echo "Or for docker builds use: docker or docker-extract"
@echo "Or for container builds use: container or container-extract"
@echo
@echo "By default docker is used, you can force podman by using podman or podman-extract"
@echo "You can also define the default via a '.env' file, see the '.env.template' for details"
@echo
@echo "For releasing a new version you can use gh-prepare and gh-release"
@echo
.PHONY: help
# Load .env variables if the file exists
ifneq (,$(wildcard ./.env))
include .env
export
endif
# Force docker to output the progress in plain
BUILDKIT_PROGRESS=plain
ifndef CONTAINER_CMD
CONTAINER_CMD = docker
endif
clean:
rm -rvf "./web-vault"
rm -rvf "./builds"
rm -rvf "./docker_builds"
rm -rvf ./web-vault
rm -rvf ./builds
rm -rvf ./docker_builds
rm -rvf ./container_builds
rm -vf ./bw_web_v*.tar.gz*
rm -vf sha256sums.txt
.PHONY: clean
checkout:
@ -37,16 +59,45 @@ tar:
full: checkout patch-web-vault build tar
.PHONY: full
docker:
docker build -t bw_web_vault .
container:
${CONTAINER_CMD} build -t bw_web_vault .
.PHONY: container
container-extract: container
@${CONTAINER_CMD} rm bw_web_vault_extract 2>/dev/null || true
@${CONTAINER_CMD} create --name bw_web_vault_extract bw_web_vault
@mkdir -vp container_builds
@rm -rf ./container_builds/bw_web_vault.tar.gz ./container_builds/web-vault
@${CONTAINER_CMD} cp bw_web_vault_extract:/bw_web_vault.tar.gz ./container_builds/bw_web_vault.tar.gz
@${CONTAINER_CMD} cp bw_web_vault_extract:/web-vault ./container_builds/web-vault
@${CONTAINER_CMD} rm bw_web_vault_extract || true
.PHONY: container-extract
# Alias for container forcing docker
docker: CONTAINER_CMD := docker
docker: container
.PHONY: docker
docker-extract: docker
@docker rm bw_web_vault_extract || true
@docker create --name bw_web_vault_extract bw_web_vault
@mkdir -vp docker_builds
@rm -rf ./docker_builds/bw_web_vault.tar.gz ./docker_builds/web-vault
@docker cp bw_web_vault_extract:/bw_web_vault.tar.gz ./docker_builds/bw_web_vault.tar.gz
@docker cp bw_web_vault_extract:/web-vault ./docker_builds/web-vault
@docker rm bw_web_vault_extract || true
# Alias for container forcing docker
docker-extract: CONTAINER_CMD := docker
docker-extract: container-extract
.PHONY: docker-extract
# Alias for container forcing podman
podman: CONTAINER_CMD := podman
podman: container
.PHONY: podman
# Alias for container forcing podman
podman-extract: CONTAINER_CMD := podman
podman-extract: container-extract
.PHONY: podman-extract
# This part is used for extracing and release a new version on Github
gh-prepare:
./scripts/gh_prepare.sh
.PHONY: gh-prepare
gh-release:
./scripts/gh_release.sh
.PHONY: gh-release

View File

@ -13,16 +13,14 @@
<br>
This is a repository to store the builds of the [Bitwarden web vault](https://github.com/bitwarden/clients/tree/master/apps/web) with the patches to make it work with [vaultwarden](https://github.com/dani-garcia/vaultwarden)
This is a repository to store the builds of the [Bitwarden web vault](https://github.com/bitwarden/clients/tree/main/apps/web) with the patches to make it work with [Vaultwarden](https://github.com/dani-garcia/vaultwarden)
To create a patch you need to modify the original sources from [Bitwarden web vault](https://github.com/bitwarden/clients/tree/master/apps/web) and execute:
To create a patch you need to modify the original sources from [Bitwarden web vault](https://github.com/bitwarden/clients/tree/main/apps/web) and execute:
```bash
git --no-pager diff --submodule=diff --no-color --minimal
```
This is needed because there are patches within the jslib submodule which with a default `git diff` are not shown.
## Building the web-vault
To build the web-vault you need either node and npm installed or use Docker.
@ -34,13 +32,30 @@ make full
That will generate a `tar.gz` file within the `builds` directory which you can extract and use with the `WEB_VAULT_FOLDER` environment variable.
### Using Docker
Or via the usage of Docker:
### Using a container
Or via the usage of building via a container:
```bash
make docker-extract
make container-extract
```
That will extract the `tar.gz` and files generated via Docker into the `container_builds` directory.
#### Which container command to use, docker or podman
The default is to use `docker`, but `podman` works too.
You can force them by replacing `container` with either `docker` or `podman`, like:
```bash
make docker-extract
# Or
make podman-extract
```
You can configure the default via a `.env` file. See the `.env.template`.<br>
Or you can set it as a make argument with the make command:
```bash
make CONTAINER_CMD=podman container-extract
```
That will extract the `tar.gz` and files generated via Docker into the `docker_builds` directory.
### More information
For more information see: [Install the web-vault](https://github.com/dani-garcia/vaultwarden/wiki/Building-binary#install-the-web-vault)
@ -51,8 +66,8 @@ The builds are available in the [releases page](https://github.com/dani-garcia/b
<br>
## Get in touch
To ask a question, offer suggestions or new features or to get help configuring or installing the software, please [use the forum](https://vaultwarden.discourse.group/).
If you spot any bugs or crashes with Vaultwarden itself, please [create an issue here](https://github.com/dani-garcia/vaultwarden/issues/). Make sure there aren't any similar issues open, though!
If you spot any bugs or crashes with vaultwarden itself, please [create an issue](https://github.com/dani-garcia/vaultwarden/issues/). Make sure there aren't any similar issues open, though!
To ask a question, offer suggestions or new features or to get help configuring or installing the software, please use either [GitHub Discussions](https://github.com/dani-garcia/vaultwarden/discussions) or [the forum](https://vaultwarden.discourse.group/).
If you prefer to chat, we're usually hanging around at [#vaultwarden:matrix.org](https://matrix.to/#/#vaultwarden:matrix.org) room on Matrix. Feel free to join us!

View File

@ -12,5 +12,7 @@ function get_web_vault_version {
if [[ -z "${VAULT_VERSION}" ]]; then
VAULT_VERSION=$(git rev-parse HEAD)
fi
echo "${VAULT_VERSION#web-}"
# Remove everything up to the first occurrence of "-"
# The extracted tag could start with either `web-`, `desktop-`, `cli-` or `browser-`
echo "${VAULT_VERSION#*-}"
}

View File

@ -7,13 +7,25 @@ if [[ -z ${PATCH_NAME} ]]; then
if [ -f "../patches/${VAULT_VERSION}.patch" ]; then
echo "Exact patch file found, using that"
PATCH_NAME="${VAULT_VERSION}.patch"
elif [ -f "../patches/legacy/${VAULT_VERSION}.patch" ]; then
echo "Exact legacy patch file found, using that"
echo "NOTE: This is a Legacy patch file for an older web-vault version!"
# Sleep 10 seconds so this note might be noticed a bit better
sleep 10
PATCH_NAME="legacy/${VAULT_VERSION}.patch"
else
echo "Patch file not found, using latest"
echo "No exact patch file not found, using latest"
# If not, use the latest one
PATCH_NAME="$(find ../patches -type f -print0 | xargs -0 basename -a | sort -V | tail -n1)"
fi
fi
# Final check if the patch file exists, if not, exit
if [[ ! -f "../patches/${PATCH_NAME}" ]]; then
echo "Patch file '${PATCH_NAME}' not found in the patches directory!"
exit 1
fi
echo "Patching images"
cp -vfR ../resources/src/* ./apps/web/src/

View File

@ -16,7 +16,7 @@ trap 'handle_error $LINENO $?' ERR
# Ask for ref if not provided
if [[ -z "$VAULT_VERSION" ]]; then
read -rp "Input a git ref (commit hash, branch name, tag name, 'main'): " input
VAULT_VERSION="${input}"
VAULT_VERSION="${input:-main}"
fi
# Check the format of the provided vault version
@ -29,27 +29,28 @@ fi
echo "Using: '${VAULT_VERSION}' to checkout bitwarden/client."
if [ ! -d "${VAULT_FOLDER}" ]; then
# If this is the first time, clone the project
git clone https://github.com/bitwarden/clients.git "${VAULT_FOLDER}"
mkdir -pv "${VAULT_FOLDER}"
pushd "${VAULT_FOLDER}"
# If this is the first time, init the repo and checkout the requested branch/tag/hash
git -c init.defaultBranch=main init
git remote add origin https://github.com/bitwarden/clients.git
popd
else
# If there already is a checked-out repo, lets clean it up first.
pushd "${VAULT_FOLDER}"
# Stash current changes if there are any, we don't want to lose our work if we had some
echo "Stashing all custom changes"
git stash --include-untracked --quiet &> /dev/null || true
# Checkout the main branch first
git checkout main
# Reset hard to make sure no changes are left
git reset --hard
git checkout -f
popd
fi
# Checkout the request
pushd "${VAULT_FOLDER}"
# Update branch and tag metadata
git fetch --tags --all
git pull origin main
# Checkout the branch we want
git -c advice.detachedHead=false checkout "${VAULT_VERSION}"
# Update branch and tag metadata
git fetch --tags --depth 1 origin "${VAULT_VERSION}"
# Checkout the branch we want
git -c advice.detachedHead=false checkout FETCH_HEAD
popd

59
scripts/gh_prepare.sh Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
set -o pipefail -o errexit
# Error handling
handle_error() {
read -n1 -r -p "FAILED: line $1, exit code $2. Press any key to exit..." _
exit 1
}
trap 'handle_error $LINENO $?' ERR
if ! command -v gh >/dev/null 2>&1; then
echo "gh command not found, unable te prepare a release."
exit 1
fi
current_branch=$(git branch --show-current 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null)
if [[ -n "$current_branch" && "${current_branch}" != "master" ]]; then
echo "Current branch '$current_branch' is not the 'master' branch."
echo "Please checkout and pull the master branch before you continue."
exit 1
fi
# Ask for release tag if not provided
if [[ -z "$RELEASE_TAG" ]]; then
read -rp "Provide git release tag (example: v2023.12.0): " input
RELEASE_TAG="${input}"
fi
# Check if the RELEASE_TAG starts with vYYYY.M.B and patch letters are allowed like vYYYY.M.Ba
if [[ ! "${RELEASE_TAG}" =~ ^v20[0-9]{2}\.[0-9]{1,2}.[0-9]{1}[a-z]?$ ]]; then
echo "The provided release tag does not meet our standards!"
echo "'${RELEASE_TAG}' does not match the vYYYY.M.B format."
exit 1
fi
# Verify if the input is correct
while true; do
read -rp "Using: '${RELEASE_TAG}' as tag, continue? (y/n): " yn
case $yn in
[Yy] )
# Continue with the release
break
;;
[Nn] )
echo "Aborting release"
exit 1
;;
* ) echo "Please answer y or n"
;;
esac
done
git tag -s "${RELEASE_TAG}"
git push origin "${RELEASE_TAG}"
echo "Wait a few seconds before using gh to create a draft release"
sleep 5
gh release create "${RELEASE_TAG}" --generate-notes --draft
echo "Now wait for the container to be build and pushed before running 'make gh-release'"

78
scripts/gh_release.sh Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env bash
set -o pipefail -o errexit
# Error handling
handle_error() {
read -n1 -r -p "FAILED: line $1, exit code $2. Press any key to exit..." _
exit 1
}
trap 'handle_error $LINENO $?' ERR
if ! command -v gh >/dev/null 2>&1; then
echo "gh command not found, unable te prepare a release."
exit 1
fi
current_branch=$(git branch --show-current 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null)
if [[ -n "$current_branch" && "${current_branch}" != "master" ]]; then
echo "Current branch '$current_branch' is not the 'master' branch."
echo "Please checkout and pull the master branch before you continue."
exit 1
fi
if [[ -z "$GPG_SIGNING_USER" ]]; then
read -rp "Provide the GPG user or key which will sign the tar.gz file: " input
GPG_SIGNING_USER="${input}"
fi
if [[ -n "$GPG_SIGNING_USER" ]]; then
if ! gpg --list-keys "$GPG_SIGNING_USER" >/dev/null 2>&1; then
echo "GPG Key for '${GPG_SIGNING_USER}' not found."
exit 1
fi
fi
# Get the latest release tag, this should match the tag created with `gh-prepare`
LATEST_REMOTE_TAG="v$(git -c 'versionsort.suffix=-' ls-remote --tags --refs --sort='v:refname' https://github.com/dani-garcia/bw_web_builds.git 'v*' | tail -n1 | grep -Eo '[^\/v]*$')"
# Ask for release tag if not provided, or validate the `$LATEST_REMOTE_TAG`
if [[ -z "$RELEASE_TAG" ]]; then
read -rp "Provide git release tag (default: '${LATEST_REMOTE_TAG}'): " input
RELEASE_TAG="${input:-${LATEST_REMOTE_TAG}}"
fi
# Check if the RELEASE_TAG starts with vYYYY.M.B and patch letters are allowed like vYYYY.M.Ba
if [[ ! "${RELEASE_TAG}" =~ ^v20[0-9]{2}\.[0-9]{1,2}.[0-9]{1}[a-z]?$ ]]; then
echo "The provided release tag does not meet our standards!"
echo "'${RELEASE_TAG}' does not match the vYYYY.M.B format."
exit 1
fi
while true; do
read -rp "Using: '${RELEASE_TAG}' as tag, continue? (y/n): " yn
case $yn in
[Yy] )
# Continue with the release
break
;;
[Nn] )
echo "Aborting prepare"
exit 1
;;
* ) echo "Please answer y or n"
;;
esac
done
echo "Extracting tar.gz file from GitHub Container Registry"
${CONTAINER_CMD} create --name "bw_web_${RELEASE_TAG}" "ghcr.io/dani-garcia/bw_web_builds:${RELEASE_TAG}"
${CONTAINER_CMD} cp "bw_web_${RELEASE_TAG}:/bw_web_vault.tar.gz" "bw_web_${RELEASE_TAG}.tar.gz"
${CONTAINER_CMD} rm "bw_web_${RELEASE_TAG}"
if [[ -f "bw_web_${RELEASE_TAG}.tar.gz" ]]; then
gpg --yes --detach-sign --armor --local-user "$GPG_SIGNING_USER" --output "bw_web_${RELEASE_TAG}.tar.gz.asc" "bw_web_${RELEASE_TAG}.tar.gz"
sha256sum "bw_web_${RELEASE_TAG}.tar.gz"* | tee sha256sums.txt
gh release upload "${RELEASE_TAG}" "bw_web_${RELEASE_TAG}.tar.gz" "bw_web_${RELEASE_TAG}.tar.gz.asc" sha256sums.txt
gh release edit "${RELEASE_TAG}" --draft=false
fi

View File

@ -15,6 +15,21 @@ trap 'handle_error $LINENO $?' ERR
pushd "${VAULT_FOLDER}"
# Try to get the vault version if possible
if [[ -z ${VAULT_VERSION} ]]; then
VAULT_VERSION=$(get_web_vault_version)
fi
# Check the format of the provided vault version
# If this is web-vYYYY.M.B or YYYY.M.B then fix this automatically to prepend with a `v` or remove web
if [[ "${VAULT_VERSION}" =~ ^20[0-9]{2}\.[0-9]{1,2}.[0-9]{1} ]]; then
VAULT_VERSION="v${VAULT_VERSION}"
elif [[ "${VAULT_VERSION}" =~ ^web-v20[0-9]{2}\.[0-9]{1,2}.[0-9]{1} ]]; then
VAULT_VERSION="${VAULT_VERSION#web-}"
fi
export VAULT_VERSION
# Apply a patch from the patches directory
# shellcheck source=apply_patches.sh
. "${BASEDIR}/apply_patches.sh"