Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f371db0
ci: add integration tests workflow for Postgres 13
mastercactapus Apr 3, 2025
2db5ae2
ci: add checkout step to integration workflow
mastercactapus Apr 3, 2025
cad2348
ci: update build script execution to use bash
mastercactapus Apr 3, 2025
eeb630d
ci: add safe.directory configuration for Git in integration workflow
mastercactapus Apr 3, 2025
8d8d29f
ci: enhance integration workflow with concurrency and comprehensive t…
mastercactapus Apr 3, 2025
7280923
ci: add Postgres start and stop steps to integration workflow
mastercactapus Apr 3, 2025
e1b1cb5
ci: streamline Postgres management in integration workflow
mastercactapus Apr 3, 2025
92e85e6
ci: add Go cache restoration steps to integration workflow
mastercactapus Apr 3, 2025
4e6de0c
Merge branch 'master' into pr-actions
mastercactapus Apr 3, 2025
f7d8063
ci: update integration workflow to restore and save Go cache
mastercactapus Apr 3, 2025
0057bed
ci: update integration workflow to enhance cache restoration and saving
mastercactapus Apr 3, 2025
68a52cf
ci: streamline test execution by integrating Postgres startup into te…
mastercactapus Apr 4, 2025
11ba340
ci: update integration workflow to save cache correctly and enable CI…
mastercactapus Apr 7, 2025
af45d1f
ci: enhance caching mechanism and add tool fetching functionality
mastercactapus Apr 7, 2025
7d4eb9a
Merge remote-tracking branch 'origin/master' into pr-actions
mastercactapus Apr 7, 2025
57fba0b
try caching
mastercactapus Apr 7, 2025
b6c3163
ci: add environment variable for cache restore and save steps
mastercactapus Apr 7, 2025
ec43c31
ci: improve cache restoration logic and ensure last used timestamp is…
mastercactapus Apr 7, 2025
f49739e
ci: improve old cache cleanup logic to handle empty GLOBAL_CACHE_PATH
mastercactapus Apr 7, 2025
66df32a
ci: fix temporary directory creation for cache saving
mastercactapus Apr 8, 2025
f053972
ci: update database URL in tests and Dockerfile for SSL mode
mastercactapus Apr 8, 2025
bdfa3a1
ci: modify cache save logic to skip if cache already exists
mastercactapus Apr 8, 2025
d7eecc5
ci: refactor test steps to start Postgres separately for clarity
mastercactapus Apr 8, 2025
6f5e404
ci: update cache key generation to include script path and add ms-pla…
mastercactapus Apr 8, 2025
1058a1b
ci: consolidate test steps into a single 'Tests' job for improved cla…
mastercactapus Apr 8, 2025
4ac7158
ci: refactor build process to include dependency installation and cac…
mastercactapus Apr 8, 2025
60fa4a3
ci: update integration workflow to use golang:1.24.2-bookworm and ref…
mastercactapus Apr 8, 2025
8a276d9
ci: update Postgres version in test jobs from 14 to 17 and adjust run…
mastercactapus Apr 8, 2025
45102f8
ci: update container image in integration jobs to goalert/build-env:g…
mastercactapus Apr 8, 2025
5d69c96
update set name
mastercactapus Apr 8, 2025
4c86bc3
try 1 again
mastercactapus Apr 8, 2025
d5be1df
test defaults
mastercactapus Apr 8, 2025
791a017
Merge branch 'pr-actions' of github.com:target/goalert into pr-actions
mastercactapus Apr 8, 2025
cdc9502
fix hash files
mastercactapus Apr 8, 2025
3e4fc72
test concurrent
mastercactapus Apr 8, 2025
afe5541
don't use refs
mastercactapus Apr 8, 2025
e3df663
attempt2
mastercactapus Apr 8, 2025
e1d6718
Merge branch 'master' into pr-actions
mastercactapus Apr 15, 2025
a2673ac
build: update bun.version to 1.2.9
mastercactapus Apr 15, 2025
147b588
update dependencies: bump golang.org/x/crypto to v0.37.0, golang.org/…
mastercactapus Apr 21, 2025
165fdb5
Merge branch 'pr-actions' of github.com:target/goalert into pr-actions
mastercactapus Apr 21, 2025
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
195 changes: 195 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
name: Integration Tests

