Skip to content

Commit f797506

Browse files
committed
Merge branch 'bq/add-base-actions' of https://github.com/coder/coder into bq/add-base-actions
2 parents c1d3046 + 0987ed1 commit f797506

File tree

19 files changed

+902
-247
lines changed

19 files changed

+902
-247
lines changed

.github/actions/setup-go/action.yaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,42 @@ inputs:
55
version:
66
description: "The Go version to use."
77
default: "1.24.2"
8+
use-preinstalled-go:
9+
description: "Whether to use preinstalled Go."
10+
default: "false"
11+
use-temp-cache-dirs:
12+
description: "Whether to use temporary GOCACHE and GOMODCACHE directories."
13+
default: "false"
814
runs:
915
using: "composite"
1016
steps:
17+
- name: Override GOCACHE and GOMODCACHE
18+
shell: bash
19+
if: inputs.use-temp-cache-dirs == 'true'
20+
run: |
21+
# cd to another directory to ensure we're not inside a Go project.
22+
# That'd trigger Go to download the toolchain for that project.
23+
cd "$RUNNER_TEMP"
24+
# RUNNER_TEMP should be backed by a RAM disk on Windows if
25+
# coder/setup-ramdisk-action was used
26+
export GOCACHE_DIR="$RUNNER_TEMP""\go-cache"
27+
export GOMODCACHE_DIR="$RUNNER_TEMP""\go-mod-cache"
28+
export GOPATH_DIR="$RUNNER_TEMP""\go-path"
29+
mkdir -p "$GOCACHE_DIR"
30+
mkdir -p "$GOMODCACHE_DIR"
31+
mkdir -p "$GOPATH_DIR"
32+
go env -w GOCACHE="$GOCACHE_DIR"
33+
go env -w GOMODCACHE="$GOMODCACHE_DIR"
34+
go env -w GOPATH="$GOPATH_DIR"
35+
1136
- name: Setup Go
1237
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
1338
with:
14-
go-version: ${{ inputs.version }}
39+
go-version: ${{ inputs.use-preinstalled-go == 'false' && inputs.version || '' }}
1540

1641
- name: Install gotestsum
1742
shell: bash
18-
run: go install gotest.tools/gotestsum@latest
43+
run: go install gotest.tools/gotestsum@3f7ff0ec4aeb6f95f5d67c998b71f272aa8a8b41 # v1.12.1
1944

2045
# It isn't necessary that we ever do this, but it helps
2146
# separate the "setup" from the "run" times.

