Skip to content
Open
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
6 changes: 3 additions & 3 deletions .github/workflows/check-dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ jobs:
working-directory: actions/spa-setup-task

steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # ratchet:actions/setup-node@v6
with:
node-version: '20'
- run: yarn install
Expand All @@ -41,7 +41,7 @@ jobs:
id: diff

# If index.js was different than expected, upload the expected version as an artifact
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # ratchet:actions/upload-artifact@v6
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with:
name: dist
Expand Down
12 changes: 5 additions & 7 deletions .github/workflows/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ jobs:
- component: canary-deployer
chart: true
steps:
- uses: actions/checkout@v4 # ratchet:exclude
- uses: azure/setup-helm@b9e51907a09c216f16ebe8536097933489208112 # ratchet:azure/setup-helm@v3
- uses: actions/checkout@v6 # ratchet:exclude
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # ratchet:azure/setup-helm@v4
if: matrix.chart
with:
version: "v3.11.1"
- name: "Build and push image"
uses: nais/platform-build-push-sign@main # ratchet:exclude
id: build_push_sign
Expand Down Expand Up @@ -78,7 +76,7 @@ jobs:
- name: "Authenticate to Google Cloud"
if: matrix.chart && github.ref == 'refs/heads/master'
id: "auth"
uses: "google-github-actions/auth@v2" # ratchet:exclude
uses: "google-github-actions/auth@v3" # ratchet:exclude
with:
workload_identity_provider: ${{ secrets.NAIS_IO_WORKLOAD_IDENTITY_PROVIDER }}
service_account: "gh-deploy@nais-io.iam.gserviceaccount.com"
Expand Down Expand Up @@ -136,9 +134,9 @@ jobs:
- build_and_push
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4 # ratchet:exclude
- uses: actions/checkout@v6 # ratchet:exclude

- uses: actions/setup-go@v5
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # ratchet:actions/setup-go@v6
with:
go-version: 'stable'

Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/test-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
name: Deploy to NAIS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2
env:
APIKEY: ${{ secrets.NAIS_DEPLOY_APIKEY }}
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/job.yaml
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent commit hash used for actions/checkout@v4. This file uses commit hash 34e114876b0b11c390a56381ad16ebd13914f8d5, while other workflow files use de0fac2e4500dabe0009e67214ff5f5447ce83dd for v6. If the intention is to update to the same version, the commit hashes should match. If this is intentionally kept at v4 while others use v6, please clarify why.

Suggested change
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6

Copilot uses AI. Check for mistakes.
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2 # ratchet:exclude
env:
APIKEY: ${{ secrets.NAIS_DEPLOY_APIKEY }}
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/job.yaml
12 changes: 6 additions & 6 deletions .github/workflows/test-naisjob-without-schedule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2
env:
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/naisjob-without-schedule.yaml
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2 # ratchet:exclude
env:
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/naisjob-without-schedule.yaml
14 changes: 7 additions & 7 deletions .github/workflows/test-naisjob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
name: Deploy to NAIS
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2
env:
APIKEY: ${{ secrets.NAIS_DEPLOY_APIKEY }}
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/naisjob.yaml
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # ratchet:actions/checkout@v6
- name: deploy to ${{ github.event.inputs.cluster }}
uses: nais/deploy/actions/deploy@v2 # ratchet:exclude
env:
APIKEY: ${{ secrets.NAIS_DEPLOY_APIKEY }}
CLUSTER: ${{ github.event.inputs.cluster }}
RESOURCE: testdata/naisjob.yaml
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @navikt/aura
* @navikt/nais
6 changes: 3 additions & 3 deletions Dockerfile.canary-deployer
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-alpine AS builder
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git make curl
ENV GOOS=linux
Expand All @@ -11,12 +11,12 @@ COPY go.sum .
RUN go mod download
COPY . .

RUN make kubebuilder
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The builder stage runs go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest, pulling and executing whatever the current latest version is from a third-party module, which is a supply chain attack risk. A compromised or hijacked upstream could inject code into your CI pipeline simply by publishing a new "latest" release. Mitigate this by pinning setup-envtest to a specific, trusted version tag rather than using @latest.

Copilot uses AI. Check for mistakes.
RUN make test
RUN make deploy-alpine


FROM alpine:3
FROM alpine:3.20

WORKDIR /app
RUN apk add --no-cache ca-certificates
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile.deploy
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-alpine AS builder
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git make curl
ENV GOOS=linux
Expand All @@ -11,12 +11,12 @@ COPY go.sum .
RUN go mod download
COPY . .

RUN make kubebuilder
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest introduces an unpinned build-time dependency on a third-party tool, which can be exploited as a supply chain vector. Any malicious change in the upstream that passes basic Go module checks would be executed automatically in your CI when building this image. Pin this tool to a specific release version and update it consciously rather than tracking @latest.

Copilot uses AI. Check for mistakes.
RUN make test
RUN make deploy-alpine


FROM alpine:3
FROM alpine:3.20