on:
push:
tags:
- v*
branches:
- master
- main
pull_request:

# Cancel in-progress jobs if a new commit is pushed to the same branch
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build Validation
runs-on: ubuntu-latest
container:
image: goalert/build-env:go1.24.2
volumes:
- /var/cache/arc:/var/cache/arc
steps:
- uses: actions/checkout@v4
- name: Set git safe directory
run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/cache@v4
with:
key: cache-${{ hashFiles('go.mod','go.sum','package.json','bun.lock','*.version')}}
path: |
/go/pkg/mod
$HOME/.cache/goalert-gettool
$HOME/.cache/Cypress
$HOME/.cache/ms-playwright
$HOME/.bun/install/cache
- name: Build all binaries
run: make cache

check:
name: make check
# You need to use the INSTALLATION_NAME from the previous step
runs-on: ubuntu-latest
needs: build
container:
image: goalert/build-env:go1.24.2
volumes:
- /var/cache/arc:/var/cache/arc
steps:
- uses: actions/checkout@v4
- name: Set git safe directory
run: git config --global --add safe.directory $GITHUB_WORKSPACE
- uses: actions/cache@v4
with:
key: cache-${{ hashFiles('go.mod','go.sum','package.json','bun.lock','*.version')}}
path: |
/go/pkg/mod
$HOME/.cache/goalert-gettool
$HOME/.cache/Cypress
$HOME/.cache/ms-playwright
$HOME/.bun/install/cache

# Run repo & linting checks
- name: Run Repo & Linting Checks
run: make check self-test

unit:
name: Unit Tests
# You need to use the INSTALLATION_NAME from the previous step
runs-on: ubuntu-latest
needs: build
container:
image: goalert/build-env:go1.24.2
volumes:
- /var/cache/arc:/var/cache/arc
steps:
- uses: actions/checkout@v4
- name: Set git safe directory
run: git config --global --add safe.directory $GITHUB_WORKSPACE

- uses: actions/cache@v4
with:
key: cache-${{ hashFiles('go.mod','go.sum','package.json','bun.lock','*.version')}}
path: |
/go/pkg/mod
$HOME/.cache/goalert-gettool
$HOME/.cache/Cypress
$HOME/.cache/ms-playwright
$HOME/.bun/install/cache

# Run repo & linting checks
- name: Run Tests
run: make test-unit test-components

# smoke:
# name: Smoke Tests (behavioral tests)
# # You need to use the INSTALLATION_NAME from the previous step
# runs-on: arc-runner-set
# needs: build
# strategy:
# matrix:
# postgres_version: [13, 17]
# container:
# image: goalert/build-env:go1.24.2
# volumes:
# - /var/cache/arc:/var/cache/arc
# steps:
# - uses: actions/checkout@v4
# - name: Set git safe directory
# run: git config --global --add safe.directory $GITHUB_WORKSPACE

# - name: Restore cache
# run: bash ./devtools/scripts/ci-cache.sh restore
# env: { CI: '1' }

# # Run repo & linting checks
# - name: Run Smoke Tests
# run: start_postgres ${{ matrix.postgres_version }} make smoketest

# playwright:
# name: Playwright Tests
# # You need to use the INSTALLATION_NAME from the previous step
# runs-on: arc-runner-set
# needs: build
# strategy:
# matrix:
# postgres_version: [13, 17]
# container:
# image: goalert/build-env:go1.24.2
# volumes:
# - /var/cache/arc:/var/cache/arc
# steps:
# - uses: actions/checkout@v4
# - name: Set git safe directory
# run: git config --global --add safe.directory $GITHUB_WORKSPACE

# - name: Restore cache
# run: bash ./devtools/scripts/ci-cache.sh restore
# env: { CI: '1' }

# # Run repo & linting checks
# - name: Run Smoke Tests
# run: bash -c 'start_postgres ${{ matrix.postgres_version }} make playwright-run'