.github/actions/upload-datadog/action.yaml

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ runs:
1010
steps:
1111
- shell: bash
1212
run: |
13+
set -e
14+
1315
owner=${{ github.repository_owner }}
1416
echo "owner: $owner"
1517
if [[ $owner != "coder" ]]; then
@@ -21,8 +23,45 @@ runs:
2123
echo "No API key provided, skipping..."
2224
exit 0
2325
fi
24-
npm install -g @datadog/datadog-ci@2.21.0
25-
datadog-ci junit upload --service coder ./gotests.xml \
26+
27+
BINARY_VERSION="v2.48.0"
28+
BINARY_HASH_WINDOWS="b7bebb8212403fddb1563bae84ce5e69a70dac11e35eb07a00c9ef7ac9ed65ea"
29+
BINARY_HASH_MACOS="e87c808638fddb21a87a5c4584b68ba802965eb0a593d43959c81f67246bd9eb"
30+
BINARY_HASH_LINUX="5e700c465728fff8313e77c2d5ba1ce19a736168735137e1ddc7c6346ed48208"
31+
32+
TMP_DIR=$(mktemp -d)
33+
34+
if [[ "${{ runner.os }}" == "Windows" ]]; then
35+
BINARY_PATH="${TMP_DIR}/datadog-ci.exe"
36+
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_win-x64"
37+
elif [[ "${{ runner.os }}" == "macOS" ]]; then
38+
BINARY_PATH="${TMP_DIR}/datadog-ci"
39+
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_darwin-arm64"
40+
elif [[ "${{ runner.os }}" == "Linux" ]]; then
41+
BINARY_PATH="${TMP_DIR}/datadog-ci"
42+
BINARY_URL="https://github.com/DataDog/datadog-ci/releases/download/${BINARY_VERSION}/datadog-ci_linux-x64"
43+
else
44+
echo "Unsupported OS: ${{ runner.os }}"
45+
exit 1
46+
fi
47+
48+
echo "Downloading DataDog CI binary version ${BINARY_VERSION} for ${{ runner.os }}..."
49+
curl -sSL "$BINARY_URL" -o "$BINARY_PATH"
50+
51+
if [[ "${{ runner.os }}" == "Windows" ]]; then
52+
echo "$BINARY_HASH_WINDOWS $BINARY_PATH" | sha256sum --check
53+
elif [[ "${{ runner.os }}" == "macOS" ]]; then
54+
echo "$BINARY_HASH_MACOS $BINARY_PATH" | shasum -a 256 --check
55+
elif [[ "${{ runner.os }}" == "Linux" ]]; then
56+
echo "$BINARY_HASH_LINUX $BINARY_PATH" | sha256sum --check
57+
fi
58+
59+
# Make binary executable (not needed for Windows)
60+
if [[ "${{ runner.os }}" != "Windows" ]]; then
61+
chmod +x "$BINARY_PATH"
62+
fi
63+
64+
"$BINARY_PATH" junit upload --service coder ./gotests.xml \
2665
--tags os:${{runner.os}} --tags runner_name:${{runner.name}}
2766
env:
2867
DATADOG_API_KEY: ${{ inputs.api-key }}

.github/workflows/ci.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ jobs:
313313
run: ./scripts/check_unstaged.sh
314314

315315
test-go:
316-
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'windows-latest-16-cores' || matrix.os }}
316+
runs-on: ${{ matrix.os == 'ubuntu-latest' && github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || matrix.os == 'macos-latest' && github.repository_owner == 'coder' && 'depot-macos-latest' || matrix.os == 'windows-2022' && github.repository_owner == 'coder' && 'depot-windows-2022-16' || matrix.os }}
317317
needs: changes
318318
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
319319
timeout-minutes: 20
@@ -326,17 +326,31 @@ jobs:
326326
- windows-2022
327327
steps:
328328
- name: Harden Runner
329+
# Harden Runner is only supported on Ubuntu runners.
330+
if: runner.os == 'Linux'
329331
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0
330332
with:
331333
egress-policy: audit
332334

335+
# Set up RAM disks to speed up the rest of the job. This action is in
336+
# a separate repository to allow its use before actions/checkout.
337+
- name: Setup RAM Disks
338+
if: runner.os == 'Windows'
339+
uses: coder/setup-ramdisk-action@79dacfe70c47ad6d6c0dd7f45412368802641439
340+
333341
- name: Checkout
334342
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
335343
with:
336344
fetch-depth: 1
337345

338346
- name: Setup Go
339347
uses: ./.github/actions/setup-go
348+
with:
349+
# Runners have Go baked-in and Go will automatically
350+
# download the toolchain configured in go.mod, so we don't
351+
# need to reinstall it. It's faster on Windows runners.
352+
use-preinstalled-go: ${{ runner.os == 'Windows' }}
353+
use-temp-cache-dirs: ${{ runner.os == 'Windows' }}
340354

341355
- name: Setup Terraform
342356
uses: ./.github/actions/setup-tf

agent/agentssh/agentssh_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,11 @@ func TestNewServer_CloseActiveConnections(t *testing.T) {
214214
}
215215

216216
for _, ch := range waitConns {
217-
<-ch
217+
select {
218+
case <-ctx.Done():
219+
t.Fatal("timeout")
220+
case <-ch:
221+
}
218222
}
219223

220224
return s, wg.Wait

coderd/workspaceagentsrpc_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func TestWorkspaceAgentReportStats(t *testing.T) {
3232
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
3333
OrganizationID: user.OrganizationID,
3434
OwnerID: user.UserID,
35+
LastUsedAt: dbtime.Now().Add(-time.Minute),
3536
}).WithAgent().Do()
3637

