diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7ad606d..b3db09c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,7 @@ jobs: -f docker/pulumi/Dockerfile \ --platform linux/amd64 \ -t ${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} \ + --target base \ --build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \ --load \ docker/pulumi @@ -98,6 +99,58 @@ jobs: --entrypoint /bin/bash \ ${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} \ -c "/src/pulumi-test-containers -test.parallel=1 -test.timeout=1h -test.v -test.run TestPulumiDockerImage" + + provider-build-environment: + name: Provider Build Environment image + strategy: + matrix: + go-version: [1.18.x] + runs-on: ubuntu-latest + steps: + # If no version of Pulumi is supplied by the incoming event (e.g. in the + # case of a PR or merge to main), we use the latest production version: + - name: Set version to latest + if: ${{ !env.PULUMI_VERSION }} + run: | + echo "PULUMI_VERSION=$(curl https://www.pulumi.com/latest-version)" >> $GITHUB_ENV + - uses: actions/checkout@master + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Setup docker buildx + uses: docker/setup-buildx-action@v1 + with: + install: true + - name: Build + # This image is only built for AMD64 for the same reasons as + # the "kitchen sink" image, listed above. + run: | + docker build \ + -f docker/pulumi/Dockerfile \ + --platform linux/amd64 \ + -t ${{ env.DOCKER_USERNAME }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} \ + --target build-environment \ + --build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \ + --load \ + docker/pulumi + - name: Install go + uses: actions/setup-go@v2 + with: + go-version: "1.18.3" + - name: Compile tests + working-directory: tests + run: | + GOOS=linux GOARCH=amd64 go test -c -o /tmp/pulumi-test-containers ./... + - name: Run tests + run: | + docker run \ + -e RUN_CONTAINER_TESTS=true \ + -e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \ + -e PULUMI_ORG=${PULUMI_ORG} \ + --volume /tmp:/src \ + --entrypoint /bin/bash \ + ${{ env.DOCKER_USERNAME }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} \ + -c "/src/pulumi-test-containers -test.parallel=1 -test.timeout=1h -test.v -test.run TestPulumiDockerImage" + base: name: Base image runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66f2b579..a2773857 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,6 +63,7 @@ jobs: --platform linux/amd64 \ -t ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }} \ -t ${{ env.DOCKER_ORG }}/pulumi:latest \ + --target base \ --build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \ --load \ docker/pulumi @@ -90,6 +91,62 @@ jobs: if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }} run: docker push ${{ env.DOCKER_ORG }}/pulumi:latest + provider-build-environment: + name: Provider Build Environment image + strategy: + matrix: + go-version: [1.18.x] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ env.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Setup docker buildx + uses: docker/setup-buildx-action@v1 + with: + install: true + - name: Build + # This image is only built for AMD64 for the same reasons as + # the "kitchen sink" image, listed above. + run: | + docker build \ + -f docker/pulumi/Dockerfile \ + --platform linux/amd64 \ + -t ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} \ + -t ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:latest \ + --target build-environment \ + --build-arg PULUMI_VERSION=${{ env.PULUMI_VERSION }} \ + --load \ + docker/pulumi + - name: Install go + uses: actions/setup-go@v2 + with: + go-version: "1.18.3" + - name: Compile tests + working-directory: tests + run: | + GOOS=linux GOARCH=amd64 go test -c -o /tmp/pulumi-test-containers ./... + - name: Run tests + run: | + docker run \ + -e RUN_CONTAINER_TESTS=true \ + -e PULUMI_ACCESS_TOKEN=${PULUMI_ACCESS_TOKEN} \ + -e PULUMI_ORG=${PULUMI_ORG} \ + --volume /tmp:/src \ + --entrypoint /bin/bash \ + ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} \ + -c "/src/pulumi-test-containers -test.parallel=1 -test.timeout=1h -test.v -test.run TestPulumiDockerImage" + - name: Push ${{ env.PULUMI_VERSION }} + run: docker push ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:${{ env.PULUMI_VERSION }} + - name: Push latest + if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }} + run: docker push ${{ env.DOCKER_ORG }}/pulumi-provider-build-environment:latest + base: name: Base image runs-on: ubuntu-latest diff --git a/.github/workflows/snyk-scan.yml b/.github/workflows/snyk-scan.yml index 62f0c077..9f71c6e3 100644 --- a/.github/workflows/snyk-scan.yml +++ b/.github/workflows/snyk-scan.yml @@ -14,8 +14,11 @@ env: jobs: kitchen-sink: - name: All SDKs image + name: All SDKs images runs-on: ubuntu-latest + strategy: + matrix: + image: ["pulumi", "pulumi-provider-build-environment"] steps: - uses: actions/checkout@master - name: Set version @@ -27,8 +30,9 @@ jobs: env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: - image: ${{ env.DOCKER_ORG }}/pulumi:${{ env.PULUMI_VERSION }} + image: ${{ env.DOCKER_ORG }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} args: --severity-threshold=high --file=docker/pulumi/Dockerfile + base: name: Base image runs-on: ubuntu-latest diff --git a/.github/workflows/sync-ecr.yml b/.github/workflows/sync-ecr.yml index d5a45da4..0907c44c 100644 --- a/.github/workflows/sync-ecr.yml +++ b/.github/workflows/sync-ecr.yml @@ -23,8 +23,11 @@ env: jobs: sync-to-ecr: - name: Kitchen Sink image + name: Kitchen Sink images runs-on: ubuntu-latest + strategy: + matrix: + image: ["pulumi", "pulumi-provider-build-environment"] steps: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 @@ -44,15 +47,15 @@ jobs: docker login -u AWS --password-stdin https://public.ecr.aws - name: Tag ${{ env.PULUMI_VERSION }} and push to AWS Public ECR run: | - docker pull docker.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} - docker tag docker.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} public.ecr.aws/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} - docker push public.ecr.aws/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} + docker pull docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} + docker tag docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} public.ecr.aws/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} + docker push public.ecr.aws/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} - name: Tag latest and push to AWS Public ECR if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }} run: | - docker pull docker.io/${{ env.DOCKER_USERNAME }}/pulumi:latest - docker tag docker.io/${{ env.DOCKER_USERNAME }}/pulumi:latest public.ecr.aws/${{ env.DOCKER_USERNAME }}/pulumi:latest - docker push public.ecr.aws/${{ env.DOCKER_USERNAME }}/pulumi:latest + docker pull docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest + docker tag docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest public.ecr.aws/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest + docker push public.ecr.aws/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest debian-images: name: Debian SDK and base images diff --git a/.github/workflows/sync-ghcr.yml b/.github/workflows/sync-ghcr.yml index fdc2cac0..9d5adaa1 100644 --- a/.github/workflows/sync-ghcr.yml +++ b/.github/workflows/sync-ghcr.yml @@ -23,8 +23,11 @@ env: jobs: sync-to-ecr: - name: Kitchen Sink image + name: Kitchen Sink images runs-on: ubuntu-latest + strategy: + matrix: + image: ["pulumi", "pulumi-provider-build-environment"] steps: - name: Login to GitHub Container Registry uses: docker/login-action@v1 @@ -34,15 +37,15 @@ jobs: password: ${{ secrets.PULUMI_BOT_TOKEN }} - name: Tag ${{ env.PULUMI_VERSION }} and push to GHCR run: | - docker pull docker.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} - docker tag docker.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} ghcr.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} - docker push ghcr.io/${{ env.DOCKER_USERNAME }}/pulumi:${{ env.PULUMI_VERSION }} + docker pull docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} + docker tag docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} ghcr.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} + docker push ghcr.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:${{ env.PULUMI_VERSION }} - name: Tag latest and push to GHCR if: ${{ github.event.inputs.tag_latest || github.event_name == 'repository_dispatch' }} run: | - docker pull docker.io/${{ env.DOCKER_USERNAME }}/pulumi:latest - docker tag docker.io/${{ env.DOCKER_USERNAME }}/pulumi:latest ghcr.io/${{ env.DOCKER_USERNAME }}/pulumi:latest - docker push ghcr.io/${{ env.DOCKER_USERNAME }}/pulumi:latest + docker pull docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest + docker tag docker.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest ghcr.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest + docker push ghcr.io/${{ env.DOCKER_USERNAME }}/${{ matrix.image }}:latest debian-images: name: Debian SDK and base images diff --git a/docker/pulumi/Dockerfile b/docker/pulumi/Dockerfile index ab0813bb..d2c99888 100644 --- a/docker/pulumi/Dockerfile +++ b/docker/pulumi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-slim +FROM python:3.9-slim AS base LABEL "repository"="https://github.com/pulumi/pulumi" LABEL "homepage"="https://pulumi.com" @@ -101,3 +101,68 @@ RUN curl -fsSL https://get.pulumi.com/ | bash -s -- --version $PULUMI_VERSION && # I think it's safe to say if we're using this mega image, we want pulumi ENTRYPOINT ["pulumi"] + +# Pulumi Bridged Terraform Provider Build Environment +# +# Bundles together everything needed to build a Terraform-based +# provider. +# +# See https://github.com/pulumi/pulumi-docker-containers/issues/111 +# for more background. +######################################################################## + +FROM base AS build-environment + +# https://github.com/pulumi/pulumictl/releases +ENV PULUMICTL_VERSION 0.0.32 +# https://github.com/golangci/golangci-lint/releases +ENV GOLANGCI_LINT_VERSION 1.49.0 +# https://github.com/goreleaser/goreleaser/releases +ENV GORELEASER_VERSION 1.11.4 + +SHELL ["/bin/bash", "-o", "errexit", "-o", "nounset", "-o", "pipefail", "-c"] + +RUN curl \ + --proto "=https" \ + --tlsv1.2 \ + --location \ + --fail \ + --verbose \ + --output "pulumictl.tar.gz" \ + "https://github.com/pulumi/pulumictl/releases/download/v${PULUMICTL_VERSION}/pulumictl-v${PULUMICTL_VERSION}-linux-amd64.tar.gz" && \ + mkdir pulumictl_extraction && \ + tar --extract --gunzip --verbose --directory pulumictl_extraction --file pulumictl.tar.gz && \ + mv pulumictl_extraction/pulumictl /usr/local/bin/pulumictl && \ + chmod a+x /usr/local/bin/pulumictl && \ + rm -Rf pulumictl_extraction && \ + rm pulumictl.tar.gz && \ + # Install golangci-lint + curl --proto "=https" \ + --tlsv1.2 \ + --silent \ + --show-error \ + --fail \ + --location \ + https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh \ + | sh -s -- -b "$(go env GOPATH)/bin" "v${GOLANGCI_LINT_VERSION}" && \ + # Install goreleaser + curl \ + --proto "=https" \ + --tlsv1.2 \ + --location \ + --fail \ + --verbose \ + --output "goreleaser.tar.gz" \ + "https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}/goreleaser_Linux_x86_64.tar.gz" && \ + mkdir goreleaser_extraction && \ + tar --extract --gunzip --verbose --directory goreleaser_extraction --file goreleaser.tar.gz && \ + mv goreleaser_extraction/goreleaser /usr/local/bin/goreleaser && \ + chmod a+x /usr/local/bin/goreleaser && \ + rm -Rf goreleaser_extraction && \ + rm goreleaser.tar.gz + +# The entrypoint of the base image is `pulumi`; we don't +# want that for this usecase, since we'll be performing different +# build-related tasks. +ENTRYPOINT [] +CMD ["bash"]