-
Notifications
You must be signed in to change notification settings - Fork 894
chore: run test-go-pg on macOS and Windows in regular CI #17853
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
Changes from 1 commit
fddaf7f
0edcb08
010d50d
6e7cc86
09539ee
2929c79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
name: "Setup Go Paths" | ||
description: Overrides Go paths like GOCACHE and GOMODCACHE to use temporary directories. | ||
outputs: | ||
gocache: | ||
description: "Value of GOCACHE" | ||
value: ${{ steps.paths.outputs.gocache }} | ||
gomodcache: | ||
description: "Value of GOMODCACHE" | ||
value: ${{ steps.paths.outputs.gomodcache }} | ||
gopath: | ||
description: "Value of GOPATH" | ||
value: ${{ steps.paths.outputs.gopath }} | ||
gotmp: | ||
description: "Value of GOTMPDIR" | ||
value: ${{ steps.paths.outputs.gotmp }} | ||
cached-dirs: | ||
description: "Go directories that should be cached between CI runs" | ||
value: ${{ steps.paths.outputs.cached-dirs }} | ||
runs: | ||
using: "composite" | ||
steps: | ||
- name: Override Go paths | ||
id: paths | ||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 | ||
with: | ||
script: | | ||
const path = require('path'); | ||
|
||
// RUNNER_TEMP should be backed by a RAM disk on Windows if | ||
// coder/setup-ramdisk-action was used | ||
const runnerTemp = process.env.RUNNER_TEMP; | ||
const gocacheDir = path.join(runnerTemp, 'go-cache'); | ||
const gomodcacheDir = path.join(runnerTemp, 'go-mod-cache'); | ||
const gopathDir = path.join(runnerTemp, 'go-path'); | ||
const gotmpDir = path.join(runnerTemp, 'go-tmp'); | ||
|
||
core.exportVariable('GOCACHE', gocacheDir); | ||
core.exportVariable('GOMODCACHE', gomodcacheDir); | ||
core.exportVariable('GOPATH', gopathDir); | ||
core.exportVariable('GOTMPDIR', gotmpDir); | ||
|
||
core.setOutput('gocache', gocacheDir); | ||
core.setOutput('gomodcache', gomodcacheDir); | ||
core.setOutput('gopath', gopathDir); | ||
core.setOutput('gotmp', gotmpDir); | ||
|
||
const cachedDirs = `${gocacheDir}\n${gomodcacheDir}`; | ||
core.setOutput('cached-dirs', cachedDirs); | ||
|
||
- name: Create directories | ||
shell: bash | ||
run: | | ||
set -e | ||
mkdir -p "$GOCACHE" | ||
mkdir -p "$GOMODCACHE" | ||
mkdir -p "$GOPATH" | ||
mkdir -p "$GOTMPDIR" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -336,21 +336,23 @@ jobs: | |
# a separate repository to allow its use before actions/checkout. | ||
- name: Setup RAM Disks | ||
if: runner.os == 'Windows' | ||
uses: coder/setup-ramdisk-action@81c5c441bda00c6c3d6bcee2e5a33ed4aadbbcc1 | ||
uses: coder/setup-ramdisk-action@a4b59caa8be2e88c348abeef042d7c1a33d8743e | ||
|
||
- name: Checkout | ||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
with: | ||
fetch-depth: 1 | ||
|
||
- name: Setup Go Paths | ||
uses: ./.github/actions/setup-go-paths | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously we were only doing this on Windows, should we do the same here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This step is now used to standardize the Go cache location on disk so the "download cache step" knows where to put it. Without it, it's somewhat complicated to figure out the paths so it works cross-OS and if Go isn't installed. |
||
|
||
- name: Setup Go | ||
uses: ./.github/actions/setup-go | ||
with: | ||
# Runners have Go baked-in and Go will automatically | ||
# download the toolchain configured in go.mod, so we don't | ||
# need to reinstall it. It's faster on Windows runners. | ||
use-preinstalled-go: ${{ runner.os == 'Windows' }} | ||
use-temp-cache-dirs: ${{ runner.os == 'Windows' }} | ||
|
||
- name: Setup Terraform | ||
uses: ./.github/actions/setup-tf | ||
|
@@ -490,21 +492,33 @@ jobs: | |
# a separate repository to allow its use before actions/checkout. | ||
- name: Setup RAM Disks | ||
if: runner.os == 'Windows' | ||
uses: coder/setup-ramdisk-action@79dacfe70c47ad6d6c0dd7f45412368802641439 | ||
uses: coder/setup-ramdisk-action@a4b59caa8be2e88c348abeef042d7c1a33d8743e | ||
|
||
- name: Checkout | ||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
with: | ||
fetch-depth: 1 | ||
|
||
- name: Setup Go Paths | ||
id: go-paths | ||
uses: ./.github/actions/setup-go-paths | ||
|
||
- name: Download Go Build Cache | ||
id: download-go-build-cache | ||
uses: ./.github/actions/test-cache/download | ||
with: | ||
key-prefix: test-go-build-${{ runner.os }}-${{ runner.arch }} | ||
cache-path: ${{ steps.go-paths.outputs.cached-dirs }} | ||
|
||
- name: Setup Go | ||
uses: ./.github/actions/setup-go | ||
with: | ||
# Runners have Go baked-in and Go will automatically | ||
# download the toolchain configured in go.mod, so we don't | ||
# need to reinstall it. It's faster on Windows runners. | ||
use-preinstalled-go: ${{ runner.os == 'Windows' }} | ||
use-temp-cache-dirs: ${{ runner.os == 'Windows' }} | ||
# Cache is already downloaded above | ||
use-cache: false | ||
|
||
- name: Setup Terraform | ||
uses: ./.github/actions/setup-tf | ||
|
@@ -515,6 +529,15 @@ jobs: | |
with: | ||
key-prefix: test-go-pg-${{ runner.os }}-${{ runner.arch }} | ||
|
||
- name: Normalize File and Directory Timestamps | ||
shell: bash | ||
# Normalize file modification timestamps so that go test can use the | ||
# cache from the previous CI run. See https://github.com/golang/go/issues/58571 | ||
# for more details. | ||
run: | | ||
find . -type f ! -path ./.git/\*\* | mtimehash | ||
find . -type d ! -path ./.git/\*\* -exec touch -t 200601010000 {} + | ||
|
||
- name: Test with PostgreSQL Database | ||
env: | ||
POSTGRES_VERSION: "13" | ||
|
@@ -523,6 +546,9 @@ jobs: | |
LC_ALL: "en_US.UTF-8" | ||
shell: bash | ||
run: | | ||
set -o errexit | ||
set -o pipefail | ||
|
||
if [ "${{ runner.os }}" == "Windows" ]; then | ||
# Create a temp dir on the R: ramdisk drive for Windows. The default | ||
# C: drive is extremely slow: https://github.com/actions/runner-images/issues/8755 | ||
|
@@ -533,6 +559,8 @@ jobs: | |
mkdir -p /tmp/tmpfs | ||
sudo mount_tmpfs -o noowners -s 8g /tmp/tmpfs | ||
go run scripts/embedded-pg/main.go -path /tmp/tmpfs/embedded-pg | ||
elif [ "${{ runner.os }}" == "Linux" ]; then | ||
make test-postgres-docker | ||
fi | ||
|
||
# if macOS, install google-chrome for scaletests | ||
|
@@ -542,10 +570,6 @@ jobs: | |
brew install google-chrome | ||
fi | ||
|
||
# By default Go will use the number of logical CPUs, which | ||
# is a fine default. | ||
PARALLEL_FLAG="" | ||
|
||
# macOS will output "The default interactive shell is now zsh" | ||
# intermittently in CI... | ||
if [ "${{ matrix.os }}" == "macos-latest" ]; then | ||
|
@@ -572,16 +596,32 @@ jobs: | |
NUM_PARALLEL_TESTS=8 | ||
fi | ||
|
||
if [ "${{ runner.os }}" == "Linux" ]; then | ||
make test-postgres | ||
else | ||
# We rerun failing tests to counteract flakiness coming from Postgres | ||
# choking on macOS and Windows sometimes. | ||
DB=ci gotestsum --rerun-fails=2 --rerun-fails-max-failures=50 \ | ||
--format standard-quiet --packages "./..." \ | ||
-- -v -p $NUM_PARALLEL_PACKAGES -parallel=$NUM_PARALLEL_TESTS -count=1 | ||
# by default, run tests with cache | ||
TESTCOUNT="" | ||
if [ "${{ github.ref }}" == "refs/heads/main" ]; then | ||
# on main, run tests without cache | ||
TESTCOUNT="-count=1" | ||
fi | ||
|
||
mkdir -p "$RUNNER_TEMP/sym" | ||
source scripts/normalize_path.sh | ||
# terraform gets installed in a random directory, so we need to normalize | ||
# the path to the terraform binary or a bunch of cached tests will be | ||
# invalidated. See scripts/normalize_path.sh for more details. | ||
normalize_path_with_symlinks "$RUNNER_TEMP/sym" "$(dirname $(which terraform))" | ||
Comment on lines
+553
to
+556
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like it would be better if we changed the test to use system terraform if it's a suitable version, then we can just install it before starting the test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean we should use the terraform download function that's built into Coder? |
||
|
||
# We rerun failing tests to counteract flakiness coming from Postgres | ||
# choking on macOS and Windows sometimes. | ||
DB=ci gotestsum --rerun-fails=2 --rerun-fails-max-failures=50 \ | ||
--format standard-quiet --packages "./..." \ | ||
-- -timeout=20m -v -p $NUM_PARALLEL_PACKAGES -parallel=$NUM_PARALLEL_TESTS $TESTCOUNT | ||
|
||
- name: Upload Go Build Cache | ||
uses: ./.github/actions/test-cache/upload | ||
with: | ||
cache-key: ${{ steps.download-go-build-cache.outputs.cache-key }} | ||
cache-path: ${{ steps.go-paths.outputs.cached-dirs }} | ||
|
||
- name: Upload Test Cache | ||
uses: ./.github/actions/test-cache/upload | ||
with: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#!/bin/bash | ||
|
||
# Call: normalize_path_with_symlinks [target_dir] [dir_prefix] | ||
# | ||
# Normalizes the PATH environment variable by replacing each directory that | ||
# begins with dir_prefix with a symbolic link in target_dir. For example, if | ||
# PATH is "/usr/bin:/bin", target_dir is /tmp, and dir_prefix is /usr, then | ||
# PATH will become "/tmp/0:/bin", where /tmp/0 links to /usr/bin. | ||
# | ||
# This is useful for ensuring that PATH is consistent across CI runs and helps | ||
# with reusing the same cache across them. Many of our go tests read the PATH | ||
# variable, and if it changes between runs, the cache gets invalidated. | ||
normalize_path_with_symlinks() { | ||
local target_dir="${1:-}" | ||
local dir_prefix="${2:-}" | ||
|
||
if [[ -z "$target_dir" || -z "$dir_prefix" ]]; then | ||
echo "Usage: normalize_path_with_symlinks <target_dir> <dir_prefix>" | ||
return 1 | ||
fi | ||
|
||
local old_path="$PATH" | ||
local -a new_parts=() | ||
local i=0 | ||
|
||
IFS=':' read -ra _parts <<<"$old_path" | ||
for dir in "${_parts[@]}"; do | ||
# Skip empty components that can arise from "::" | ||
[[ -z $dir ]] && continue | ||
|
||
# Skip directories that don't start with $dir_prefix | ||
if [[ "$dir" != "$dir_prefix"* ]]; then | ||
new_parts+=("$dir") | ||
continue | ||
fi | ||
|
||
local link="$target_dir/$i" | ||
|
||
# Replace any pre-existing file or link at $target_dir/$i | ||
if [[ -e $link || -L $link ]]; then | ||
rm -rf -- "$link" | ||
fi | ||
|
||
# without MSYS ln will deepcopy the directory on Windows | ||
MSYS=winsymlinks:nativestrict ln -s -- "$dir" "$link" | ||
new_parts+=("$link") | ||
i=$((i + 1)) | ||
done | ||
|
||
export PATH | ||
PATH="$( | ||
IFS=':' | ||
echo "${new_parts[*]}" | ||
)" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind using the script here, but you can accomplish the same with bash by echoing to
GITHUB_ENV
andGITHUB_OUTPUT
: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actionsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose to use the script to handle setting multi-line env variables. With bash, you have to be very careful with whitespace and indentation. It's error-prone.