Skip to content
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
186 changes: 35 additions & 151 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,157 +1,41 @@
name: CI
# Shared go-service CI from compliance-framework/workflows, pinned to a release commit that
# ccf-bump moves. The status check to require is `ci / required`.
name: ci

on:
pull_request:
# closed: notify marks the PR's needs-human card handled and closes its CI incident.
types: [opened, edited, synchronize, reopened, labeled, unlabeled, closed]
push:
branches:
- main
- release-*
pull_request: {}
branches: [main]

env:
# Common versions
GOLANGCI_VERSION: 'v2.11.4'
permissions: {}

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version-file: "go.mod"

- name: Find the Go Cache
id: go
run: |
echo "build-cache=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT

- name: Cache the Go Build Cache
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.build-cache }}
key: ${{ runner.os }}-build-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Cache Go Dependencies
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.mod-cache }}
key: ${{ runner.os }}-mod-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Lint
uses: golangci/golangci-lint-action@v7
with:
version: ${{ env.GOLANGCI_VERSION }}
skip-cache: true
skip-save-cache: true
args: --timeout=30m

check-diff:
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/main'

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Go
uses: actions/setup-go@v4
id: setup-go
with:
go-version-file: "go.mod"

- name: Download Go modules
if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
run: go mod download

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"

- name: Check Diff
run: |
make check-diff

unit-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Fetch History
run: git fetch --prune --unshallow

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version-file: "go.mod"

- name: Find the Go Cache
id: go
run: |
echo "build-cache=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT

- name: Cache the Go Build Cache
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.build-cache }}
key: ${{ runner.os }}-build-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Cache Go Dependencies
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.mod-cache }}
key: ${{ runner.os }}-mod-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Generate Swagger Docs
run: |
make swag

- name: Run Unit Tests
run: |
make test

integration-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Fetch History
run: git fetch --prune --unshallow

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version-file: "go.mod"

- name: Find the Go Cache
id: go
run: |
echo "build-cache=$(go env GOCACHE)" >> $GITHUB_OUTPUT
echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT

- name: Cache the Go Build Cache
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.build-cache }}
key: ${{ runner.os }}-build-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Cache Go Dependencies
uses: actions/cache@v3
with:
path: ${{ steps.go.outputs.mod-cache }}
key: ${{ runner.os }}-mod-${{ github.sha }}-${{ hashFiles('**/go.sum') }}

- name: Generate Swagger Docs
run: |
make swag

- name: Run Unit Tests
run: |
make test-integration
ci:
uses: compliance-framework/workflows/.github/workflows/ci-go-service.yml@899dbe5d7dac02de5fd60a92d764b189259e03dd # v1.5.0
with:
# Regenerate the Swagger docs (docs/) from the handler annotations before vet, the tests
# and the make targets, as the old CI did before its tests.
prepare-command: make swag
# test-integration starts postgres through testcontainers (Docker is on the runner);
# check-diff reruns swag and fails when the tree is dirty (stale committed docs).
make-targets: test-integration check-diff
# api's lint has needed up to 30 minutes (the old CI ran it with --timeout=30m).
lint-timeout-minutes: 30
permissions:
actions: read
contents: read
pull-requests: read
security-events: write
secrets: inherit

notify:
needs: [ci]
if: always()
uses: compliance-framework/workflows/.github/workflows/notify-failure.yml@899dbe5d7dac02de5fd60a92d764b189259e03dd # v1.5.0
with:
needs: ${{ toJSON(needs) }}
permissions:
contents: read
secrets: inherit
19 changes: 11 additions & 8 deletions internal/service/scheduler/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package scheduler

import (
"context"
"sync/atomic"
"testing"
"time"

Expand All @@ -10,19 +11,21 @@ import (
"go.uber.org/zap"
)

// mockJob is safe for concurrent use: cron runs Execute on its own goroutines, and those
// runs can overlap each other and the test's reads.
type mockJob struct {
name string
executed bool
execCount int
executed atomic.Bool
execCount atomic.Int32
}

func (j *mockJob) Name() string {
return j.name
}

func (j *mockJob) Execute(ctx context.Context) error {
j.executed = true
j.execCount++
j.executed.Store(true)
j.execCount.Add(1)
return nil
}

Expand Down Expand Up @@ -67,8 +70,8 @@ func TestCronScheduler_RunNow(t *testing.T) {
err = sched.RunNow(ctx, "test-job")
require.NoError(t, err)

assert.True(t, job.executed)
assert.Equal(t, 1, job.execCount)
assert.True(t, job.executed.Load())
assert.Equal(t, int32(1), job.execCount.Load())
}

func TestCronScheduler_RunNow_NotFound(t *testing.T) {
Expand Down Expand Up @@ -98,8 +101,8 @@ func TestCronScheduler_StartStop(t *testing.T) {
<-ctx.Done()

// Job should have executed at least once
assert.True(t, job.executed)
assert.GreaterOrEqual(t, job.execCount, 1)
assert.True(t, job.executed.Load())
assert.GreaterOrEqual(t, job.execCount.Load(), int32(1))
}

func TestScheduleConstants(t *testing.T) {
Expand Down
Loading