open-vault/.github/workflows/build-vault-oss.yml
Ryan Cragun d1e9b99233
[QT-576] Optimize build workflow (#21486) (#21601)
Improve our build workflow execution time by using custom runners,
improved caching and conditional Web UI builds.

Runners
-------
We improve our build times[0] by using larger custom runners[1] when
building the UI and Vault.

Caching
-------
We improve Vault caching by keeping a cache for each build job. This
strategy has the following properties which should result in faster
build times when `go.sum` hasn't been changed from prior builds, or
when a pull request is retried or updated after a prior successful
build:

* Builds will restore cached Go modules and Go build cache according to
  the Go version, platform, architecture, go tags, and hash of `go.sum`
  that relates to each individual build workflow. This reduces the
  amount of time it will take to download the cache on hits and upload
  the cache on misses.
* Parallel build workflows won't clobber each others build cache. This
  results in much faster compile times after cache hits because the Go
  compiler can reuse the platform, architecture, and tag specific build
  cache that it created on prior runs.
* Older modules and build cache will not be uploaded when creating a new
  cache. This should result in lean cache sizes on an ongoing basis.
* On cache misses we will have to upload our compressed module and build
  cache. This will slightly extend the build time for pull requests that
  modify `go.sum`.

Web UI
------
We no longer build the web UI in every build workflow. Instead we separate
the UI building into its own workflow and cache the resulting assets.
The same UI assets are restored from cache during build worklows. This
strategy has the following properties:

* If the `ui` directory has not changed from prior builds we'll restore
  `http/web_ui` from cache and skip building the UI for no reason.
* We continue to use the built-in `yarn` caching functionality in
  `action/setup-node`. The default mode saves the `yarn` global cache.
  to improve UI build times if the cache has not been modified.

Changes
-------
* Add per platform/archicture Go module and build caching
* Move UI building into a separate job and cache the result
* Restore UI cache during build
* Pin workflows

Notes
-----
[0] https://hashicorp.atlassian.net/browse/QT-578
[1] https://github.com/hashicorp/vault/actions/runs/5415830307/jobs/9844829929

Signed-off-by: Ryan Cragun <me@ryan.ec>
2023-07-05 15:19:49 -06:00

136 lines
5.1 KiB
YAML

---
name: build_vault
# This workflow is intended to be called by the build workflow for each Vault
# binary that needs to be built and packaged. The ci make targets that are
# utilized automatically determine build metadata and handle building and
# packing vault.
on:
workflow_call:
inputs:
bundle-path:
required: false
type: string
cgo-enabled:
type: string
default: 0
create-packages:
type: boolean
default: true
goos:
required: true
type: string
goarch:
required: true
type: string
go-cache:
required: true
type: string
go-mod-cache:
required: true
type: string
go-tags:
type: string
go-version:
type: string
package-name:
type: string
default: vault
vault-version:
type: string
required: true
web-ui-cache-key:
type: string
required: true
jobs:
build:
runs-on: custom-linux-xl-vault-latest
name: Vault ${{ inputs.goos }} ${{ inputs.goarch }} v${{ inputs.vault-version }}
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
with:
go-version: ${{ inputs.go-version }}
cache: false # Use our own caching strategy for better cross platform support
- name: Set up Go cache key tags
id: cache-key-tags
run: echo "gotags=$(echo ${{ inputs.go-tags }} | tr ' ' '-')" >> "$GITHUB_ENV"
- name: Set up Go cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: |
${{ inputs.go-cache }}
${{ inputs.go-mod-cache }}
# Manage the Go cache for each build workflow individually. This ensures that only relevant
# module and build cache for that specific combination kept. This helps reduce our cache
# download and speeds up compiling because the build cache is always preserved.
key: go-${{ inputs.go-version }}-${{ inputs.goos }}-${{ inputs.goarch }}-${{ env.gotags }}-${{ hashFiles('**/go.sum') }}
# We intentionally omit partial restore keys to ensure that we always create a new cache
# if we don't get a hit. That ensures that we only keep up-to-date modules and build cache.
- name: Restore UI from cache
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
enableCrossOsArchive: true
fail-on-cache-miss: true
path: http/web_ui
# Only restore the UI asset cache if we haven't modified anything in the ui directory.
# Never do a partial restore of the web_ui if we don't get a cache hit.
key: ${{ inputs.web-ui-cache-key }}
- name: Build Vault
env:
CGO_ENABLED: ${{ inputs.cgo-enabled }}
GOARCH: ${{ inputs.goarch }}
GOOS: ${{ inputs.goos }}
GO_TAGS: ${{ inputs.go-tags }}
run: make ci-build
- name: Determine artifact basename
env:
GOARCH: ${{ inputs.goarch }}
GOOS: ${{ inputs.goos }}
run: echo "ARTIFACT_BASENAME=$(make ci-get-artifact-basename)" >> "$GITHUB_ENV"
- name: Bundle Vault
env:
BUNDLE_PATH: out/${{ env.ARTIFACT_BASENAME }}.zip
run: make ci-bundle
- uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: ${{ env.ARTIFACT_BASENAME }}.zip
path: out/${{ env.ARTIFACT_BASENAME }}.zip
if-no-files-found: error
- if: ${{ inputs.create-packages }}
uses: hashicorp/actions-packaging-linux@v1
with:
name: ${{ github.event.repository.name }}
description: Vault is a tool for secrets management, encryption as a service, and privileged access management.
arch: ${{ inputs.goarch }}
version: ${{ inputs.vault-version }}
maintainer: HashiCorp
homepage: https://github.com/hashicorp/vault
license: MPL-2.0
binary: dist/${{ inputs.package-name }}
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 }}
name: Determine package file names
run: |
echo "RPM_PACKAGE=$(basename out/*.rpm)" >> "$GITHUB_ENV"
echo "DEB_PACKAGE=$(basename out/*.deb)" >> "$GITHUB_ENV"
- if: ${{ inputs.create-packages }}
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: ${{ env.RPM_PACKAGE }}
path: out/${{ env.RPM_PACKAGE }}
if-no-files-found: error
- if: ${{ inputs.create-packages }}
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
with:
name: ${{ env.DEB_PACKAGE }}
path: out/${{ env.DEB_PACKAGE }}
if-no-files-found: error