WORKDIR /app
RUN apk add --no-cache ca-certificates wget
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile.deploy-action
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-alpine AS builder
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git make curl
ENV GOOS=linux
Expand All @@ -11,12 +11,12 @@ COPY go.sum .
RUN go mod download
COPY . .

RUN make kubebuilder
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest command in the builder stage fetches and runs a mutable version of a third-party tool during image builds, which is a supply chain risk. If the upstream module is compromised or publishes a malicious update, your CI builds will automatically incorporate and execute it. To reduce this risk, pin setup-envtest to a fixed, reviewed version tag instead of relying on @latest.

Copilot uses AI. Check for mistakes.
RUN make test
RUN make deploy-alpine


FROM alpine:3
FROM alpine:3.20

WORKDIR /app
ENV TZ="Europe/Oslo"
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile.deployd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-alpine AS builder
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git make curl
ENV GOOS=linux
Expand All @@ -11,12 +11,12 @@ COPY go.sum .
RUN go mod download
COPY . .

RUN make kubebuilder
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest in this Dockerfile pulls and executes an unpinned third-party tool at build time, creating a supply chain attack surface. A compromised or malicious upstream release would be picked up automatically by future builds and executed in the CI environment. Pin this to a specific, vetted version instead of @latest so upgrades happen only after review.

Copilot uses AI. Check for mistakes.
RUN make test
RUN make deployd-alpine


FROM alpine:3
FROM alpine:3.20

WORKDIR /app
RUN apk add --no-cache ca-certificates
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile.hookd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.24-alpine AS builder
FROM golang:1.25-alpine AS builder

RUN apk add --no-cache git make curl
ENV GOOS=linux
Expand All @@ -11,12 +11,12 @@ COPY go.sum .
RUN go mod download
COPY . .

RUN make kubebuilder
RUN go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest in the build stage pulls and executes a mutable third-party tool version at image build time, which is a classic supply chain risk. If the upstream module or its distribution channel is ever compromised, every new image build would automatically consume and execute the malicious version in CI. Prefer pinning this dependency to a specific, reviewed version (e.g., an explicit tagged release) and only updating it intentionally after review.

Copilot uses AI. Check for mistakes.
RUN make test
RUN make hookd-alpine


FROM alpine:3
FROM alpine:3.20

WORKDIR /app
RUN apk add --no-cache ca-certificates
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 NAV
Copyright (c) NAV

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
34 changes: 29 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ PROTOC = $(shell which protoc)
PROTOC_GEN_GO = $(shell which protoc-gen-go)
BUILDTIME = $(shell date "+%s")
DATE = $(shell date "+%Y-%m-%d")
K8S_VERSION := 1.27.1
K8S_VERSION := 1.33.5
LAST_COMMIT = $(shell git rev-parse --short HEAD)
VERSION ?= $(DATE)-$(LAST_COMMIT)
LDFLAGS := -X github.com/nais/deploy/pkg/version.Revision=$(LAST_COMMIT) -X github.com/nais/deploy/pkg/version.Date=$(DATE) -X github.com/nais/deploy/pkg/version.BuildUnixTime=$(BUILDTIME)
arch := $(shell uname -m | sed s/aarch64/arm64/ | sed s/x86_64/amd64/)
os := $(shell uname -s | tr '[:upper:]' '[:lower:]')
testbin_dir := ./.testbin/
tools_archive := kubebuilder-tools-${K8S_VERSION}-$(os)-$(arch).tar.gz
SETUP_ENVTEST := $(shell command -v setup-envtest 2>/dev/null || command -v $(shell go env GOPATH)/bin/setup-envtest 2>/dev/null)

.PHONY: all proto hookd deployd token-generator deploy alpine test docker upload deploy-alpine hookd-alpine deployd-alpine
.PHONY: all proto hookd deployd token-generator deploy alpine test docker upload deploy-alpine hookd-alpine deployd-alpine envtest-info

all: hookd deployd deploy

Expand Down Expand Up @@ -63,8 +64,18 @@ alpine:
go build -a -installsuffix cgo -o bin/deployd -ldflags "-s $(LDFLAGS)" cmd/deployd/main.go
go build -a -installsuffix cgo -o bin/deploy -ldflags "-s $(LDFLAGS)" cmd/deploy/main.go

test: kubebuilder
go test ./... -count=1
test:
@if [ -n "$(SETUP_ENVTEST)" ]; then \
ASSETS=$$($(SETUP_ENVTEST) use -p path); \
echo "Using envtest assets: $$ASSETS"; \
export KUBEBUILDER_ASSETS=$$ASSETS; \
go test ./... -count=1; \
else \
echo "setup-envtest not found; falling back to kubebuilder tools download"; \
$(MAKE) kubebuilder; \
export KUBEBUILDER_ASSETS=$(testbin_dir); \
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The export statement is missing before KUBEBUILDER_ASSETS assignment in the fallback path. The variable is set but not exported, which means it won't be available to the go test subprocess. Change line 76 to: export KUBEBUILDER_ASSETS=$(testbin_dir); \ (add 'export' before the variable assignment, similar to line 71).

