diff --git a/.github/workflows/publish-latest-image.yml b/.github/workflows/publish-latest-image.yml new file mode 100644 index 00000000..7df218a7 --- /dev/null +++ b/.github/workflows/publish-latest-image.yml @@ -0,0 +1,52 @@ +name: publish-latest-image + +on: + workflow_dispatch: + push: + branches: + - main + +permissions: + contents: read + packages: write + +jobs: + publish-latest-image: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + with: + go-version-file: "go.mod" + check-latest: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0 + with: + version: v2.11.2 + args: release --config .goreleaser.latest.yml --snapshot --clean + + - name: Push snapshot images + run: | + docker push "ghcr.io/${GITHUB_REPOSITORY}:latest-amd64" + docker push "ghcr.io/${GITHUB_REPOSITORY}:latest-arm64" + + - name: Create and push manifest for :latest tag + run: | + docker manifest create "ghcr.io/${GITHUB_REPOSITORY}:latest" "ghcr.io/${GITHUB_REPOSITORY}:latest-amd64" "ghcr.io/${GITHUB_REPOSITORY}:latest-arm64" + docker manifest push "ghcr.io/${GITHUB_REPOSITORY}:latest" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..fd1eacbc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: release + +on: + release: + types: + - published + +permissions: + contents: write + packages: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + with: + go-version-file: "go.mod" + check-latest: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + - name: Login to GitHub Container Registry + uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0 + with: + version: v2.11.2 + args: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index ebad078c..586edf3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea bin +dist secret.env certs diff --git a/.goreleaser.latest.yml b/.goreleaser.latest.yml new file mode 100644 index 00000000..5c2af4cc --- /dev/null +++ b/.goreleaser.latest.yml @@ -0,0 +1,76 @@ +version: 2 + +env: + - GITHUB_REPOSITORY={{ if index .Env "GITHUB_REPOSITORY" }}{{ .Env.GITHUB_REPOSITORY }}{{ else }}temporalio/temporal-worker-controller{{ end }} + +before: + hooks: + - go mod download + +announce: + skip: true + +changelog: + disable: true + +release: + disable: true + +builds: + - id: nix + dir: cmd + binary: temporal-worker-controller + ldflags: + - -s -w -X github.com/temporalio/temporal-worker-controller/internal/controller.Version={{.Version}} + goarch: + - amd64 + - arm64 + goos: + - linux + env: + - CGO_ENABLED=0 + +checksum: + disable: true + +# Only build Docker images with 'latest' tag +dockers: + - image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-amd64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - --platform=linux/amd64 + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.description=Temporal Worker Controller for Kubernetes + - --label=org.opencontainers.image.url=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.version=latest + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.licenses=MIT + extra_files: + - LICENSE + + - image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-arm64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - --platform=linux/arm64 + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.description=Temporal Worker Controller for Kubernetes + - --label=org.opencontainers.image.url=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.version=latest + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.licenses=MIT + extra_files: + - LICENSE + +docker_manifests: + - name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest-arm64" \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..ac656190 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,96 @@ +version: 2 + +env: + - GITHUB_REPOSITORY={{ if index .Env "GITHUB_REPOSITORY" }}{{ .Env.GITHUB_REPOSITORY }}{{ else }}temporalio/temporal-worker-controller{{ end }} + +before: + hooks: + - go mod download + +announce: + skip: true + +changelog: + disable: true + +release: + prerelease: auto + draft: false + +builds: + - id: nix + dir: cmd + binary: temporal-worker-controller + ldflags: + - -s -w -X github.com/temporalio/temporal-worker-controller/internal/controller.Version={{.Version}} + goarch: + - amd64 + - arm64 + goos: + - linux + - darwin + env: + - CGO_ENABLED=0 + +archives: + - id: default + name_template: "temporal-worker-controller_{{ .Version }}_{{ .Os }}_{{ .Arch }}" + files: + - LICENSE + +checksum: + name_template: "checksums.txt" + algorithm: sha256 + +dockers: + - image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:v{{ .Major }}.{{ .Minor }}-amd64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - --platform=linux/amd64 + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.description=Temporal Worker Controller for Kubernetes + - --label=org.opencontainers.image.url=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.version={{ .Version }} + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.licenses=MIT + extra_files: + - LICENSE + + - image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-arm64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:v{{ .Major }}.{{ .Minor }}-arm64" + dockerfile: Dockerfile.goreleaser + use: buildx + build_flag_templates: + - --platform=linux/arm64 + - --label=org.opencontainers.image.title={{ .ProjectName }} + - --label=org.opencontainers.image.description=Temporal Worker Controller for Kubernetes + - --label=org.opencontainers.image.url=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPOSITORY }} + - --label=org.opencontainers.image.version={{ .Version }} + - --label=org.opencontainers.image.created={{ time "2006-01-02T15:04:05Z07:00" }} + - --label=org.opencontainers.image.revision={{ .FullCommit }} + - --label=org.opencontainers.image.licenses=MIT + extra_files: + - LICENSE + +docker_manifests: + - name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-arm64" + + - name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:v{{ .Major }}.{{ .Minor }}" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:v{{ .Major }}.{{ .Minor }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:v{{ .Major }}.{{ .Minor }}-arm64" + + - name_template: "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest" + image_templates: + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-amd64" + - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Tag }}-arm64" \ No newline at end of file diff --git a/Dockerfile.goreleaser b/Dockerfile.goreleaser new file mode 100644 index 00000000..9ebdfc6f --- /dev/null +++ b/Dockerfile.goreleaser @@ -0,0 +1,5 @@ +FROM gcr.io/distroless/static-debian12:nonroot + +COPY temporal-worker-controller /usr/local/bin/temporal-worker-controller + +ENTRYPOINT ["temporal-worker-controller"] \ No newline at end of file diff --git a/internal/controller/util.go b/internal/controller/util.go index 3c42ef76..1c1285b1 100644 --- a/internal/controller/util.go +++ b/internal/controller/util.go @@ -14,8 +14,16 @@ const ( defaultControllerIdentity = "temporal-worker-controller" ) -// getControllerVersion returns the version from environment variable (set by Helm from image.tag) +// Version is set by goreleaser via ldflags at build time +var Version = "unknown" + +// getControllerVersion returns the version, preferring build-time injection over environment variable func getControllerVersion() string { + // First check if version was injected at build time + if Version != "" && Version != "unknown" { + return Version + } + // Fall back to environment variable (set by Helm from image.tag) if version := os.Getenv("CONTROLLER_VERSION"); version != "" { return version }