3738
ac := agentsdk.New(client.URL)

enterprise/coderd/prebuilds/reconcile.go

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ type StoreReconciler struct {
4040
registerer prometheus.Registerer
4141
metrics *MetricsCollector
4242

43-
cancelFn context.CancelCauseFunc
44-
running atomic.Bool
45-
stopped atomic.Bool
46-
done chan struct{}
43+
cancelFn context.CancelCauseFunc
44+
running atomic.Bool
45+
stopped atomic.Bool
46+
done chan struct{}
47+
provisionNotifyCh chan database.ProvisionerJob
4748
}
4849

4950
var _ prebuilds.ReconciliationOrchestrator = &StoreReconciler{}
@@ -56,13 +57,14 @@ func NewStoreReconciler(store database.Store,
5657
registerer prometheus.Registerer,
5758
) *StoreReconciler {
5859
reconciler := &StoreReconciler{
59-
store: store,
60-
pubsub: ps,
61-
logger: logger,
62-
cfg: cfg,
63-
clock: clock,
64-
registerer: registerer,
65-
done: make(chan struct{}, 1),
60+
store: store,
61+
pubsub: ps,
62+
logger: logger,
63+
cfg: cfg,
64+
clock: clock,
65+
registerer: registerer,
66+
done: make(chan struct{}, 1),
67+
provisionNotifyCh: make(chan database.ProvisionerJob, 10),
6668
}
6769

6870
reconciler.metrics = NewMetricsCollector(store, logger, reconciler)
@@ -100,6 +102,29 @@ func (c *StoreReconciler) Run(ctx context.Context) {
100102
// NOTE: without this atomic bool, Stop might race with Run for the c.cancelFn above.
101103
c.running.Store(true)
102104

105+
// Publish provisioning jobs outside of database transactions.
106+
// A connection is held while a database transaction is active; PGPubsub also tries to acquire a new connection on
107+
// Publish, so we can exhaust available connections.
108+
//
109+
// A single worker dequeues from the channel, which should be sufficient.
110+
// If any messages are missed due to congestion or errors, provisionerdserver has a backup polling mechanism which
111+
// will periodically pick up any queued jobs (see poll(time.Duration) in coderd/provisionerdserver/acquirer.go).
112+
go func() {
113+
for {
114+
select {
115+
case <-c.done:
116+
return
117+
case <-ctx.Done():
118+
return
119+
case job := <-c.provisionNotifyCh:
120+
err := provisionerjobs.PostJob(c.pubsub, job)
121+
if err != nil {
122+
c.logger.Error(ctx, "failed to post provisioner job to pubsub", slog.Error(err))
123+
}
124+
}
125+
}
126+
}()
127+
103128
for {
104129
select {
105130
// TODO: implement pubsub listener to allow reconciling a specific template imperatively once it has been changed,
@@ -576,10 +601,16 @@ func (c *StoreReconciler) provision(
576601
return xerrors.Errorf("provision workspace: %w", err)
577602
}
578603

579-
err = provisionerjobs.PostJob(c.pubsub, *provisionerJob)
580-
if err != nil {
581-
// Client probably doesn't care about this error, so just log it.
582-
c.logger.Error(ctx, "failed to post provisioner job to pubsub", slog.Error(err))
604+
if provisionerJob == nil {
605+
return nil
606+
}
607+
608+
// Publish provisioner job event outside of transaction.
609+
select {
610+
case c.provisionNotifyCh <- *provisionerJob:
611+
default: // channel full, drop the message; provisioner will pick this job up later with its periodic check, though.
612+
c.logger.Warn(ctx, "provisioner job notification queue full, dropping",
613+
slog.F("job_id", provisionerJob.ID), slog.F("prebuild_id", prebuildID.String()))
583614
}
584615

585616
c.logger.Info(ctx, "prebuild job scheduled", slog.F("transition", transition),

0 commit comments

Comments
 (0)