Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f6d0470
Modernize Docker build with parameterization and registry flexibility
chaptersix Nov 21, 2025
bda2d14
Address PR feedback: simplify Dockerfile and workflows
chaptersix Nov 21, 2025
eb253ec
Merge origin/main, keeping JavaScript registry logic and major versio…
chaptersix Nov 21, 2025
de99805
Convert build-and-publish.yml registry logic to JavaScript
chaptersix Nov 21, 2025
3d355a1
Convert Dockerfile to use distroless base image
chaptersix Nov 22, 2025
5f92312
Move docker-bake.hcl to root and update references
chaptersix Nov 22, 2025
2d3086e
Convert Dockerfile to use scratch base for maximum minimalism
chaptersix Nov 22, 2025
f64d6f2
Fix Dockerfile to work with GoReleaser output structure
chaptersix Nov 22, 2025
144d933
Clean up Docker build file organization
chaptersix Nov 22, 2025
312bcef
Add latest tag detection for Docker image builds
chaptersix Nov 22, 2025
92f17f3
Fix latest tag logic to push both latest and release tags
chaptersix Nov 22, 2025
86172ad
Fix Docker build bugs: remove invalid platform ARG and correct TAG_LA…
chaptersix Nov 22, 2025
3dedd3e
Use intermediate dist stage for reliable multi-platform builds
chaptersix Nov 22, 2025
942869d
Simplify Dockerfile to use Alpine base without intermediate stage
chaptersix Nov 22, 2025
1db66a6
Clean up Dockerfile: remove syntax comment and simplify structure
chaptersix Nov 22, 2025
ff9df1a
Add explicit chmod to COPY instruction for binary permissions
chaptersix Nov 22, 2025
21f02c6
Restore intermediate dist stage for explicit path normalization
chaptersix Nov 22, 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
1 change: 0 additions & 1 deletion .github/docker/.gitignore

This file was deleted.

34 changes: 0 additions & 34 deletions .github/docker/cli.Dockerfile

This file was deleted.

147 changes: 88 additions & 59 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1
uses: actions/setup-go@v4
with:
go-version-file: "go.mod"
check-latest: true
Expand All @@ -69,6 +69,25 @@ jobs:
id: go
run: echo "go=$(go version | cut -d ' ' -f 3)" >> $GITHUB_OUTPUT

- name: Check if release is latest
if: inputs.publish
id: check_latest_release
uses: actions/github-script@v7
with:
script: |
const releaseTag = '${{ inputs.version }}';
const { data: release } = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: releaseTag
});

const isLatest = !release.prerelease && !release.draft;
core.setOutput('is_latest', isLatest);
console.log(`Release: ${release.tag_name}`);
console.log(`Prerelease: ${release.prerelease}, Draft: ${release.draft}`);
console.log(`Should tag as latest: ${isLatest}`);

- name: Run GoReleaser (release)
if: inputs.publish
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
Expand Down Expand Up @@ -108,60 +127,70 @@ jobs:
INPUT_REGISTRY_NAMESPACE: ${{ inputs.registry_namespace }}
INPUT_IMAGE_NAME: ${{ inputs.image_name }}
REPO_OWNER: ${{ github.repository_owner }}
run: |
echo "cli_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "image_sha_tag=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "image_branch_tag=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT

if [[ "$INPUT_PUBLISH" == "true" ]]; then
# Get version from input, strip 'v' prefix
VERSION="$INPUT_VERSION"
VERSION="${VERSION#v}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
else
echo "version=snapshot" >> $GITHUB_OUTPUT
fi

# Determine registry (with auto-detection for temporalio vs forks)
REGISTRY="$INPUT_REGISTRY"
if [[ -z "$REGISTRY" ]]; then
if [[ "$REPO_OWNER" == "temporalio" ]]; then
REGISTRY="docker.io"
else
REGISTRY="ghcr.io"
fi
fi

# Determine registry type for authentication
if [[ "$REGISTRY" == "ghcr.io" ]]; then
echo "registry_type=ghcr" >> $GITHUB_OUTPUT
elif [[ "$REGISTRY" == "docker.io" ]]; then
echo "registry_type=dockerhub" >> $GITHUB_OUTPUT
else
echo "registry_type=other" >> $GITHUB_OUTPUT
fi