Copilot uses AI. Check for mistakes.
go test ./... -count=1; \
fi

migration:
go generate ./...
Expand All @@ -75,7 +86,7 @@ kubebuilder: $(testbin_dir)/$(tools_archive)

$(testbin_dir)/$(tools_archive):
mkdir -p $(testbin_dir)
curl -L -O --output-dir $(testbin_dir) "https://storage.googleapis.com/kubebuilder-tools/$(tools_archive)"
curl -fL --output $(testbin_dir)/$(tools_archive) "https://storage.googleapis.com/kubebuilder-tools/$(tools_archive)"

check:
go run honnef.co/go/tools/cmd/staticcheck ./...
Expand All @@ -88,3 +99,16 @@ hookd-alpine:

deploy-alpine:
go build -a -installsuffix cgo -o bin/deploy -ldflags "-s $(LDFLAGS)" ./cmd/deploy/

envtest-info:
@echo "setup-envtest (PATH): $$(command -v setup-envtest || true)"
@echo "setup-envtest (GOPATH/bin): $$(command -v $(shell go env GOPATH)/bin/setup-envtest || true)"
@echo "GOPATH: $$(go env GOPATH)"
@echo "KUBEBUILDER_ASSETS (env): $${KUBEBUILDER_ASSETS:-<unset>}"
@if [ -n "$(SETUP_ENVTEST)" ]; then \
ASSETS=$$($(SETUP_ENVTEST) use -p path); \
echo "envtest assets: $$ASSETS"; \
ls -la "$$ASSETS"; \
else \
echo "setup-envtest not found"; \
fi
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
source <(setup-envtest use -p env)
```

Troubleshooting envtest assets:
```
make envtest-info
```

Docker image builds also run `make test`, which uses `setup-envtest` when available.

## Running locally

For a combination of more tools running locally ([hookd](https://github.com/nais/deploy), [Console frontend](https://github.com/nais/console-frontend) and more), check out the [nais/features-dev](https://github.com/nais/features-dev) repo.
Expand Down Expand Up @@ -189,7 +196,6 @@ Once the above components are running and configured, you can deploy using the f
--wait \
;
```

```
./bin/deploy --resource res.yaml --cluster local --apikey 20cefcd6bd0e8b8860c4ea90e75d7123019ed7866c61bd09e23821948878a11d --deploy-server http://localhost:8080 --wait
```
Expand Down
21 changes: 15 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
module github.com/nais/deploy

go 1.24.0
go 1.25.7

tool (
github.com/vektra/mockery/v2
golang.org/x/vuln/cmd/govulncheck
google.golang.org/grpc/cmd/protoc-gen-go-grpc
google.golang.org/protobuf/cmd/protoc-gen-go
honnef.co/go/tools/cmd/staticcheck
mvdan.cc/gofumpt
)

require (
github.com/aymerick/raymond v2.0.2+incompatible
Expand All @@ -20,22 +29,17 @@ require (
github.com/spf13/pflag v1.0.6
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.10.0
github.com/vektra/mockery/v2 v2.53.2
go.opentelemetry.io/otel v1.36.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0
go.opentelemetry.io/otel/sdk v1.36.0
go.opentelemetry.io/otel/trace v1.36.0
golang.org/x/vuln v1.1.4
google.golang.org/grpc v1.72.2
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
google.golang.org/protobuf v1.36.5
gopkg.in/sakura-internet/go-rison.v3 v3.2.0
gopkg.in/yaml.v2 v2.4.0
honnef.co/go/tools v0.6.0
k8s.io/api v0.32.2
k8s.io/apimachinery v0.32.2
k8s.io/client-go v0.32.2
mvdan.cc/gofumpt v0.8.0
sigs.k8s.io/controller-runtime v0.20.2
)

Expand Down Expand Up @@ -115,6 +119,7 @@ require (
github.com/spf13/cobra v1.8.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/vektra/mockery/v2 v2.53.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
Expand All @@ -134,17 +139,21 @@ require (
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.10.0 // indirect
golang.org/x/tools v0.32.0 // indirect
golang.org/x/vuln v1.1.4 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
honnef.co/go/tools v0.6.0 // indirect
k8s.io/apiextensions-apiserver v0.32.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
mvdan.cc/gofumpt v0.8.0 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tools]
go = "1.25.7"
8 changes: 5 additions & 3 deletions pkg/deployd/deployd/deployd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,11 @@ func newTestRig() (*testRig, error) {

rig := &testRig{}

err = os.Setenv("KUBEBUILDER_ASSETS", testBinDirectory())
if err != nil {
return nil, fmt.Errorf("failed to set environment variable: %w", err)
if os.Getenv("KUBEBUILDER_ASSETS") == "" {
err = os.Setenv("KUBEBUILDER_ASSETS", testBinDirectory())
if err != nil {
return nil, fmt.Errorf("failed to set environment variable: %w", err)
}
}

rig.scheme, err = scheme.All()
Expand Down
Loading