vault/.github/actions/build-vault/action.yml
Vault Automation e7965c8bdf
[VAULT-41294] docker: build OCI container images (#11545) (#11549)
This change does a few things that might not be obvious:

- We stop requesting the previous runner image. This will result in us
  using Docker 29 instead of 28. With this comes changes in our
  container build system, most notably that container images are now
  exported as OCI images. Every container runtime that we support also
  supports OCI images so this ought to have no meaningful impact to
  downstream users. One noticeable change is that the image layers are
  now compressed so the final image size on disk will be considerably
  smaller than before.

- Upgrade `hashicorp/action-setup-enos` to the latest version. This is not
  strictly required for this change but as we just released a new version of
  the CLI it makes sense to update it here. We should also note that recently
  we released a new version of `terraform-provider-enos` which contains
  necessary for this change as our docker and kind resources needed to be
  updated handle OCI and Docker exported images. Previously they relied on
  files that existed only in Docker images.

Signed-off-by: Ryan Cragun <me@ryan.ec>
Co-authored-by: Ryan Cragun <me@ryan.ec>
2025-12-29 10:58:02 -08:00

274 lines
12 KiB
YAML

# Copyright IBM Corp. 2016, 2025
# SPDX-License-Identifier: BUSL-1.1
---
name: Build Vault
description: |
Build various Vault binaries and package them into Zip bundles, Deb and RPM packages,
and various container images. Upload the resulting artifacts to Github Actions artifact storage.
This composite action is used across both CE and Ent, thus is should maintain compatibility with
both repositories.
inputs:
github-token:
description: An elevated Github token to access private Go modules if necessary.
default: ""
cgo-enabled:
description: Enable or disable CGO during the build.
default: "0"
create-docker-container:
description: Package the binary into a Docker/AWS container.
default: "true"
create-redhat-container:
description: Package the binary into a Redhat container.
default: "false"
create-packages:
description: Package the binaries into deb and rpm formats.
default: "true"
goos:
description: The Go GOOS value environment variable to set during the build.
goarch:
description: The Go GOARCH value environment variable to set during the build.
goarm:
description: The Go GOARM value environment variable to set during the build.
default: ""
goexperiment:
description: Which Go experiments to enable.
default: ""
go-tags:
description: A comma separated list of tags to pass to the Go compiler during build.
default: ""
package-name:
description: The name to use for the linux packages.
default: ${{ github.event.repository.name }}
vault-binary-name:
description: The name of the vault binary.
default: vault
vault-edition:
description: The edition of vault to build.
vault-version:
description: The version metadata to inject into the build via the linker.
web-ui-cache-key:
description: The cache key for restoring the pre-built web UI artifact.
outputs:
vault-binary-path:
description: The location of the built binary.
value: ${{ steps.containerize.outputs.vault-binary-path != '' && steps.containerize.outputs.vault-binary-path || steps.metadata.outputs.binary-path }}
runs:
using: composite
steps:
- id: set-up-go
uses: ./.github/actions/set-up-go
with:
github-token: ${{ inputs.github-token }}
- uses: ./.github/actions/install-tools # sets env.VAULT_TOOLS_PATH
- if: inputs.vault-edition != 'ce'
name: Configure Git
shell: bash
run: git config --global url."https://${{ inputs.github-token }}:@github.com".insteadOf "https://github.com"
- name: Restore UI from cache
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5.0.1
with:
# Restore the UI asset from the UI build workflow. Never use a partial restore key.
enableCrossOsArchive: true
fail-on-cache-miss: true
path: http/web_ui
key: ${{ inputs.web-ui-cache-key }}
- name: Metadata
id: metadata
env:
# We need these for the artifact basename helper
GOARCH: ${{ inputs.goarch }}
GOOS: ${{ inputs.goos }}
VERSION: ${{ inputs.vault-version }}
VERSION_METADATA: ${{ inputs.vault-edition != 'ce' && inputs.vault-edition || '' }}
shell: bash
run: |
if [[ '${{ inputs.vault-edition }}' =~ 'ce' ]]; then
build_step_name='Vault ${{ inputs.goos }} ${{ inputs.goarch }} v${{ inputs.vault-version }}'
package_version='${{ inputs.vault-version }}'
linux_package_license='BUSL-1.1'
else
build_step_name='Vault ${{ inputs.goos }} ${{ inputs.goarch }} v${{ inputs.vault-version }}+${{ inputs.vault-edition }}'
package_version='${{ inputs.vault-version }}+ent' # this should always be +ent here regardless of enterprise edition
linux_package_license='IPLA'
fi
# Generate a builder cache key that considers anything that might change
# our build container, including:
# - The Go version we're building with
# - External Go build tooling as defined in tools/tools.sh
# - The Dockerfile or .build directory
# - The build-vault Github action
docker_sha=$(git ls-tree HEAD Dockerfile --object-only --abbrev=5)
build_sha=$(git ls-tree HEAD .build --object-only --abbrev=5)
tools_sha=$(git ls-tree HEAD tools/tools.sh --object-only --abbrev=5)
github_sha=$(git ls-tree HEAD .github/actions/build-vault --object-only --abbrev=5)
{
echo "artifact-basename=$(make ci-get-artifact-basename)"
echo "binary-path=dist/${{ inputs.vault-binary-name }}"
echo "build-step-name=${build_step_name}"
echo "vault-builder-cache-key=${docker_sha}-${build_sha}-${tools_sha}-${github_sha}-$(cat .go-version)"
echo "package-version=${package_version}"
echo "linux_package_license=${linux_package_license}"
} | tee -a "$GITHUB_OUTPUT"
- if: inputs.vault-edition != 'ce'
id: build-vault-select-license
uses: hashicorp-forge/actions-pao-tool/select-license@6997f7457c338e008506005cc370e7b02f7fb421 # v1.0.3
with:
arch: ${{ matrix.goarch }}
- if: inputs.cgo-enabled == '0'
name: ${{ steps.metadata.outputs.build-step-name }}
env:
CGO_ENABLED: 0
GO_TAGS: ${{ inputs.go-tags }}
GOARCH: ${{ inputs.goarch }}
GOARM: ${{ inputs.goarm }}
GOOS: ${{ inputs.goos }}
GOEXPERIMENT: ${{ inputs.goexperiment }}
GOPRIVATE: github.com/hashicorp
VERSION: ${{ inputs.version }}
VERSION_METADATA: ${{ inputs.vault-edition != 'ce' && inputs.vault-edition || '' }}
shell: bash
run: make ci-build
- if: inputs.cgo-enabled == '1'
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
with:
driver-opts: network=host # So we can run our own little registry
- if: inputs.cgo-enabled == '1'
shell: bash
run: docker run -d -p 5000:5000 --restart always --name registry registry:2
- name: Build CGO builder image
if: inputs.cgo-enabled == '1'
id: build-push-action-attempt-1
continue-on-error: true # we will retry this if it fails
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
env:
DOCKER_BUILD_SUMMARY: false
with:
context: .
build-args: |
GO_VERSION=${{ steps.set-up-go.outputs.go-version }}
# Only build a container for the host OS since the same container
# handles cross building.
platforms: linux/amd64
push: true
target: builder
tags: localhost:5000/vault-builder:${{ steps.metadata.outputs.vault-builder-cache-key }}
# Upload the resulting minimal image to actions cache. This could
# be a problem if the resulting images are too big.
cache-from: type=gha,scope=vault-builder-${{ steps.metadata.outputs.vault-builder-cache-key }}
cache-to: type=gha,mode=min,scope=vault-builder-${{ steps.metadata.outputs.vault-builder-cache-key }}
github-token: ${{ inputs.github-token }}
- name: Build CGO builder image
id: build-push-action-attempt-2
continue-on-error: false
if: inputs.cgo-enabled == '1' && steps.build-push-action-attempt-1.outcome != 'success'
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
env:
DOCKER_BUILD_SUMMARY: false
with:
context: .
build-args: |
GO_VERSION=${{ steps.set-up-go.outputs.go-version }}
# Only build a container for the host OS since the same container
# handles cross building.
platforms: linux/amd64
push: true
target: builder
tags: localhost:5000/vault-builder:${{ steps.metadata.outputs.vault-builder-cache-key }}
# Upload the resulting minimal image to actions cache. This could
# be a problem if the resulting images are too big.
cache-from: type=gha,scope=vault-builder-${{ steps.metadata.outputs.vault-builder-cache-key }}
cache-to: type=gha,mode=min,scope=vault-builder-${{ steps.metadata.outputs.vault-builder-cache-key }}
github-token: ${{ inputs.github-token }}
- if: inputs.cgo-enabled == '1'
name: ${{ steps.metadata.outputs.build-step-name }}
shell: bash
run: |
mkdir -p dist
mkdir -p out
docker run \
-v $(pwd):/build \
-v ${VAULT_TOOLS_PATH}:/opt/tools/bin \
-v $(go env GOMODCACHE):/go-mod-cache \
--env GITHUB_TOKEN='${{ inputs.github-token }}' \
--env CGO_ENABLED=1 \
--env GO_TAGS='${{ inputs.go-tags }}' \
--env GOARCH='${{ inputs.goarch }}' \
--env GOARM='${{ inputs.goarm }}' \
--env GOEXPERIMENT='${{ inputs.goexperiment }}' \
--env GOMODCACHE=/go-mod-cache \
--env GOOS='${{ inputs.goos }}' \
--env VERSION='${{ inputs.version }}' \
--env VERSION_METADATA='${{ inputs.vault-edition != 'ce' && inputs.vault-edition || '' }}' \
localhost:5000/vault-builder:${{ steps.metadata.outputs.vault-builder-cache-key }} \
make ci-build
- if: inputs.vault-edition != 'ce'
shell: bash
run: make ci-prepare-ent-legal
env:
LICENSE_DIR: "${{ steps.build-vault-select-license.outputs.license-path }}/Softcopy"
- if: inputs.vault-edition == 'ce'
shell: bash
run: make ci-prepare-ce-legal
- name: Bundle Vault
env:
BUNDLE_PATH: out/${{ steps.metadata.outputs.artifact-basename }}.zip
shell: bash
run: make ci-bundle
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ steps.metadata.outputs.artifact-basename }}.zip
path: out/${{ steps.metadata.outputs.artifact-basename }}.zip
if-no-files-found: error
- if: inputs.create-packages == 'true'
uses: hashicorp/actions-packaging-linux@33f7d23b14f24e6a7b7d9948cb7f5caca2045ee3
with:
name: ${{ inputs.package-name }}
description: Vault is a tool for secrets management, encryption as a service, and privileged access management.
arch: ${{ inputs.goarch }}
version: ${{ steps.metadata.outputs.package-version }}
maintainer: HashiCorp
homepage: https://github.com/hashicorp/vault
license: ${{ steps.metadata.outputs.linux_package_license }}
binary: ${{ steps.metadata.outputs.binary-path }}
deb_depends: openssl
rpm_depends: openssl
config_dir: .release/linux/package/
preinstall: .release/linux/preinst
postinstall: .release/linux/postinst
postremove: .release/linux/postrm
- if: inputs.create-packages == 'true'
id: package-files
name: Determine package file names
shell: bash
run: |
{
echo "rpm-files=$(basename out/*.rpm)"
echo "deb-files=$(basename out/*.deb)"
} | tee -a "$GITHUB_OUTPUT"
- if: inputs.create-packages == 'true'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ steps.package-files.outputs.rpm-files }}
path: out/${{ steps.package-files.outputs.rpm-files }}
if-no-files-found: error
- if: inputs.create-packages == 'true'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: ${{ steps.package-files.outputs.deb-files }}
path: out/${{ steps.package-files.outputs.deb-files }}
if-no-files-found: error
# Do our containerization last as it will move the binary location if we create containers.
- uses: ./.github/actions/containerize
id: containerize
with:
docker: ${{ inputs.create-docker-container }}
redhat: ${{ inputs.create-redhat-container }}
goarch: ${{ inputs.goarch }}
goos: ${{ inputs.goos }}
vault-binary-path: ${{ steps.metadata.outputs.binary-path }}
vault-edition: ${{ inputs.vault-edition }}
vault-version: ${{ inputs.vault-version }}