on: push: branches: - main pull_request: branches: - main release: types: - published name: build-test permissions: read-all jobs: build-test-arch: name: Build and test ZOT permissions: contents: write packages: write runs-on: ubuntu-latest strategy: matrix: os: [linux, darwin, freebsd] arch: [amd64, arm64] steps: - name: Check out source code uses: actions/checkout@v4 - uses: ./.github/actions/clean-runner - name: Install go uses: actions/setup-go@v4 with: cache: false go-version: 1.20.x - name: Cache go dependencies id: cache-go-dependencies uses: actions/cache@v3 with: path: | ~/go/pkg/mod key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go-mod- - name: Cache go build output id: cache-go-build uses: actions/cache@v3 with: path: | ~/.cache/go-build key: ${{ matrix.os }}-${{ matrix.arch }}-go-build-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ matrix.os }}-${{ matrix.arch }}-go-build- - name: Install go dependencies if: steps.cache-go-dependencies.outputs.cache-hit != 'true' run: | cd $GITHUB_WORKSPACE go mod download - name: Install other dependencies run: | cd $GITHUB_WORKSPACE go install github.com/swaggo/swag/cmd/swag@v1.8.12 sudo apt-get update sudo apt-get install rpm sudo apt-get install snapd sudo apt-get install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config git clone https://github.com/containers/skopeo -b v1.12.0 $GITHUB_WORKSPACE/src/github.com/containers/skopeo cd $GITHUB_WORKSPACE/src/github.com/containers/skopeo && \ make bin/skopeo && \ sudo cp bin/skopeo /usr/bin && \ rm -rf $GITHUB_WORKSPACE/src/github.com/containers/skopeo cd $GITHUB_WORKSPACE curl -Lo notation.tar.gz https://github.com/notaryproject/notation/releases/download/v1.0.0-rc.4/notation_1.0.0-rc.4_linux_amd64.tar.gz sudo tar xvzf notation.tar.gz -C /usr/bin notation rm -f notation.tar.gz go install github.com/wadey/gocovmerge@latest - if: matrix.os == 'linux' && matrix.arch == 'amd64' name: Setup localstack service run: | pip install localstack # Install LocalStack cli docker pull localstack/localstack:1.3 # Make sure to pull the latest version of the image localstack start -d # Start LocalStack in the background echo "Waiting for LocalStack startup..." # Wait 30 seconds for the LocalStack container localstack wait -t 30 # to become ready before timing out echo "Startup complete" aws --endpoint-url=http://localhost:4566 s3api create-bucket --bucket zot-storage --region us-east-2 --create-bucket-configuration="{\"LocationConstraint\": \"us-east-2\"}" aws dynamodb --endpoint-url http://localhost:4566 --region "us-east-2" create-table --table-name BlobTable --attribute-definitions AttributeName=Digest,AttributeType=S --key-schema AttributeName=Digest,KeyType=HASH --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 env: AWS_ACCESS_KEY_ID: fake AWS_SECRET_ACCESS_KEY: fake - name: Check disk space before build run: | cd $GITHUB_WORKSPACE set -x df -h sudo ls -lRh /tmp/* || true sudo du -sh /tmp || true sudo du -sh /tmp/* || true sudo find /tmp/ -size +5M | sudo xargs ls -lh du -sh ./* || true find ./ -size +5M | xargs ls -lh sudo du -sh /var/ sudo du -sh /var/lib/docker/ du -sh /home/runner/work/ set +x - name: Run build and test timeout-minutes: 80 run: | echo "Building for $OS:$ARCH" cd $GITHUB_WORKSPACE if [[ $OS == "linux" && $ARCH == "amd64" ]]; then make sudo env "PATH=$PATH" make privileged-test else make binary binary-minimal binary-debug cli bench exporter-minimal fi env: S3MOCK_ENDPOINT: localhost:4566 DYNAMODBMOCK_ENDPOINT: http://localhost:4566 AWS_ACCESS_KEY_ID: fake AWS_SECRET_ACCESS_KEY: fake OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - if: matrix.os == 'linux' && matrix.arch == 'amd64' name: Stop localstack run: | localstack stop - name: Check disk space after build if: always() run: | cd $GITHUB_WORKSPACE set -x df -h sudo ls -lRh /tmp/* || true sudo du -sh /tmp || true sudo du -sh /tmp/* || true sudo find /tmp/ -size +5M | sudo xargs ls -lh du -sh ./* || true find ./ -size +5M | xargs ls -lh sudo du -sh /var/ sudo du -sh /var/lib/docker/ du -sh /home/runner/work/ set +x - name: Upload code coverage uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} - name: Generate GraphQL Introspection JSON on Release if: github.event_name == 'release' && github.event.action == 'published' && matrix.os == 'linux' && matrix.arch == 'amd64' run: | bin/zot-linux-amd64 serve examples/config-search.json & sleep 10 curl -X POST -H "Content-Type: application/json" -d @.pkg/debug/githubWorkflows/introspection-query.json http://localhost:5000/v2/_zot/ext/search | jq > bin/zot-gql-introspection-result.json pkill zot - if: github.event_name == 'release' && github.event.action == 'published' name: Publish artifacts on releases uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: bin/z* tag: ${{ github.ref }} overwrite: true file_glob: true push-image: if: github.event_name == 'release' && github.event.action== 'published' name: Push OCI images to GitHub Packages runs-on: ubuntu-latest permissions: contents: read security-events: write packages: write strategy: matrix: os: [linux, darwin] arch: [amd64, arm64] steps: - name: Check out the repo uses: actions/checkout@v4 - name: Log in to GitHub Docker Registry uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push zot container image uses: project-stacker/stacker-build-push-action@main with: file: 'build/stacker.yaml' build-args: | RELEASE_TAG=${{ github.event.release.tag_name }} COMMIT=${{ github.event.release.tag_name }}-${{ github.sha }} OS=${{ matrix.os }} ARCH=${{ matrix.arch }} REPO_NAME=zot-${{ matrix.os }}-${{ matrix.arch }} url: docker://ghcr.io/${{ github.repository_owner }} tags: ${{ github.event.release.tag_name }} latest username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Run zot container image with docker run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then docker run -d -p 5000:5000 ghcr.io/${{ github.repository_owner }}/zot-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5000/v2/' docker kill $(docker ps -q) fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Run zot container image with podman run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then podman run -d -p 5000:5000 ghcr.io/${{ github.repository_owner }}/zot-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5000/v2/' podman kill --all fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Build and push zot-minimal container image uses: project-stacker/stacker-build-push-action@main with: file: 'build/stacker-minimal.yaml' build-args: | RELEASE_TAG=${{ github.event.release.tag_name }} COMMIT=${{ github.event.release.tag_name }}-${{ github.sha }} OS=${{ matrix.os }} ARCH=${{ matrix.arch }} EXT=-minimal REPO_NAME=zot-minimal-${{ matrix.os }}-${{ matrix.arch }} url: docker://ghcr.io/${{ github.repository_owner }} tags: ${{ github.event.release.tag_name }} latest username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Run zot-minimal container image with docker run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then docker run -d -p 5000:5000 ghcr.io/${{ github.repository_owner }}/zot-minimal-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5000/v2/' docker kill $(docker ps -q) fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Run zot-minimal container image with podman run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then podman run -d -p 5000:5000 ghcr.io/${{ github.repository_owner }}/zot-minimal-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5000/v2/' podman kill --all fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Build and push zot-exporter container image uses: project-stacker/stacker-build-push-action@main with: file: 'build/stacker-zxp.yaml' build-args: | RELEASE_TAG=${{ github.event.release.tag_name }} COMMIT=${{ github.event.release.tag_name }}-${{ github.sha }} OS=${{ matrix.os }} ARCH=${{ matrix.arch }} REPO_NAME=zxp-${{ matrix.os }}-${{ matrix.arch }} url: docker://ghcr.io/${{ github.repository_owner }} tags: ${{ github.event.release.tag_name }} latest username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Run zot-exporter container image with docker run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then docker run -d -p 5001:5001 ghcr.io/${{ github.repository_owner }}/zxp-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5001/metrics' docker kill $(docker ps -q) fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Run zot-exporter container image with podman run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then podman run -d -p 5001:5001 ghcr.io/${{ github.repository_owner }}/zxp-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} sleep 2 curl --connect-timeout 5 \ --max-time 10 \ --retry 12 \ --retry-max-time 360 \ --retry-connrefused \ 'http://localhost:5001/metrics' podman kill --all fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Build and push zb container image uses: project-stacker/stacker-build-push-action@main with: file: 'build/stacker-zb.yaml' build-args: | RELEASE_TAG=${{ github.event.release.tag_name }} COMMIT=${{ github.event.release.tag_name }}-${{ github.sha }} OS=${{ matrix.os }} ARCH=${{ matrix.arch }} REPO_NAME=zb-${{ matrix.os }}-${{ matrix.arch }} url: docker://ghcr.io/${{ github.repository_owner }} tags: ${{ github.event.release.tag_name }} latest username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Run zb container image with docker run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then docker run ghcr.io/${{ github.repository_owner }}/zb-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} --help fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Run zb container image with podman run: | if [[ $OS == "linux" && $ARCH == "amd64" ]]; then podman run ghcr.io/${{ github.repository_owner }}/zb-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }} --help fi env: OS: ${{ matrix.os }} ARCH: ${{ matrix.arch }} - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: 'ghcr.io/${{ github.repository }}-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }}' format: 'sarif' output: 'trivy-results.sarif' env: TRIVY_USERNAME: ${{ github.actor }} TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - name: Run Trivy vulnerability scanner (minimal) uses: aquasecurity/trivy-action@master with: image-ref: 'ghcr.io/${{ github.repository }}-minimal-${{ matrix.os }}-${{ matrix.arch }}:${{ github.event.release.tag_name }}' format: 'sarif' output: 'trivy-results.sarif' env: TRIVY_USERNAME: ${{ github.actor }} TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v2.21.5 with: sarif_file: 'trivy-results.sarif' update-helm-chart: if: github.event_name == 'release' && github.event.action== 'published' needs: push-image name: Update Helm Chart permissions: contents: write packages: write runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: ref: main fetch-depth: '0' - name: Checkout project-zot/helm-charts uses: actions/checkout@v4 with: repository: project-zot/helm-charts ref: main fetch-depth: '0' token: ${{ secrets.HELM_PUSH_TOKEN }} path: ./helm-charts - name: Configure Git run: | git config --global user.name 'github-actions' git config --global user.email 'github-actions@users.noreply.github.com' - name: Update appVersion uses: mikefarah/yq@master with: cmd: yq -i '.appVersion = "${{ github.event.release.tag_name }}"' 'helm-charts/charts/zot/Chart.yaml' - name: Update image tag uses: mikefarah/yq@master with: cmd: yq -i '.image.tag = "${{ github.event.release.tag_name }}"' 'helm-charts/charts/zot/values.yaml' - name: Update version run: | sudo apt-get install pip pip install pybump pybump bump --file helm-charts/charts/zot/Chart.yaml --level patch - name: Push changes to project-zot/helm-charts run: | cd ./helm-charts git commit -am "build: automated update of Helm Chart" git push