diff --git a/claude-code/Dockerfile.arm64 b/claude-code/Dockerfile.arm64 deleted file mode 120000 index 1d1fe94df..000000000 --- a/claude-code/Dockerfile.arm64 +++ /dev/null @@ -1 +0,0 @@ -Dockerfile \ No newline at end of file diff --git a/claude-code/Dockerfile.arm64 b/claude-code/Dockerfile.arm64 new file mode 100644 index 000000000..373427537 --- /dev/null +++ b/claude-code/Dockerfile.arm64 @@ -0,0 +1,44 @@ +FROM debian:bookworm-slim + +ARG CLAUDE_CODE_VERSION=2.1.105 + +LABEL version="${CLAUDE_CODE_VERSION}" + +# Common dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + ca-certificates \ + git \ + jq \ + unzip \ + python3 \ + awscli \ + gpg \ + openssh-client \ + bash \ + less \ + && rm -rf /var/lib/apt/lists/* + +# yq (latest) +RUN curl -fsSL "https://github.com/mikefarah/yq/releases/latest/download/yq_linux_$(dpkg --print-architecture)" \ + -o /usr/local/bin/yq \ + && chmod +x /usr/local/bin/yq + +# GitHub CLI +RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + -o /usr/share/keyrings/githubcli-archive-keyring.gpg \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \ + > /etc/apt/sources.list.d/github-cli.list \ + && apt-get update \ + && apt-get install -y --no-install-recommends gh \ + && rm -rf /var/lib/apt/lists/* + +# Non-root user +RUN useradd -m -s /bin/bash claude +USER claude +ENV HOME=/home/claude +ENV PATH="/home/claude/.local/bin:${PATH}" +WORKDIR /home/claude + +# Claude Code CLI (Native Install) +RUN curl -fsSL https://claude.ai/install.sh | bash -s "${CLAUDE_CODE_VERSION}" diff --git a/claude-code/Makefile b/claude-code/Makefile index 5f5b1b4f1..3edd4f0a4 100644 --- a/claude-code/Makefile +++ b/claude-code/Makefile @@ -5,25 +5,59 @@ PLATFORM:=$(shell case "$(ARCH)" in \ (*) echo $(ARCH) ;; \ esac) +ARM64_SUFFIX:=aarch64 +AMD64_SUFFIX:=x86_64 +SUFFIX:=$(shell case "$(ARCH)" in \ + ("arm64"|"aarch64") echo "$(ARM64_SUFFIX)" ;; \ + ("x86_64") echo "$(AMD64_SUFFIX)" ;; \ + (*) echo $(ARCH) ;; \ +esac) + +# $(call image_ref,version,suffix) -> chatwork/claude-code:[-] +image_ref=chatwork/claude-code:$(1)$(if $(2),-$(2)) + .PHONY: build build: - @docker buildx build -t chatwork/`basename $$PWD`:latest --platform linux/${PLATFORM} -f Dockerfile --load .; \ - version=$$(docker inspect -f {{.Config.Labels.version}} chatwork/`basename $$PWD`:latest); \ + @docker buildx build -t $(call image_ref,latest) --platform linux/${PLATFORM} -f Dockerfile --load .; \ + version=$$(docker inspect -f {{.Config.Labels.version}} $(call image_ref,latest)); \ if [ -n "$$version" ]; then \ - docker tag chatwork/`basename $$PWD`:latest chatwork/`basename $$PWD`:$$version; \ + docker tag $(call image_ref,latest) $(call image_ref,$$version); \ fi .PHONY: test test: build docker-compose -f docker-compose.test.yml up --no-start sut - docker cp $(shell pwd)/goss `basename $$PWD`:/goss + docker cp $(shell pwd)/goss claude-code:/goss docker-compose -f docker-compose.test.yml up --no-recreate --exit-code-from sut sut .PHONY: push push: - @version=$$(docker inspect -f {{.Config.Labels.version}} chatwork/`basename $$PWD`:latest); \ - if docker inspect --format='{{index .RepoDigests 0}}' chatwork/$$(basename $$PWD):$$version >/dev/null 2>&1; then \ + @version=$$(docker inspect -f {{.Config.Labels.version}} $(call image_ref,latest)); \ + if docker inspect --format='{{index .RepoDigests 0}}' $(call image_ref,$$version,$(SUFFIX)) >/dev/null 2>&1; then \ echo "no changes"; \ else \ - docker buildx build -t chatwork/`basename $$PWD`:$$version -t chatwork/`basename $$PWD`:latest --platform linux/amd64,linux/arm64 -f Dockerfile --push .; \ + docker buildx build -t $(call image_ref,$$version,$(SUFFIX)) --platform linux/${PLATFORM} -f Dockerfile --push .; \ fi + +.PHONY: manifest\:push +manifest\:push: + @version=$$(docker inspect -f {{.Config.Labels.version}} $(call image_ref,latest)); \ + if docker inspect --format='{{index .RepoDigests 0}}' $(call image_ref,$$version) >/dev/null 2>&1; then \ + echo "no changes"; \ + else \ + docker pull $(call image_ref,$$version,$(ARM64_SUFFIX)); \ + docker pull $(call image_ref,$$version,$(AMD64_SUFFIX)); \ + arm64_digest=$$(docker inspect -f '{{index .RepoDigests 0}}' $(call image_ref,$$version,$(ARM64_SUFFIX))); \ + amd64_digest=$$(docker inspect -f '{{index .RepoDigests 0}}' $(call image_ref,$$version,$(AMD64_SUFFIX))); \ + docker buildx imagetools create -t $(call image_ref,$$version) $$arm64_digest $$amd64_digest; \ + docker buildx imagetools create -t $(call image_ref,latest) $$arm64_digest $$amd64_digest; \ + hub-tool tag rm $(call image_ref,$$version,$(ARM64_SUFFIX)) -f; \ + hub-tool tag rm $(call image_ref,$$version,$(AMD64_SUFFIX)) -f; \ + fi + +.PHONY: manifest\:succeed-message +manifest\:succeed-message: + @version=$$(docker inspect -f {{.Config.Labels.version}} $(call image_ref,latest)); \ + echo "Released new tags."; \ + echo "- $(call image_ref,$$version)"; \ + echo "- $(call image_ref,latest)" diff --git a/claude-code/goss/goss.yaml b/claude-code/goss/goss.yaml index 71db1504f..49b3904da 100644 --- a/claude-code/goss/goss.yaml +++ b/claude-code/goss/goss.yaml @@ -18,3 +18,5 @@ command: exit-status: 0 gpg --version: exit-status: 0 + aws --version: + exit-status: 0