# Set namespace (defaults to repository owner)
NAMESPACE="$INPUT_REGISTRY_NAMESPACE"
if [[ -z "$NAMESPACE" ]]; then
NAMESPACE="$REPO_OWNER"
fi

# Set image name (defaults to 'temporal')
IMAGE_NAME="$INPUT_IMAGE_NAME"
if [[ -z "$IMAGE_NAME" ]]; then
IMAGE_NAME="temporal"
fi

# For Docker Hub, use empty string as registry (special case)
if [[ "$REGISTRY" == "docker.io" ]]; then
echo "image_repo=" >> $GITHUB_OUTPUT
else
echo "image_repo=${REGISTRY}" >> $GITHUB_OUTPUT
fi

echo "image_namespace=${NAMESPACE}" >> $GITHUB_OUTPUT
echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT
uses: actions/github-script@v7
with:
script: |
const inputVersion = process.env.INPUT_VERSION;
const inputPublish = process.env.INPUT_PUBLISH;
const inputRegistry = process.env.INPUT_REGISTRY;
const inputRegistryNamespace = process.env.INPUT_REGISTRY_NAMESPACE;
const inputImageName = process.env.INPUT_IMAGE_NAME;
const repoOwner = process.env.REPO_OWNER;

// Get git information
const { execSync } = require('child_process');
const cliSha = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
const imageShaTag = execSync('git rev-parse --short HEAD', { encoding: 'utf8' }).trim();
const imageBranchTag = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();

core.setOutput('cli_sha', cliSha);
core.setOutput('image_sha_tag', imageShaTag);
core.setOutput('image_branch_tag', imageBranchTag);

// Determine version
let version;
if (inputPublish === 'true') {
// Get version from input, strip 'v' prefix
version = inputVersion.startsWith('v') ? inputVersion.slice(1) : inputVersion;
} else {
version = 'snapshot';
}
core.setOutput('version', version);

// Determine registry (with auto-detection for temporalio vs forks)
let registry = inputRegistry;
if (!registry) {
if (repoOwner === 'temporalio') {
registry = 'docker.io';
} else {
registry = 'ghcr.io';
}
}

// Determine registry type for authentication
let registryType;
if (registry === 'ghcr.io') {
registryType = 'ghcr';
} else if (registry === 'docker.io') {
registryType = 'dockerhub';
} else {
registryType = 'other';
}
core.setOutput('registry_type', registryType);

// Set namespace (defaults to repository owner)
const namespace = inputRegistryNamespace || repoOwner;
core.setOutput('image_namespace', namespace);

// Set image name (defaults to 'temporal')
const imageName = inputImageName || 'temporal';
core.setOutput('image_name', imageName);

// For Docker Hub, use empty string as registry (special case)
const imageRepo = registry === 'docker.io' ? '' : registry;
core.setOutput('image_repo', imageRepo);

console.log(`Registry: ${registry}, Type: ${registryType}, Namespace: ${namespace}, Image: ${imageName}`);

- name: Log in to GitHub Container Registry
if: inputs.publish && steps.meta.outputs.registry_type == 'ghcr'
Expand All @@ -182,15 +211,15 @@ jobs:
if: inputs.publish
run: |
docker buildx bake \
--file .github/docker/docker-bake.hcl \
--file docker-bake.hcl \
--push \
cli
env:
CLI_SHA: ${{ steps.meta.outputs.cli_sha }}
IMAGE_SHA_TAG: ${{ steps.meta.outputs.image_sha_tag }}
IMAGE_BRANCH_TAG: ${{ steps.meta.outputs.image_branch_tag }}
VERSION: ${{ steps.meta.outputs.version }}
TAG_LATEST: false
TAG_LATEST: ${{ steps.check_latest_release.outputs.is_latest == 'true' }}
IMAGE_REPO: ${{ steps.meta.outputs.image_repo }}
IMAGE_NAMESPACE: ${{ steps.meta.outputs.image_namespace }}
IMAGE_NAME: ${{ steps.meta.outputs.image_name }}
Expand All @@ -200,7 +229,7 @@ jobs:
if: ${{ !inputs.publish }}
run: |
docker buildx bake \
--file .github/docker/docker-bake.hcl \
--file docker-bake.hcl \
cli
env:
CLI_SHA: ${{ steps.meta.outputs.cli_sha }}
Expand Down
41 changes: 24 additions & 17 deletions .github/workflows/update-latest-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
uses: actions/checkout@v3
with:
ref: ${{ github.event.release.tag_name }}

