diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..2502a94d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,85 @@ +name: build + +on: + push: + branches: + - 'main' + - 'release/*' + tags: + - 'v*' + pull_request: + branches: + - '*' + +env: + DOCKERHUB_SLUG: distribution/distribution + +jobs: + build: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - + name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + images: | + ${{ env.DOCKERHUB_SLUG }} + tags: | + type=semver,pattern={{version}} + type=ref,event=pr + type=edge + labels: | + org.opencontainers.image.title=Distribution + org.opencontainers.image.description=The toolkit to pack, ship, store, and deliver container content + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - + name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build artifacts + uses: docker/bake-action@v1 + with: + targets: artifact-all + - + name: Move artifacts + run: | + mv ./bin/**/* ./bin/ + - + name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: registry + path: ./bin/* + if-no-files-found: error + - + name: Build image + uses: docker/bake-action@v1 + with: + files: | + ./docker-bake.hcl + ${{ steps.meta.outputs.bake-file }} + targets: image-all + push: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} + - + name: GitHub Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + draft: true + files: | + bin/*.tar.gz + bin/*.zip + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/conformance.yml b/.github/workflows/conformance.yml index 47224e4d..904a5bd7 100644 --- a/.github/workflows/conformance.yml +++ b/.github/workflows/conformance.yml @@ -8,27 +8,26 @@ jobs: run-conformance-test: runs-on: ubuntu-latest steps: - - name: set up docker - uses: docker-practice/actions-setup-docker@0.0.1 + - + name: Checkout + uses: actions/checkout@v2 with: - docker_version: 18.09 - docker_channel: stable - - - uses: actions/checkout@v2 + fetch-depth: 0 + - + name: Build image + uses: docker/bake-action@v1 with: - path: src/github.com/distribution/distribution - - - name: start distribution server - working-directory: ./src/github.com/distribution/distribution + targets: image-local + - + name: Start distribution server run: | IP=`hostname -I | awk '{print $1}'` echo "IP=$IP" >> $GITHUB_ENV echo "OCI_ROOT_URL=http://$IP:5000" >> $GITHUB_ENV - DISTRIBUTION_REF="local-distribution:v$(date +%Y%m%d%H%M%S)" - docker build -f ./Dockerfile -t "${DISTRIBUTION_REF}" . - docker run --rm -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true -idt "${DISTRIBUTION_REF}" - - - name: Run OCI Distribution Spec conformance tests + DISTRIBUTION_REF="registry:local" + docker run --rm -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true -idt "registry:local" + - + name: Run OCI Distribution Spec conformance tests uses: opencontainers/distribution-spec@main env: OCI_ROOT_URL: ${{ env.OCI_ROOT_URL }} @@ -38,3 +37,13 @@ jobs: OCI_TEST_CONTENT_DISCOVERY: 1 OCI_TEST_CONTENT_MANAGEMENT: 1 OCI_HIDE_SKIPPED_WORKFLOWS: 1 + - + name: Move test results + run: mkdir -p .out/ && mv {report.html,junit.xml} .out/ + - + name: Upload test results + uses: actions/upload-artifact@v2 + with: + name: oci-test-results-${{ github.sha }} + path: .out/ + if-no-files-found: error diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index c1a6110b..0b3c67fe 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -12,28 +12,25 @@ jobs: run-e2e-test: runs-on: ubuntu-latest steps: - - name: set up docker - uses: docker-practice/actions-setup-docker@0.0.1 + - + name: Checkout + uses: actions/checkout@v2 with: - docker_version: 18.09 - docker_channel: stable - - - name: checkout distribution - uses: actions/checkout@master + fetch-depth: 0 + - + name: Build image + uses: docker/bake-action@v1 with: - path: main - - - name: start distribution server + targets: image-local + - + name: Start distribution server run: | IP=`hostname -I | awk '{print $1}'` echo "IP=$IP" >> $GITHUB_ENV echo '{"insecure-registries" : ["'$IP':5000"]}' | sudo tee /etc/docker/daemon.json sudo service docker restart - DISTRIBUTION_REF="local-distribution:v$(date +%Y%m%d%H%M%S)" - cd ./main - docker build -f ./Dockerfile -t "${DISTRIBUTION_REF}" . - docker run --rm -p 5000:5000 -p 5001:5001 -idt "${DISTRIBUTION_REF}" - - - name: script + docker run --rm -p 5000:5000 -p 5001:5001 -idt "registry:local" + - + name: Tests run: | - bash ./main/tests/push.sh $IP + bash ./tests/push.sh $IP diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 57482056..00000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,60 +0,0 @@ -name: Release docker image - -on: - push: - tags: - - "*" - -jobs: - publish: - name: Build and publish docker image - runs-on: ubuntu-latest - env: - DOCKER_BUILDTAGS: "include_oss include_gcs" - CGO_ENABLED: 1 - GO111MODULE: "auto" - GOPATH: ${{ github.workspace }} - GOOS: linux - COMMIT_RANGE: ${{ github.event_name == 'pull_request' && format('{0}..{1}',github.event.pull_request.base.sha, github.event.pull_request.head.sha) || format('{0}..{1}', github.event.before, github.event.after) }} - - steps: - - name: Get git tag - id: get_git_tag - run: echo ::set-output name=git_tag::${GITHUB_REF#refs/tags/} - - - name: Verify git tag - env: - GIT_TAG: ${{ steps.get_git_tag.outputs.git_tag }} - # NOTE: this is a simple Regexp, following the current versioning scheme - # In ideal world we should use this monstrosity: - # https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string - run: | - [[ ${GIT_TAG} =~ ^v[0-9]+.[0-9]+.[0-9]+ ]] - - - name: Check out source code - if: ${{ success() }} - uses: actions/checkout@v2 - with: - ref: ${{ steps.get_git_tag.outputs.git_tag }} - - - name: Set image tag - env: - GIT_TAG: ${{ steps.get_git_tag.outputs.git_tag }} - id: get_image_tag - run: echo ::set-output name=docker_tag::${GIT_TAG} - - - name: Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - if: ${{ success() }} - uses: docker/build-push-action@v2 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64 - push: true - tags: distribution/distribution:{{ steps.get_image_tag.outputs.docker_tag }} diff --git a/Dockerfile b/Dockerfile index 7eb90bb3..723949c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,44 @@ +# syntax=docker/dockerfile:1.3 + ARG GO_VERSION=1.17 +ARG GORELEASER_XX_VERSION=1.2.5 -FROM golang:${GO_VERSION}-alpine3.14 AS build +FROM --platform=$BUILDPLATFORM crazymax/goreleaser-xx:${GORELEASER_XX_VERSION} AS goreleaser-xx +FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS base +COPY --from=goreleaser-xx / / +RUN apk add --no-cache file git +WORKDIR /src +FROM base AS build ENV GO111MODULE=auto -ENV DISTRIBUTION_DIR /go/src/github.com/distribution/distribution -ENV BUILDTAGS include_oss include_gcs +ENV CGO_ENABLED=0 +ARG TARGETPLATFORM +ARG PKG="github.com/distribution/distribution/v3" +ARG BUILDTAGS="include_oss include_gcs" +RUN --mount=type=bind,target=/src,rw \ + --mount=type=cache,target=/root/.cache/go-build \ + --mount=target=/go/pkg/mod,type=cache \ + goreleaser-xx --debug \ + --name="registry" \ + --dist="/out" \ + --main="./cmd/registry" \ + --flags="-v" \ + --ldflags="-s -w -X '$PKG/version.Version={{.Version}}' -X '$PKG/version.Revision={{.Commit}}' -X '$PKG/version.Package=$PKG'" \ + --tags="$BUILDTAGS" \ + --files="LICENSE" \ + --files="README.md" -ARG GOOS=linux -ARG GOARCH=amd64 -ARG GOARM=6 -ARG VERSION -ARG REVISION +FROM scratch AS artifacts +COPY --from=build /out/*.tar.gz / +COPY --from=build /out/*.zip / -RUN set -ex \ - && apk add --no-cache make git file - -WORKDIR $DISTRIBUTION_DIR -COPY . $DISTRIBUTION_DIR -RUN CGO_ENABLED=0 make PREFIX=/go clean binaries && file ./bin/registry | grep "statically linked" +FROM scratch AS binary +COPY --from=build /usr/local/bin/registry* / FROM alpine:3.14 - -RUN set -ex \ - && apk add --no-cache ca-certificates - +RUN apk add --no-cache ca-certificates COPY cmd/registry/config-dev.yml /etc/docker/registry/config.yml -COPY --from=build /go/src/github.com/distribution/distribution/bin/registry /bin/registry +COPY --from=build /usr/local/bin/registry /bin/registry VOLUME ["/var/lib/registry"] EXPOSE 5000 ENTRYPOINT ["registry"] diff --git a/docker-bake.hcl b/docker-bake.hcl new file mode 100644 index 00000000..10a22b75 --- /dev/null +++ b/docker-bake.hcl @@ -0,0 +1,54 @@ +group "default" { + targets = ["image-local"] +} + +// Special target: https://github.com/docker/metadata-action#bake-definition +target "docker-metadata-action" { + tags = ["registry:local"] +} + +target "binary" { + target = "binary" + output = ["./bin"] +} + +target "artifact" { + target = "artifacts" + output = ["./bin"] +} + +target "artifact-all" { + inherits = ["artifact"] + platforms = [ + "darwin/amd64", + "darwin/arm64", + "linux/amd64", + "linux/arm/v5", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm64", + "linux/ppc64le", + "linux/s390x" + ] +} + +target "image" { + inherits = ["docker-metadata-action"] +} + +target "image-local" { + inherits = ["image"] + output = ["type=docker"] +} + +target "image-all" { + inherits = ["image"] + platforms = [ + "linux/amd64", + "linux/arm/v6", + "linux/arm/v7", + "linux/arm64", + "linux/ppc64le", + "linux/s390x" + ] +}