solana: multi-tenant deployment #706
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Anchor Base Image | |
| # Build the anchor-base image when Anchor version changes | |
| # This image pre-compiles Anchor to avoid 6+ minute compile times in CLI builds | |
| # | |
| # Handles three cases: | |
| # 1. Bootstrap: No image exists -> builds and pushes | |
| # 2. Update: Anchor version changed -> builds and pushes | |
| # 3. No-op: Image already exists with correct version -> skips build | |
| # | |
| # Can be called directly or as a reusable workflow from cli.yml | |
| on: | |
| workflow_dispatch: | |
| workflow_call: | |
| outputs: | |
| image: | |
| description: "The full image reference to use" | |
| value: ${{ jobs.build.outputs.image }} | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| # Note: No concurrency block here - when called as reusable workflow, | |
| # github.workflow refers to the CALLER, which would conflict. | |
| # The caller (cli.yml) handles its own concurrency. | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }}/anchor-base | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| packages: write | |
| outputs: | |
| image: ${{ steps.result.outputs.image }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - name: Extract Anchor version from Anchor.toml | |
| id: anchor | |
| run: | | |
| ANCHOR_VERSION=$(grep 'anchor_version' solana/Anchor.toml | sed 's/.*"\(.*\)"/\1/') | |
| echo "version=${ANCHOR_VERSION}" >> $GITHUB_OUTPUT | |
| - name: Check if fork PR | |
| id: check-fork | |
| run: | | |
| if [[ "${{ github.event_name }}" == "pull_request" && "${GITHUB_EVENT_PULL_REQUEST_HEAD_REPO_FULL_NAME}" != "${{ github.repository }}" ]]; then | |
| echo "is_fork=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "is_fork=false" >> $GITHUB_OUTPUT | |
| fi | |
| env: | |
| GITHUB_EVENT_PULL_REQUEST_HEAD_REPO_FULL_NAME: ${{ github.event.pull_request.head.repo.full_name }} | |
| - name: Check if anchor-base image exists | |
| id: check | |
| run: | | |
| if docker manifest inspect ${{ env.REGISTRY }}/${IMAGE_NAME}:${STEPS_ANCHOR_OUTPUTS_VERSION} > /dev/null 2>&1; then | |
| echo "exists=true" >> $GITHUB_OUTPUT | |
| echo "Image ${{ env.REGISTRY }}/${IMAGE_NAME}:${STEPS_ANCHOR_OUTPUTS_VERSION} already exists" | |
| else | |
| echo "exists=false" >> $GITHUB_OUTPUT | |
| echo "Image not found, will build" | |
| # Fork PRs cannot push new images | |
| if [[ "${STEPS_CHECK_FORK_OUTPUTS_IS_FORK}" == "true" ]]; then | |
| echo "::error::Fork PRs cannot build anchor-base image. Image does not exist. A maintainer must first build this image by running this workflow from main." | |
| exit 1 | |
| fi | |
| fi | |
| env: | |
| STEPS_ANCHOR_OUTPUTS_VERSION: ${{ steps.anchor.outputs.version }} | |
| STEPS_CHECK_FORK_OUTPUTS_IS_FORK: ${{ steps.check-fork.outputs.is_fork }} | |
| - name: Set up Docker Buildx | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 | |
| - name: Log in to Container Registry | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push anchor-base image | |
| if: steps.check.outputs.exists == 'false' | |
| uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 | |
| with: | |
| context: . | |
| file: Dockerfile.anchor-base | |
| build-args: | | |
| ANCHOR_VERSION=${{ steps.anchor.outputs.version }} | |
| push: true | |
| tags: | | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.anchor.outputs.version }} | |
| ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest | |
| cache-from: type=gha,scope=anchor-base | |
| cache-to: type=gha,mode=max,scope=anchor-base | |
| - name: Output image reference | |
| id: result | |
| run: | | |
| echo "image=${{ env.REGISTRY }}/${IMAGE_NAME}:${STEPS_ANCHOR_OUTPUTS_VERSION}" >> $GITHUB_OUTPUT | |
| env: | |
| STEPS_ANCHOR_OUTPUTS_VERSION: ${{ steps.anchor.outputs.version }} |