Expand Down Expand Up @@ -47,22 +47,29 @@ jobs:
- name: Get registry configuration
if: steps.check_latest.outputs.is_latest == 'true'
id: registry
run: |
REPO_OWNER="${{ github.repository_owner }}"

# Auto-detect registry based on repository owner
if [[ "$REPO_OWNER" == "temporalio" ]]; then
REGISTRY="docker.io"
echo "type=dockerhub" >> $GITHUB_OUTPUT
echo "repo=" >> $GITHUB_OUTPUT
else
REGISTRY="ghcr.io"
echo "type=ghcr" >> $GITHUB_OUTPUT
echo "repo=${REGISTRY}" >> $GITHUB_OUTPUT
fi

echo "namespace=${REPO_OWNER}" >> $GITHUB_OUTPUT
echo "image=temporal" >> $GITHUB_OUTPUT
uses: actions/github-script@v7
with:
script: |
const repoOwner = context.repo.owner;

// Auto-detect registry based on repository owner
let registry, type, repo;
if (repoOwner === 'temporalio') {
registry = 'docker.io';
type = 'dockerhub';
repo = '';
} else {
registry = 'ghcr.io';
type = 'ghcr';
repo = registry;
}

core.setOutput('type', type);
core.setOutput('repo', repo);
core.setOutput('namespace', repoOwner);
core.setOutput('image', 'temporal');

console.log(`Registry: ${registry}, Type: ${type}, Namespace: ${repoOwner}`);

- name: Log in to GitHub Container Registry
if: steps.check_latest.outputs.is_latest == 'true' && steps.registry.outputs.type == 'ghcr'
Expand Down
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Intermediate stage to normalize goreleaser output paths
# This copies both architecture binaries and renames them to clean paths,
# allowing the final stage to select the correct binary using TARGETARCH
FROM scratch AS dist
COPY dist/nix_linux_amd64_v1/temporal /dist/amd64/temporal
COPY dist/nix_linux_arm64_v8.0/temporal /dist/arm64/temporal

FROM alpine:3.22@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412

ARG TARGETARCH

RUN apk add --no-cache ca-certificates
COPY --chmod=755 --from=dist /dist/${TARGETARCH}/temporal /usr/local/bin/temporal
RUN adduser -u 1000 -D temporal
USER temporal

ENTRYPOINT ["temporal"]
31 changes: 0 additions & 31 deletions Makefile

This file was deleted.

10 changes: 2 additions & 8 deletions .github/docker/docker-bake.hcl → docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,17 @@ variable "TAG_LATEST" {
default = false
}

# Alpine base image with digest for reproducible builds
variable "ALPINE_IMAGE" {
default = "alpine:3.22@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412"
}


target "cli" {
dockerfile = ".github/docker/cli.Dockerfile"
dockerfile = "Dockerfile"
context = "."
tags = compact([
IMAGE_REPO == "" ? "${IMAGE_NAMESPACE}/${IMAGE_NAME}:${IMAGE_SHA_TAG}" : "${IMAGE_REPO}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:${IMAGE_SHA_TAG}",
IMAGE_REPO == "" ? "${IMAGE_NAMESPACE}/${IMAGE_NAME}:${VERSION}" : "${IMAGE_REPO}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:${VERSION}",
TAG_LATEST ? (IMAGE_REPO == "" ? "${IMAGE_NAMESPACE}/${IMAGE_NAME}:latest" : "${IMAGE_REPO}/${IMAGE_NAMESPACE}/${IMAGE_NAME}:latest") : "",
])
platforms = ["linux/amd64", "linux/arm64"]
args = {
ALPINE_IMAGE = "${ALPINE_IMAGE}"
}
labels = {
"org.opencontainers.image.title" = "temporal"
"org.opencontainers.image.description" = "Temporal CLI"
Expand Down
Loading