# cy-wide:
# name: Cypess Widescreen Tests
# # You need to use the INSTALLATION_NAME from the previous step
# runs-on: arc-runner-set
# needs: build
# strategy:
# matrix:
# postgres_version: [13, 17]
# container:
# image: goalert/build-env:go1.24.2
# volumes:
# - /var/cache/arc:/var/cache/arc
# steps:
# - uses: actions/checkout@v4
# - name: Set git safe directory
# run: git config --global --add safe.directory $GITHUB_WORKSPACE

# - name: Restore cache
# run: bash ./devtools/scripts/ci-cache.sh restore
# env: { CI: '1' }

# # Run repo & linting checks
# - name: Run Smoke Tests
# run: bash -c 'start_postgres ${{ matrix.postgres_version }} make cy-wide-prod-run'

# cy-mobile:
# name: Cypess Mobile Tests
# # You need to use the INSTALLATION_NAME from the previous step
# runs-on: arc-runner-set
# needs: build
# strategy:
# matrix:
# postgres_version: [13, 17]
# container:
# image: goalert/build-env:go1.24.2
# volumes:
# - /var/cache/arc:/var/cache/arc
# steps:
# - uses: actions/checkout@v4
# - name: Set git safe directory
# run: git config --global --add safe.directory $GITHUB_WORKSPACE

# - name: Restore cache
# run: bash ./devtools/scripts/ci-cache.sh restore
# env: { CI: '1' }

# # Run repo & linting checks
# - name: Run Smoke Tests
# run: bash -c 'start_postgres ${{ matrix.postgres_version }} make cy-mobile-prod-run'
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,25 @@ $(BIN_DIR)/tools/mailpit: mailpit.version
$(BIN_DIR)/tools/bun: bun.version
go tool gettool -t bun -v $(shell cat bun.version) -o $@

.PHONY: setup-cypress
setup-cypress: $(BIN_DIR)/tools/bun
bun x cypress install

.PHONY: setup-playwright
setup-playwright: $(BIN_DIR)/tools/bun
bun x playwright install

.PHONY: deps
deps: setup-cypress setup-playwright ## Install all dependencies
go get tool ./...

.PHONY: cache
cache: deps
$(MAKE) -j4 binaries

.PHONY: binaries
binaries: bin/goalert bin/goalert.cover bin/goalert-linux-amd64.tgz bin/goalert-linux-arm.tgz bin/goalert-linux-arm64.tgz bin/goalert-darwin-amd64.tgz bin/goalert-windows-amd64.zip ## Prime the build cache by building all binaries

bun.lock: $(BIN_DIR)/tools/bun
$(BIN_DIR)/tools/bun install
touch "$@"
Expand Down Expand Up @@ -226,6 +245,10 @@ generate: $(NODE_DEPS) pkg/sysapi/sysapi.pb.go pkg/sysapi/sysapi_grpc.pb.go
$(SQLC) generate
go generate ./...

.PHONY: self-test
self-test:
$(MAKE) bin/goalert BUNDLE=1
./bin/goalert self-test --offline

test-all: test-unit test-components test-smoke test-integration
test-integration: playwright-run cy-wide-prod-run cy-mobile-prod-run
Expand Down Expand Up @@ -321,6 +344,7 @@ resetdb: config.json.bak ## Recreate the database leaving it empty (no migration
go tool resetdb --no-migrate

clean: ## Clean up build artifacts
chmod +w -f -R bin || true
rm -rf bin node_modules web/src/node_modules .pnp.cjs .pnp.loader.mjs web/src/build/static .yarn storybook-static

