diff --git a/.dockerignore b/.dockerignore index b00143df7..9fa965e3a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ .git* +.github/ +.devcontainer/ .venv __pycache__/ diff --git a/.github/workflows/build-pull-request.yaml b/.github/workflows/build-pull-request.yaml index 2a8b63fe7..fa6285d4e 100644 --- a/.github/workflows/build-pull-request.yaml +++ b/.github/workflows/build-pull-request.yaml @@ -9,10 +9,18 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true +permissions: + contents: read + actions: write + packages: read + jobs: cpp-linter: runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write steps: - uses: actions/checkout@v4 - uses: cpp-linter/cpp-linter-action@main @@ -24,7 +32,7 @@ jobs: style: microsoft ignore: include/argparse lines-changed-only: true - thread-comments: true + thread-comments: update format-review: true tidy-checks: '-*' @@ -34,18 +42,62 @@ jobs: echo "some linter checks failed. ${{ steps.linter.outputs.checks-failed }}" exit 1 - build-n-test: - runs-on: [gpu] + build-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write strategy: + fail-fast: false matrix: - target: [release, develop] + include: + - target: release + os: ubuntu24.04 + cuda_version: 13.2.0 + optix_version: 9.1.0 + geant4_version: 11.4.1 + cmake_version: 4.3.1 + - target: release + os: ubuntu24.04 + cuda_version: 13.0.2 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 + - target: release + os: ubuntu22.04 + cuda_version: 12.1.1 + optix_version: 8.0.0 + geant4_version: 11.3.2 + cmake_version: 3.22.1 + - target: develop + os: ubuntu24.04 + cuda_version: 13.0.2 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 + - target: develop + os: ubuntu24.04 + cuda_version: 12.5.1 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 3.28.3 + - target: develop + os: ubuntu22.04 + cuda_version: 12.1.1 + optix_version: 8.0.0 + geant4_version: 11.3.2 + cmake_version: 3.22.1 steps: - name: Define environment variables run: | - echo IMAGE_NAME=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV - echo IMAGE_TAG=$(echo "PR-${{ github.event.pull_request.number }}-${{ matrix.target }}") >> $GITHUB_ENV + IMAGE_NAME=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')-buildcache + REF_SANITIZED=PR-${{ github.event.pull_request.number }} + BUILD_VARIANT=cuda${{ matrix.cuda_version }}-${{ matrix.target }}-${{ matrix.os }}-optix${{ matrix.optix_version }}-geant4${{ matrix.geant4_version }}-cmake${{ matrix.cmake_version }} + echo IMAGE_NAME=${IMAGE_NAME} >> $GITHUB_ENV + echo IMAGE_TAG=${REF_SANITIZED}-${BUILD_VARIANT} >> $GITHUB_ENV + echo CACHE_REF=${IMAGE_NAME}:${BUILD_VARIANT} >> $GITHUB_ENV - name: Checkout code uses: actions/checkout@v4 @@ -53,29 +105,126 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Build and push with Docker + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build PR image uses: docker/build-push-action@v6 with: context: . - tags: ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + tags: | + ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} target: ${{ matrix.target }} - load: true - cache-from: type=local,src=/home/runner/.buildx-cache - cache-to: type=local,dest=/home/runner/.buildx-cache-new,mode=max - - - name: Move cache - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 + build-args: | + OS=${{ matrix.os }} + CUDA_VERSION=${{ matrix.cuda_version }} + OPTIX_VERSION=${{ matrix.optix_version }} + GEANT4_VERSION=${{ matrix.geant4_version }} + CMAKE_VERSION=${{ matrix.cmake_version }} + cache-from: type=registry,ref=${{ env.CACHE_REF }} + push: ${{ matrix.target == 'develop' && github.event.pull_request.head.repo.full_name == github.repository }} + + test-develop-image: + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + needs: build-image + runs-on: [gpu] + permissions: + contents: read + packages: read + + strategy: + fail-fast: false + matrix: &develop_matrix + include: + - os: ubuntu24.04 + cuda_version: 13.0.2 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 + - os: ubuntu24.04 + cuda_version: 12.5.1 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 3.28.3 + - os: ubuntu22.04 + cuda_version: 12.1.1 + optix_version: 8.0.0 + geant4_version: 11.3.2 + cmake_version: 3.22.1 + + steps: + - name: Define environment variables + run: | + IMAGE_NAME=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')-buildcache + REF_SANITIZED=PR-${{ github.event.pull_request.number }} + BUILD_VARIANT=cuda${{ matrix.cuda_version }}-develop-${{ matrix.os }}-optix${{ matrix.optix_version }}-geant4${{ matrix.geant4_version }}-cmake${{ matrix.cmake_version }} + echo IMAGE_NAME=${IMAGE_NAME} >> $GITHUB_ENV + echo IMAGE_TAG=${REF_SANITIZED}-${BUILD_VARIANT} >> $GITHUB_ENV + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Pull develop image run: | - rm -rf /home/runner/.buildx-cache - mv /home/runner/.buildx-cache-new /home/runner/.buildx-cache + docker pull ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - name: Run tests - if: ${{ matrix.target == 'develop' }} run: | docker run --rm --gpus 'device=1' ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} tests/test_opticks.sh docker run --rm --gpus 'device=1' ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} tests/test_simg4ox.sh docker run --rm --gpus 'device=1' ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} tests/test_GPURaytrace.sh docker run --rm --gpus 'device=1' ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} tests/test_GPUPhotonFileSource.sh docker run --rm --gpus 'device=1' ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} tests/test_GPUPhotonSource_8x8SiPM.sh + + - name: Cleanup local test image + if: ${{ success() }} + run: | + docker image rm -f ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} || true + + + cleanup-pr-images: + if: ${{ success() && github.event.pull_request.head.repo.full_name == github.repository }} + needs: test-develop-image + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: *develop_matrix + + steps: + - name: Define environment variables + run: | + PACKAGE_NAME=$(echo ${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]')-buildcache + REF_SANITIZED=PR-${{ github.event.pull_request.number }} + BUILD_VARIANT=cuda${{ matrix.cuda_version }}-develop-${{ matrix.os }}-optix${{ matrix.optix_version }}-geant4${{ matrix.geant4_version }}-cmake${{ matrix.cmake_version }} + echo PACKAGE_NAME=${PACKAGE_NAME} >> $GITHUB_ENV + echo IMAGE_TAG=${REF_SANITIZED}-${BUILD_VARIANT} >> $GITHUB_ENV + + - name: Delete successful PR image from GHCR + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + OWNER: ${{ github.repository_owner }} + run: | + VERSION_ID=$( + gh api --paginate "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions?per_page=100" \ + --jq ".[] | select((.metadata.container.tags // []) | index(\"$IMAGE_TAG\")) | .id" \ + | head -n 1 + ) + + if [ -z "$VERSION_ID" ]; then + echo "No GHCR version found with tag $IMAGE_TAG" + exit 0 + fi + + echo "Deleting GHCR version $VERSION_ID for tag $IMAGE_TAG" + gh api -X DELETE "/orgs/$OWNER/packages/container/$PACKAGE_NAME/versions/$VERSION_ID" diff --git a/.github/workflows/build-push.yaml b/.github/workflows/build-push.yaml index 65611465b..ef0b04893 100644 --- a/.github/workflows/build-push.yaml +++ b/.github/workflows/build-push.yaml @@ -6,23 +6,65 @@ on: - main - test +permissions: + contents: read + packages: write + jobs: build-push: - runs-on: [gpu] + runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - target: [release, develop] + include: + - target: release + os: ubuntu24.04 + cuda_version: 13.2.0 + optix_version: 9.1.0 + geant4_version: 11.4.1 + cmake_version: 4.3.1 + - target: release + os: ubuntu24.04 + cuda_version: 13.0.2 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 + - target: release + os: ubuntu22.04 + cuda_version: 12.1.1 + optix_version: 8.0.0 + geant4_version: 11.3.2 + cmake_version: 3.22.1 + - target: develop + os: ubuntu24.04 + cuda_version: 13.0.2 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 + - target: develop + os: ubuntu24.04 + cuda_version: 12.5.1 + optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 3.28.3 + - target: develop + os: ubuntu22.04 + cuda_version: 12.1.1 + optix_version: 8.0.0 + geant4_version: 11.3.2 + cmake_version: 3.22.1 steps: - name: Define environment variables run: | - echo IMAGE_NAME=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV - echo IMAGE_TAG=$(echo ${{ matrix.target }}) >> $GITHUB_ENV - if [ "${{ matrix.target }}" = "release" ]; then - echo IMAGE_TAG=latest >> $GITHUB_ENV - fi + IMAGE_NAME=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') + CACHE_IMAGE_NAME=${IMAGE_NAME}-buildcache + BUILD_VARIANT=cuda${{ matrix.cuda_version }}-${{ matrix.target }}-${{ matrix.os }}-optix${{ matrix.optix_version }}-geant4${{ matrix.geant4_version }}-cmake${{ matrix.cmake_version }} + echo IMAGE_NAME=${IMAGE_NAME} >> $GITHUB_ENV + echo IMAGE_TAG=${BUILD_VARIANT} >> $GITHUB_ENV + echo CACHE_REF=${CACHE_IMAGE_NAME}:${BUILD_VARIANT} >> $GITHUB_ENV - name: Checkout code uses: actions/checkout@v4 @@ -37,33 +79,32 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push to registries uses: docker/build-push-action@v6 with: + context: . push: true tags: | - ghcr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - docker.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} target: ${{ matrix.target }} - cache-from: type=local,src=/home/runner/.buildx-cache - cache-to: type=local,dest=/home/runner/.buildx-cache-new,mode=max + build-args: | + OS=${{ matrix.os }} + CUDA_VERSION=${{ matrix.cuda_version }} + OPTIX_VERSION=${{ matrix.optix_version }} + GEANT4_VERSION=${{ matrix.geant4_version }} + CMAKE_VERSION=${{ matrix.cmake_version }} + cache-from: type=registry,ref=${{ env.CACHE_REF }} + cache-to: type=registry,ref=${{ env.CACHE_REF }},mode=max - - name: Move cache - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 + - name: Add devel alias tag for default CUDA + if: ${{ github.ref_name == 'main' && matrix.target == 'develop' && matrix.os == 'ubuntu24.04' && matrix.cuda_version == '13.0.2' && matrix.optix_version == '9.0.0' && matrix.geant4_version == '11.4.1' && matrix.cmake_version == '4.2.1' }} run: | - rm -rf /home/runner/.buildx-cache - mv /home/runner/.buildx-cache-new /home/runner/.buildx-cache + docker buildx imagetools create -t ${{ env.IMAGE_NAME }}:develop ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} cleanup: runs-on: ubuntu-latest needs: build-push steps: - uses: dataaxiom/ghcr-cleanup-action@v1 + with: + packages: ${{ github.event.repository.name }},${{ github.event.repository.name }}-buildcache diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f3531e35b..3992060f1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -21,18 +21,20 @@ jobs: os: ubuntu24.04 cuda_version: 13.0.2 optix_version: 9.0.0 + geant4_version: 11.4.1 + cmake_version: 4.2.1 steps: - name: Define environment variables run: | + IMAGE_NAME=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') + CACHE_IMAGE_NAME=${IMAGE_NAME}-buildcache REF_SANITIZED=$(echo "${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9._-]/-/g') - BUILD_VARIANT=cuda${{ matrix.cuda_version }}-${{ matrix.target }}-${{ matrix.os }}-optix${{ matrix.optix_version }} - echo REF_SANITIZED=$REF_SANITIZED >> $GITHUB_ENV - echo BUILD_VARIANT=$BUILD_VARIANT >> $GITHUB_ENV - echo IMAGE_NAME=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV + BUILD_VARIANT=cuda${{ matrix.cuda_version }}-${{ matrix.target }}-${{ matrix.os }}-optix${{ matrix.optix_version }}-geant4${{ matrix.geant4_version }}-cmake${{ matrix.cmake_version }} + echo IMAGE_NAME=${IMAGE_NAME} >> $GITHUB_ENV echo IMAGE_TAG=${REF_SANITIZED}-${BUILD_VARIANT} >> $GITHUB_ENV echo IMAGE_TAG_SHORT=${REF_SANITIZED} >> $GITHUB_ENV - echo CACHE_SCOPE=${BUILD_VARIANT} >> $GITHUB_ENV + echo CACHE_REF=${CACHE_IMAGE_NAME}:${BUILD_VARIANT} >> $GITHUB_ENV - name: Checkout code uses: actions/checkout@v4 @@ -50,20 +52,26 @@ jobs: - name: Build and push to registries uses: docker/build-push-action@v6 with: + context: . push: true tags: | - ghcr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} - ghcr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG_SHORT }} + ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} + ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG_SHORT }} + ${{ env.IMAGE_NAME }}:latest target: ${{ matrix.target }} build-args: | OS=${{ matrix.os }} CUDA_VERSION=${{ matrix.cuda_version }} OPTIX_VERSION=${{ matrix.optix_version }} - cache-from: type=gha,scope=${{ env.CACHE_SCOPE }} - cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }} + GEANT4_VERSION=${{ matrix.geant4_version }} + CMAKE_VERSION=${{ matrix.cmake_version }} + cache-from: type=registry,ref=${{ env.CACHE_REF }} + cache-to: type=registry,ref=${{ env.CACHE_REF }},mode=max cleanup: runs-on: ubuntu-latest needs: release steps: - uses: dataaxiom/ghcr-cleanup-action@v1 + with: + packages: ${{ github.event.repository.name }},${{ github.event.repository.name }}-buildcache