Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade CI workflows #113

Merged
merged 3 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions .github/actions/bootstrap/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: "Bootstrap"

description: "Bootstrap all tools and dependencies"
inputs:
go-version:
description: "Go version to install"
required: true
default: "1.21.x"
use-go-cache:
description: "Restore go cache"
required: true
default: "true"
cache-key-prefix:
description: "Prefix all cache keys with this value"
required: true
default: "831180ac25"
build-cache-key-prefix:
description: "Prefix build cache key with this value"
required: true
default: "f8b6d31dea"
bootstrap-apt-packages:
description: "Space delimited list of tools to install via apt"
default: ""

runs:
using: "composite"
steps:
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe #v4.1.0
with:
go-version: ${{ inputs.go-version }}

- name: Restore tool cache
id: tool-cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
with:
path: ${{ github.workspace }}/.tmp
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

# note: we need to keep restoring the go mod cache before bootstrapping tools since `go install` is used in
# some installations of project tools.
- name: Restore go module cache
id: go-mod-cache
if: inputs.use-go-cache == 'true'
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
with:
path: |
~/go/pkg/mod
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-

- name: (cache-miss) Bootstrap project tools
shell: bash
if: steps.tool-cache.outputs.cache-hit != 'true'
run: make bootstrap-tools

- name: Restore go build cache
id: go-cache
if: inputs.use-go-cache == 'true'
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
with:
path: |
~/.cache/go-build
key: ${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-

- name: (cache-miss) Bootstrap go dependencies
shell: bash
if: steps.go-mod-cache.outputs.cache-hit != 'true' && inputs.use-go-cache == 'true'
run: make bootstrap-go

- name: Install apt packages
if: inputs.bootstrap-apt-packages != ''
shell: bash
run: |
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y ${{ inputs.bootstrap-apt-packages }}
11 changes: 11 additions & 0 deletions .github/scripts/ci-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

red=$(tput setaf 1)
bold=$(tput bold)
normal=$(tput sgr0)

# assert we are running in CI (or die!)
if [[ -z "$CI" ]]; then
echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}"
exit 1
fi
50 changes: 50 additions & 0 deletions .github/scripts/trigger-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -eu

bold=$(tput bold)
normal=$(tput sgr0)

if ! [ -x "$(command -v gh)" ]; then
echo "The GitHub CLI could not be found. To continue follow the instructions at https://github.com/cli/cli#installation"
exit 1
fi

gh auth status

# we need all of the git state to determine the next version. Since tagging is done by
# the release pipeline it is possible to not have all of the tags from previous releases.
git fetch --tags

# populates the CHANGELOG.md and VERSION files
echo "${bold}Generating changelog...${normal}"
make changelog 2> /dev/null

NEXT_VERSION=$(cat VERSION)

if [[ "$NEXT_VERSION" == "" || "${NEXT_VERSION}" == "(Unreleased)" ]]; then
echo "Could not determine the next version to release. Exiting..."
exit 1
fi

while true; do
read -p "${bold}Do you want to trigger a release for version '${NEXT_VERSION}'?${normal} [y/n] " yn
case $yn in
[Yy]* ) echo; break;;
[Nn]* ) echo; echo "Cancelling release..."; exit;;
* ) echo "Please answer yes or no.";;
esac
done

echo "${bold}Kicking off release for ${NEXT_VERSION}${normal}..."
echo
gh workflow run release.yaml -f version=${NEXT_VERSION}

echo
echo "${bold}Waiting for release to start...${normal}"
sleep 10

set +e

echo "${bold}Head to the release workflow to monitor the release:${normal} $(gh run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')"
id=$(gh run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId')
gh run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" gh run view $id --log-failed)
78 changes: 31 additions & 47 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
name: "Release"
on:
push:
# take no actions on push to any branch...
branches-ignore:
- "**"
# ... only act on release tags
tags:
- "v*"
permissions:
contents: read

env:
GO_VERSION: "1.21.x"
on:
workflow_dispatch:
inputs:
version:
description: tag the latest commit on main with the given version (prefixed with v)
required: true

jobs:
quality-gate:
environment: release
runs-on: ubuntu-latest # This OS choice is arbitrary. None of the steps in this job are specific to either Linux or macOS.
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0

# we don't want to release commits that have been pushed and tagged, but not necessarily merged onto main
- name: Ensure tagged commit is on main
- name: Check if tag already exists
# note: this will fail if the tag already exists
run: |
echo "Tag: ${GITHUB_REF##*/}"
git fetch origin main
git merge-base --is-ancestor ${GITHUB_REF##*/} origin/main && echo "${GITHUB_REF##*/} is a commit on main!"
[[ "${{ github.event.inputs.version }}" == v* ]] || (echo "version '${{ github.event.inputs.version }}' does not have a 'v' prefix" && exit 1)
git tag ${{ github.event.inputs.version }}

- name: Check static analysis results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 #v1.1.0
Expand Down Expand Up @@ -52,56 +48,44 @@ jobs:

release:
needs: [quality-gate]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
permissions:
packages: write
contents: write
steps:

- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe #v4.1.0
with:
go-version: ${{ env.GO_VERSION }}

- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0
with:
fetch-depth: 0

- name: Restore tool cache
id: tool-cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
with:
path: ${{ github.workspace }}/.tmp
key: ${{ runner.os }}-tool-${{ hashFiles('Makefile') }}

- name: Restore go cache
id: go-cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
# use the same cache we used for building snapshots
build-cache-key-prefix: "snapshot"

- name: (cache-miss) Bootstrap all project dependencies
if: steps.tool-cache.outputs.cache-hit != 'true' || steps.go-cache.outputs.cache-hit != 'true'
run: make bootstrap
- name: Tag release
run: |
git tag -a ${{ github.event.inputs.version }} -m "Release ${{ github.event.inputs.version }}"
git push origin --tags
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Build & publish release artifacts
run: make release
run: make ci-release
env:
# for creating the release (requires write access to packages and content)
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- uses: anchore/sbom-action@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 #v0.14.3
continue-on-error: true
with:
artifact-name: sbom.spdx.json

- uses: 8398a7/action-slack@fbd6aa58ba854a740e11a35d0df80cb5d12101d8 #v3.15.1
with:
status: ${{ job.status }}
fields: repo,workflow,action,eventName
text: "A new Chronicle release is ready to be manually published: https://github.com/anchore/chronicle/releases"
text: "A new Chronicle release has been published: https://github.com/anchore/chronicle/releases"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
if: ${{ success() }}

- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 #v3.1.3
with:
name: artifacts
path: dist/**/*
Loading
Loading