Skip to content

pkg/osquery: fix flaky secretless enrollment test #10071

pkg/osquery: fix flaky secretless enrollment test

pkg/osquery: fix flaky secretless enrollment test #10071

Workflow file for this run

name: ci
on:
workflow_dispatch:
push:
branches: [main, master]
tags: "*"
pull_request:
branches: "**"
merge_group:
types: [checks_requested]
permissions:
contents: read
jobs:
# Our non-containerized launcher builds -- macOS and Windows. Linux is handled separately
# below to preserve Ubuntu 20.04 support.
build:
permissions:
contents: read
id-token: write # Required to create an OIDC token for Cloudsmith auth
name: launcher
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # Consider changing this sometime
matrix:
os:
- macos-15
- windows-latest
env:
CACHE_KEY_PREFIX: '' # Deliberately empty -- only set to distinguish our second build (for reproducibility testing) from this main build
steps: &non_container_build_steps
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Setup Cloudsmith CLI # Exports CLOUDSMITH_API_KEY
uses: step-security/cloudsmith-cli-action@dd1da513017145043c2d29a38b3b85c2b609b5ad # v2.0.3
# For now, we only use Cloudsmith on builds we're going to distribute: refs/head/main for nightly builds, and 'tag' for stable builds
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
with:
oidc-auth-only: 'true' # Just the auth, don't need the CLI installed in CI
oidc-namespace: '1password'
oidc-service-slug: 'ga-kolide-launcher'
- name: Configure GOPROXY
# For now, we only use Cloudsmith on builds we're going to distribute: refs/head/main for nightly builds, and 'tag' for stable builds.
# cloudsmith-cli-action should mask the API key, but we add additional masks just to be safe.
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
shell: bash
run: |
echo "::add-mask::${CLOUDSMITH_API_KEY}"
[ -z "${CLOUDSMITH_API_KEY:-}" ] && exit 1
goproxy="https://token:${CLOUDSMITH_API_KEY}@go.pkg.1infra.dev/op-golang/"
echo "::add-mask::$goproxy"
echo "GOPROXY=$goproxy" >> "$GITHUB_ENV"
- name: Check out code
id: checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # need a full checkout for `git describe`
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "./go.mod"
check-latest: true
cache: false
id: go
# use bash, because the powershell syntax is different and this is a cross platform workflow
- id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
- name: Go Mod Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
- name: Get dependencies
run: make deps
- name: Build (debug)
if: github.ref_type != 'tag'
shell: bash
run: MAKE_debugsymbols=true make -j2 github-build
- name: Build
if: github.ref_type == 'tag'
run: make -j2 github-build
- name: Check macOS build target
if: contains(matrix.os, 'macos')
# this uses grep's exit code
run: otool -l build/launcher | grep -A1 "minos 11"
- name: Lipo
run: make github-lipo
if: ${{ contains(matrix.os, 'macos') }}
- name: App Bundle
run: make github-launcherapp
if: ${{ contains(matrix.os, 'macos') }}
- name: Cache build output
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ env.CACHE_KEY_PREFIX }}${{ runner.os }}-${{ github.run_id }}
enableCrossOsArchive: true
build_reproducible:
name: launcher -- reproducible
permissions:
contents: read
id-token: write # Required to create an OIDC token for Cloudsmith auth
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # Consider changing this sometime
matrix:
os:
- macos-15
- windows-latest
env:
CACHE_KEY_PREFIX: 'reproducible-' # Differentiates this build from the build generated by `build`
steps: *non_container_build_steps
# Our containerized launcher build -- we need to build launcher on Ubuntu 20.04
# in order to continue to support that platform, but that GH runner has been EOL'ed --
# so we have a separate build here in an ubuntu:20.04 container instead.
build_linux:
permissions:
contents: read
id-token: write # Required to create an OIDC token for Cloudsmith auth
name: launcher (linux)
runs-on: ubuntu-22.04
container: ubuntu:20.04 # Required to support launcher on Ubuntu 20.04
env:
CACHE_KEY_PREFIX: '' # Deliberately empty -- only set to distinguish our second build (for reproducibility testing) from this main build
steps: &container_build_steps
# zstd is needed so we can restore cache later -- see https://github.com/actions/cache/issues/1455#issuecomment-2328358604
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Setup Cloudsmith CLI # Exports CLOUDSMITH_API_KEY
uses: step-security/cloudsmith-cli-action@dd1da513017145043c2d29a38b3b85c2b609b5ad # v2.0.3
# For now, we only use Cloudsmith on builds we're going to distribute: refs/head/main for nightly builds, and 'tag' for stable builds
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
with:
oidc-auth-only: 'true' # Just the auth, don't need the CLI installed in CI
oidc-namespace: '1password'
oidc-service-slug: 'ga-kolide-launcher'
- name: Configure GOPROXY
# For now, we only use Cloudsmith on builds we're going to distribute: refs/head/main for nightly builds, and 'tag' for stable builds.
# cloudsmith-cli-action should mask the API key, but we add additional masks just to be safe.
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
shell: bash
run: |
echo "::add-mask::${CLOUDSMITH_API_KEY}"
[ -z "${CLOUDSMITH_API_KEY:-}" ] && exit 1
goproxy="https://token:${CLOUDSMITH_API_KEY}@go.pkg.1infra.dev/op-golang/"
echo "::add-mask::$goproxy"
echo "GOPROXY=$goproxy" >> "$GITHUB_ENV"
- name: Install build dependencies
run: |
apt-get -y update
apt-get -y install build-essential ca-certificates openssl git zstd
update-ca-certificates
- name: Check out code
id: checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # need a full checkout for `git describe`
- name: Ignore dubious ownership
run: git config --global --add safe.directory /__w/launcher/launcher
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "./go.mod"
check-latest: true
cache: false
id: go
- id: go-cache-paths
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('go.sum') }}
- name: Go Mod Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('go.sum') }}
- name: Get dependencies
run: make deps
- name: Set up zig
uses: step-security/setup-zig@1e9fbd457bcc3587b58845344a267f12f151709c # v2.2.2
- name: Build (debug)
if: github.ref_type != 'tag'
run: MAKE_debugsymbols=true make -j2 github-build
- name: Build
if: github.ref_type == 'tag'
run: make -j2 github-build
- name: Cache build output
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ env.CACHE_KEY_PREFIX }}${{ runner.os }}-${{ github.run_id }}
enableCrossOsArchive: true
build_linux_reproducible:
permissions:
contents: read
id-token: write # Required to create an OIDC token for Cloudsmith auth
name: launcher (linux) -- reproducible
runs-on: ubuntu-22.04
container: ubuntu:20.04 # Required to support launcher on Ubuntu 20.04
env:
CACHE_KEY_PREFIX: 'reproducible-' # Differentiates this build from the build generated by `build_linux`
steps: *container_build_steps
reproducible_verify:
needs: [build, build_reproducible, build_linux, build_linux_reproducible]
name: verify
permissions:
contents: read
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
runneros:
- Linux
- macOS
- Windows
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: cache restore build 1 output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ matrix.runneros }}-${{ github.run_id }}
fail-on-cache-miss: true
enableCrossOsArchive: true
- name: move build 1
run: mv ./build ./build1
- name: cache restore build 2 output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: reproducible-${{ matrix.runneros }}-${{ github.run_id }}
fail-on-cache-miss: true
enableCrossOsArchive: true
- name: move build 2
run: mv ./build ./build2
- name: Verify (Posix)
if: matrix.runneros == 'Linux' || matrix.runneros == 'macOS'
run: |
HASH1=$(sha256sum build1/launcher | awk '{ print $1 }')
HASH2=$(sha256sum build2/launcher | awk '{ print $1 }')
if [ "$HASH1" = "$HASH2" ]; then
echo "Builds match"
else
echo "Builds differ: build 1: ${HASH1}: build 2: ${HASH2}"
fi
- name: Verify (Windows)
if: matrix.runneros == 'Windows'
run: |
HASH1=$(sha256sum build1/launcher.exe | awk '{ print $1 }')
HASH2=$(sha256sum build2/launcher.exe | awk '{ print $1 }')
if [ "$HASH1" = "$HASH2" ]; then
echo "Builds match"
else
echo "Builds differ: build 1: ${HASH1}: build 2: ${HASH2}"
fi
# this job captures the version of launcher on one of the runners then that version is
# compared to the version of all other runners during exec testing. This is to ensure
# that the version of launcher is the same across all runners. We run this job in a container
# to confirm launcher support on ubuntu 20.04, since runners no longer support ubuntu 20.04.
version_baseline:
permissions:
contents: read
name: Version Baseline
runs-on: ubuntu-22.04
container: ubuntu:20.04
needs: build_linux
outputs:
version: ${{ steps.version.outputs.version }}
steps:
# Needed so we can restore cache -- see https://github.com/actions/cache/issues/1455#issuecomment-2328358604
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Install zstd
run: |
apt-get -y update
apt-get -y install zstd
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
fail-on-cache-miss: true # Need launcher build from cache to run it below
enableCrossOsArchive: true
- id: version
name: Launcher Version
working-directory: build
shell: bash
run: ./launcher --version 2>/dev/null | awk '/version /{print "version="$4}' >> "$GITHUB_OUTPUT"
launcher_test:
permissions:
contents: read
name: test
needs:
- build # a desktop runner test requires a build to exist
- build_linux
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- macos-15
- windows-latest
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Check out code
id: checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # need a full checkout for `git describe`
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "./go.mod"
check-latest: true
cache: false
- name: cache restore - build
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
enableCrossOsArchive: true
- id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: cache restore - GOCACHE
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
enableCrossOsArchive: true
- name: cache restore - GOMODCACHE
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
enableCrossOsArchive: true
- name: Test
run: make test
- name: Upload coverage
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ runner.os }}-coverage.out
path: ./coverage.out
if-no-files-found: error
launcher_table_test:
permissions:
contents: read
name: Launcher table performance test
needs:
- build
- build_linux
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- macos-15
- windows-latest
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Check out code
id: checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # need a full checkout for `git describe`
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "./go.mod"
check-latest: true
cache: false
- name: cache restore - build
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
enableCrossOsArchive: true
- id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: cache restore - GOCACHE
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
enableCrossOsArchive: true
- name: cache restore - GOMODCACHE
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
enableCrossOsArchive: true
- name: Test
run: make test-bench-tables > benchmark.txt
- name: Display results
shell: bash
run: cat ./benchmark.txt
- name: Get run ID for last launcher table performance test on main
id: main-run-id
if: github.ref != 'refs/heads/main' && github.ref_type != 'tag'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "main-run-id=$(gh run list --repo kolide/launcher --branch main --workflow ci --limit 1 --json databaseId -q '.[].databaseId')" >> "$GITHUB_OUTPUT"
- name: Download benchmark from main
id: download-benchmark
if: github.ref != 'refs/heads/main' && github.ref_type != 'tag'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
continue-on-error: true
with:
name: ${{ runner.os }}-benchmark.txt
github-token: ${{ github.token }} # Grants permission to read from other workflow runs
run-id: ${{ steps.main-run-id.outputs.main-run-id }}
path: main
- name: Install benchstat
if: github.ref != 'refs/heads/main' && github.ref_type != 'tag' && steps.download-benchmark.outcome == 'success'
run: go install golang.org/x/perf/cmd/benchstat@9e4b9ddef5b6a4371594ec978cb4b8088bec845d # untagged, unversioned
- name: Compare performance against main
if: github.ref != 'refs/heads/main' && github.ref_type != 'tag' && steps.download-benchmark.outcome == 'success'
shell: bash
run: |
benchstat main/benchmark.txt ./benchmark.txt > benchstat.txt
cat ./benchstat.txt
# We want to check for performance regressions.
# The regex matches lines that look like:
# AppIcons-3 5.606m ± 10% 10012.759m ± 0% +178505.57% (p=0.000 n=10)
# Format is: <Function name> <benchmark measurement from main> ± <confidence interval> <benchmark measurement from PR> ± <confidence interval> +<percent change versus main>
# We're capturing the percent change against main, whenever it is a performance regression (positive delta).
# We only care when it's at least a 1% change (so we ignore e.g. +0.02%).
# When it's a negative change (e.g. -178505.57%), that's a performance improvement.
# When there's no difference, benchstat outputs a ~ instead.
REGRESSIONS=$(grep -E '^.+-\d+\s+(?:\d+\.?\d*[a-zA-Z]*\s±\s\d+%\s+){2}(\+[1-9]+\.?\d*%)' ./benchstat.txt || :)
if [ -n "$REGRESSIONS" ]
then
echo "Performance regressions found:"
echo "$REGRESSIONS"
exit 1
fi
- name: Skip benchmark comparison (no baseline)
if: github.ref != 'refs/heads/main' && github.ref_type != 'tag' && steps.download-benchmark.outcome != 'success'
shell: bash
run: |
echo "::notice::Skipping benchmark comparison - no baseline found on main branch. This is expected for new benchmarks."
- name: Save benchmark results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ runner.os }}-benchmark.txt
path: ./benchmark.txt
if-no-files-found: error
exec_testing:
permissions:
contents: read
name: Exec Test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
- ubuntu-22.04
- ubuntu-24.04
- macos-14
- macos-15
- macos-26
- windows-2022
- windows-2025
needs:
- version_baseline # version_baseline implies build_linux
- build # need the other builds too
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
fail-on-cache-miss: true # If we can't restore the cache, then we won't have a launcher binary to run below
enableCrossOsArchive: true
- name: Launcher Version
working-directory: build
shell: bash
run: |
./launcher --version
thisVersion=$(./launcher --version 2>/dev/null | grep "version" | awk '{print $4}')
baseVersion="${{ needs.version_baseline.outputs.version }}"
if [[ "$thisVersion" != "$baseVersion" ]]; then
printf "launcher version %s does not match baseline version %s" "$thisVersion" "$baseVersion"
exit 1
fi
- name: Download Osquery
working-directory: build
run: ./launcher download-osquery --directory osqueryd-download
- name: Move Osquery (posix)
if: ${{ runner.os != 'Windows' }}
working-directory: build
run: mv ./osqueryd-download/osqueryd/osqueryd ./
- name: Move Osquery (windows)
if: ${{ runner.os == 'Windows' }}
working-directory: build
run: |
sleep 2
mv ./osqueryd-download/osqueryd/osqueryd.exe ./
- name: Osquery Version
working-directory: build
run: ./osqueryd --version
- name: Launcher Doctor
working-directory: build
run: ./launcher doctor
container_exec_testing:
permissions:
contents: read
name: Exec Test Containers
runs-on: ubuntu-22.04
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
container:
# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
- ubuntu:20.04
#- centos:7 # Unsupported by actions/cache/restore GLIBC Issues
- centos:8
- debian:11
- debian:12
needs:
- version_baseline # version_baseline implies build_linux
- build # need the other builds too
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: OS Info
run: |
echo uname:
uname -a
for f in /etc/*release; do echo -e "\n\n$f:"; cat "$f" || true; done
# zstd is needed so we can restore cache -- see https://github.com/actions/cache/issues/1455#issuecomment-2328358604;
# ca-certificates and openssl are needed to download osquery.
- name: Install dependencies
run: |
if grep NAME /etc/os-release | grep -q centos; then
echo CentOS detected
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/CentOS-*.repo
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/CentOS-*.repo
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/CentOS-*.repo
dnf install -y zstd
elif command -v apt-get > /dev/null; then
echo apt-get detected
apt-get -y update
apt-get -y install zstd ca-certificates openssl
update-ca-certificates
fi
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
fail-on-cache-miss: true # If we can't restore the cache, then we won't have a launcher binary to run below
enableCrossOsArchive: true
- name: Launcher Version
working-directory: build
shell: bash
run: |
./launcher --version
thisVersion=$(./launcher --version 2>/dev/null | grep "version" | awk '{print $4}')
baseVersion="${{ needs.version_baseline.outputs.version }}"
if [[ "$thisVersion" != "$baseVersion" ]]; then
printf "launcher version %s does not match baseline version %s" "$thisVersion" "$baseVersion"
exit 1
fi
- name: Download Osquery
working-directory: build
run: |
./launcher download-osquery --directory osqueryd-download
mv ./osqueryd-download/osqueryd/osqueryd ./
- name: Osquery Version
working-directory: build
run: ./osqueryd --version
- name: Launcher Doctor
working-directory: build
run: ./launcher doctor
# If the prior exec tests suceeded, this grabs the cached things, and moves them to artifacts. We ought
# be able to do this entirely on ubuntu, so let's try!
store_artifacts:
permissions:
contents: read
name: Store Artifacts
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
artifactos:
# artifactos needs to match the runner.os set by the builds. (Which is not quite the same as matrix.os)
- Linux
- macOS
- Windows
needs:
- exec_testing
- container_exec_testing
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ matrix.artifactos }}-${{ github.run_id }}
fail-on-cache-miss: true # If we can't restore the cache, then we won't have anything to upload
enableCrossOsArchive: true
- name: Upload Build
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ${{ matrix.artifactos }}-build
path: build/
if-no-files-found: error
# Generate each platform's table schema by running its cached binary (tables
# are compile-time per GOOS, so each runner emits only its own). A separate
# matrix job, rather than steps in build/build_linux, avoids duplicating the
# step and avoids colliding with the reproducible build twins.
generate_schema:
permissions:
contents: read
name: Generate table schema
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-24.04
- macos-26
- windows-2025
needs:
- build
- build_linux
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
fail-on-cache-miss: true # need the launcher binary to run it below
enableCrossOsArchive: true
- name: Generate table schema
shell: bash
run: |
launcher_bin=build/launcher
if [ "$RUNNER_OS" = "Windows" ]; then launcher_bin=build/launcher.exe; fi
"$launcher_bin" specs --output "launcher-specs-${RUNNER_OS}.json"
- name: Upload table schema
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: schema-${{ runner.os }}
path: launcher-specs-${{ runner.os }}.json
if-no-files-found: error
combine_schema:
permissions:
contents: write # required to attach the schema to the release on tag builds
name: Combine table schema
runs-on: ubuntu-22.04
needs:
- generate_schema
steps:
# Reuse the Linux launcher binary built by build_linux rather than
# rebuilding from source -- the merge logic is platform-independent, so the
# cached binary does the combine without a checkout, Go toolchain, or deps.
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: cache restore build output
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ./build
key: ${{ runner.os }}-${{ github.run_id }}
fail-on-cache-miss: true # need the launcher binary to run it below
enableCrossOsArchive: true
- name: Download platform schemas
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: schema-*
path: schemas
merge-multiple: true
- name: Combine schemas
shell: bash
run: |
# Glob the downloaded schemas rather than naming each file, so this is
# robust to $RUNNER_OS casing or the platform set changing.
shopt -s nullglob
schema_files=(schemas/launcher-specs-*.json)
if [ ${#schema_files[@]} -eq 0 ]; then
echo "no per-platform schema files found in schemas/" >&2
exit 1
fi
build/launcher specs --merge \
--output launcher-schema.json \
"${schema_files[@]}"
- name: Upload combined schema
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: launcher-schema
path: launcher-schema.json
if-no-files-found: error
# On tag builds, attach the freshly-combined schema to the tag's GitHub
# release so k2 can ingest it. If no release exists yet for the tag (e.g.
# the tag was pushed without a release), we skip rather than fail the build
# -- use the manual `release-schema.yml` workflow to attach it once the
# release exists.
- name: Attach schema to release
if: github.ref_type == 'tag'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
# A missing release is expected and non-fatal (the manual
# release-schema.yml backfill handles it); any other error must fail.
if err=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" 2>&1 >/dev/null); then
gh release upload "$TAG" launcher-schema.json --repo "$GITHUB_REPOSITORY" --clobber
echo "Attached launcher-schema.json to release $TAG"
elif printf '%s' "$err" | grep -qi 'release not found'; then
echo "::notice::No GitHub release found for tag $TAG; skipping schema upload. Use the 'Attach table schema to release' workflow to attach it once the release exists."
else
echo "failed to look up release $TAG: $err" >&2
exit 1
fi
package_builder_test:
permissions:
contents: read
id-token: write # Required to create an OIDC token for Cloudsmith auth
name: package_builder
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os:
- ubuntu-22.04
- macos-15
- windows-latest
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- name: Setup Cloudsmith CLI # Exports CLOUDSMITH_API_KEY
uses: step-security/cloudsmith-cli-action@dd1da513017145043c2d29a38b3b85c2b609b5ad # v2.0.3
# We don't distribute package_builder via these artifacts, but nonetheless use Cloudsmith where we can (main and tagged builds).
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
with:
oidc-auth-only: 'true' # Just the auth, don't need the CLI installed in CI
oidc-namespace: '1password'
oidc-service-slug: 'ga-kolide-launcher'
- name: Configure GOPROXY
# We don't distribute package_builder via these artifacts, but nonetheless use Cloudsmith where we can (main and tagged builds).
# cloudsmith-cli-action should mask the API key, but we add additional masks just to be safe.
if: github.ref == 'refs/heads/main' || github.ref_type == 'tag'
shell: bash
run: |
echo "::add-mask::${CLOUDSMITH_API_KEY}"
[ -z "${CLOUDSMITH_API_KEY:-}" ] && exit 1
goproxy="https://token:${CLOUDSMITH_API_KEY}@go.pkg.1infra.dev/op-golang/"
echo "::add-mask::$goproxy"
echo "GOPROXY=$goproxy" >> "$GITHUB_ENV"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # need a full checkout for `git describe`
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "./go.mod"
check-latest: true
cache: false
id: go
- id: go-cache-paths
shell: bash
run: |
echo "go-build=$(go env GOCACHE)" >> "$GITHUB_OUTPUT"
echo "go-mod=$(go env GOMODCACHE)" >> "$GITHUB_OUTPUT"
- name: Go Build Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
- name: Go Mod Cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ${{ steps.go-cache-paths.outputs.go-mod }}
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
- run: make deps
- id: build
run: make package-builder
- name: package
id: run-package-builder
run: ${{ steps.build.outputs.binary }} make --i-am-a-kolide-customer --debug --hostname=localhost --enroll_secret=secret --launcher_version=nightly --osquery_version=nightly --output_dir=./
- name: Test install macOS
if: ${{ contains(matrix.os, 'macos') }}
run: |
# Check that we can install
sudo installer -dumplog -pkg ./launcher.darwin-launchd-pkg.pkg -target /
# Quick check that at least a couple of the files we expect now exist
if [ ! -f /Library/LaunchDaemons/com.launcher.launcher.plist ]; then echo "missing launchd entry" && exit 1; fi
if [ ! -f /usr/local/launcher/osquery.app/Contents/MacOS/osqueryd ]; then echo "missing osqueryd binary" && exit 1; fi
if [ ! -L /usr/local/launcher/bin/osqueryd ]; then echo "missing osquery symlink" && exit 1; fi
if [ ! -e /usr/local/launcher/bin/osqueryd ]; then echo "osquery symlink is present but broken" && exit 1; fi
if [ ! -f /usr/local/launcher/Kolide.app/Contents/MacOS/launcher ]; then echo "missing launcher binary" && exit 1; fi
if [ ! -L /usr/local/launcher/bin/launcher ]; then echo "missing launcher symlink" && exit 1; fi
if [ ! -e /usr/local/launcher/bin/launcher ]; then echo "launcher symlink is present but broken" && exit 1; fi
# This job is here as a github status check -- it allows us to move
# the merge dependency from being on all the jobs to this single
# one.
ci_mergeable:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit # Audit network and disk activity
- run: true
needs:
- build
- build_linux
- launcher_test
- package_builder_test
- exec_testing
- container_exec_testing
- combine_schema