new-migration:
Expand Down
2 changes: 1 addition & 1 deletion bun.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.5
1.2.9
3 changes: 2 additions & 1 deletion devtools/ci/dockerfiles/build-env/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ RUN apt-get update && apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
unzip \
gnupg-agent \
software-properties-common \
build-essential \
Expand All @@ -26,7 +27,7 @@ RUN \
rm -rf /var/lib/apt/lists/*

# Postgres
ENV PGDATA=/var/lib/postgresql/data PGUSER=postgres DB_URL=postgresql://postgres@?client_encoding=UTF8
ENV PGDATA=/var/lib/postgresql/data PGUSER=postgres DB_URL=postgresql://postgres@?client_encoding=UTF8&sslmode=disable
RUN mkdir -p ${PGDATA} /run/postgresql /var/log/postgresql &&\
chown postgres ${PGDATA} /run/postgresql /var/log/postgresql &&\
su postgres -c "/usr/lib/postgresql/13/bin/initdb $PGDATA" &&\
Expand Down
78 changes: 75 additions & 3 deletions devtools/gettool/fetchfile.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,65 @@
package main

import (
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
)

var errMiss = fmt.Errorf("file not found in cache")

func hash256(in string) string {
sum := sha256.Sum256([]byte(in))
return hex.EncodeToString(sum[:])
}

func getCacheFile(url string) (*os.File, int64, error) {
if cacheDir == "" {
return nil, 0, errMiss
}

file := filepath.Join(cacheDir, hash256(url)+".data")
fd, err := os.Open(file)
if errors.Is(err, os.ErrNotExist) {
return nil, 0, errMiss
}
info, err := fd.Stat()
if err != nil {
return nil, 0, fmt.Errorf("stat: %w", err)
}
return fd, info.Size(), nil
}

func mkCacheFile(url string) (*os.File, error) {
file := filepath.Join(cacheDir, hash256(url)+".data.tmp")
err := os.MkdirAll(cacheDir, 0o755)
if err != nil {
return nil, fmt.Errorf("create cache dir: %w", err)
}

fd, err := os.Create(file)
if err != nil {
return nil, fmt.Errorf("create cache file: %w", err)
}
return fd, nil
}

// fetchFile will download and open a file with the contents of `url`.
func fetchFile(url string) (*os.File, int64, error) {
file, size, err := getCacheFile(url)
if err == nil {
return file, size, nil
}
if err != errMiss {
return nil, 0, fmt.Errorf("getCacheFile: %w", err)
}

resp, err := http.Get(url)
if err != nil {
return nil, 0, fmt.Errorf("fetch: %w", err)
Expand All @@ -18,16 +69,37 @@ func fetchFile(url string) (*os.File, int64, error) {
return nil, 0, fmt.Errorf("non-200 response: %s", resp.Status)
}

fd, err := os.CreateTemp("", "*.zip")
if err != nil {
return nil, 0, fmt.Errorf("create temp file: %w", err)
var fd *os.File
var cacheFailed bool
if cacheDir != "" {
fd, err = mkCacheFile(url)
if err != nil {
log.Println("failed to update cache:", err)
}
}

if fd == nil {
fd, err = os.CreateTemp("", "*.zip")
if err != nil {
return nil, 0, fmt.Errorf("create temp file: %w", err)
}
cacheFailed = true
}

n, err := io.Copy(fd, resp.Body)
if err != nil {
fd.Close()
return nil, 0, fmt.Errorf("download file '%s': %w", url, err)
}

if !cacheFailed {
err = os.Rename(fd.Name(), filepath.Join(cacheDir, hash256(url)+".data"))
if err != nil {
fd.Close()
return nil, 0, fmt.Errorf("rename cache file: %w", err)
}
}

_, err = fd.Seek(0, 0)
if err != nil {
fd.Close()
Expand Down
15 changes: 15 additions & 0 deletions devtools/gettool/run.go → devtools/gettool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,30 @@ package main
import (
"flag"
"log"
"os"
"path/filepath"
)

var cacheDir string

func main() {
tool := flag.String("t", "", "Tool to fetch.")
version := flag.String("v", "", "Version of the tool to fetch.")
output := flag.String("o", "", "Output file/dir.")
flag.StringVar(&cacheDir, "c", os.Getenv("GETTOOL_CACHE"), "Cache dir.")
flag.Parse()
log.SetFlags(log.Lshortfile)

if cacheDir != "" {
// do nothing, already set
} else if base := os.Getenv("XDG_CACHE_HOME"); base != "" {
// use the XDG_CACHE_HOME
cacheDir = filepath.Join(base, "goalert-gettool")
} else if home := os.Getenv("HOME"); home != "" {
// use the HOME dir
cacheDir = filepath.Join(home, ".cache", "goalert-gettool")
}

if *tool == "" {
log.Fatal("-t flag is required")
}
Expand Down
Loading
Loading