diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b87291..5f9fcbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,21 +6,30 @@ on: - main - release-* pull_request: {} - workflow_dispatch: {} + workflow_dispatch: + inputs: + version: + description: Package version (e.g. v0.1.0) + required: false env: # Common versions GO_VERSION: '1.21.3' GOLANGCI_VERSION: 'v1.54.2' - DOCKER_BUILDX_VERSION: 'v0.10.0' + DOCKER_BUILDX_VERSION: 'v0.11.2' + XP_CHANNEL: master # TODO(negz): Pin to stable once v1.14 is released. + XP_VERSION: current # TODO(negz): Pin to a version once v1.14 is released. - # Common users. We can't run a step 'if secrets.AWS_USR != ""' but we can run - # a step 'if env.AWS_USR' != ""', so we copy these to succinctly test whether + # Common users. We can't run a step 'if secrets.USR != ""' but we can run + # a step 'if env.USR' != ""', so we copy these to succinctly test whether # credentials have been provided before trying to run steps that need them. - XPKG_PUSH_ROBOT_USR: ${{ secrets.XPKG_PUSH_ROBOT_USR }} + XPKG_ACCESS_ID: ${{ secrets.XPKG_ACCESS_ID }} -jobs: + # The package to push, without a version tag. + XPKG: xpkg.upbound.io/${{ github.repository}} + XPKG_VERSION: ${{ inputs.version }} +jobs: lint: runs-on: ubuntu-22.04 steps: @@ -31,39 +40,18 @@ jobs: uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} + cache: false # The golangci-lint action does its own caching. - name: Lint uses: golangci/golangci-lint-action@v3 with: version: ${{ env.GOLANGCI_VERSION }} - codeql: - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: go - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - - unit-tests: + unit-test: runs-on: ubuntu-22.04 - steps: - name: Checkout uses: actions/checkout@v4 - with: - submodules: true - name: Setup Go uses: actions/setup-go@v4 @@ -73,17 +61,14 @@ jobs: - name: Run Unit Tests run: go test -v -cover ./... - push-package: + build: runs-on: ubuntu-22.04 - strategy: fail-fast: true matrix: - platform: - - linux/amd64 - - linux/arm64 - - linux/ppc641e - + arch: + - amd64 + - arm64 steps: - name: Setup QEMU uses: docker/setup-qemu-action@v3 @@ -99,24 +84,64 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Setup Go - uses: actions/setup-go@v4 - with: - go-version: ${{ env.GO_VERSION }} - - - name: Build Function Runtime + - name: Build Runtime + id: image uses: docker/build-push-action@v5 with: context: . - platforms: ${{ matrix.platform }} + platforms: linux/${{ matrix.arch }} + cache-from: type=gha + cache-to: type=gha,mode=max + target: image + build-args: + GO_VERSION=${{ env.GO_VERSION }} + outputs: type=docker,dest=runtime.tar + + - name: Setup the Crossplane CLI + run: "curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh" + - name: Build Package + run: ./crossplane xpkg build --package-file=${{ matrix.arch }}.xpkg --package-root=package/ --embed-runtime-image-tarball=runtime.tar - # TODO(negz): Build Function package using Crossplane CLI. + - name: Upload Single-Platform Package + uses: actions/upload-artifact@v3 + with: + name: packages + path: "*.xpkg" + if-no-files-found: error + retention-days: 1 + + push: + runs-on: ubuntu-22.04 + needs: + - build + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download Single-Platform Packages + uses: actions/download-artifact@v3 + with: + name: packages + path: . + + - name: Setup the Crossplane CLI + run: "curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh" - name: Login to Upbound uses: docker/login-action@v3 - if: env.XPKG_PUSH_ROBOT_USR != '' + if: env.XPKG_ACCESS_ID != '' with: registry: xpkg.upbound.io - username: ${{ secrets.XPKG_PUSH_ROBOT_USR }} - password: ${{ secrets.XPKG_PUSH_ROBOT_PSW }} + username: ${{ secrets.XPKG_ACCESS_ID }} + password: ${{ secrets.XPKG_TOKEN }} + + # If a version wasn't explicitly passed as a workflow_dispatch input we + # default to version v0.0.0-shortsha, for example v0.0.0-8ed5691. + - name: Set Default Multi-Platform Package Version + if: env.XPKG_VERSION == '' + run: echo "XPKG_VERSION=v0.0.0-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + + - name: Push Multi-Platform Package to Upbound + if: env.XPKG_ACCESS_ID != '' + run: "./crossplane --verbose xpkg push --package-files $(echo *.xpkg|tr ' ' ,) ${{ env.XPKG }}:${{ env.XPKG_VERSION }}" diff --git a/Dockerfile b/Dockerfile index d1db681..6ae4d7d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,30 @@ -FROM golang:1.20 as build-stage +# syntax=docker/dockerfile:1 -WORKDIR /fn +# We use the latest Go 1.x version unless asked to use something else. +ARG GO_VERSION=1 +ARG TARGETOS +ARG TARGETARCH -COPY go.mod go.sum ./ -RUN go mod download +# Setup the base environment. +FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION} AS base -COPY input/ ./input -COPY *.go ./ +WORKDIR /fn +ENV CGO_ENABLED=0 -RUN CGO_ENABLED=0 go build -o /function . +COPY go.mod go.sum ./ +RUN --mount=type=cache,target=/go/pkg/mod go mod download -FROM gcr.io/distroless/base-debian11 AS build-release-stage +# Build the Function. +FROM base AS build +RUN --mount=target=. \ + --mount=type=cache,target=/go/pkg/mod \ + --mount=type=cache,target=/root/.cache/go-build \ + GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /function . +# Produce the Function image. +FROM gcr.io/distroless/base-debian11 AS image WORKDIR / - -COPY --from=build-stage /function /function - +COPY --from=build /function /function EXPOSE 9443 - USER nonroot:nonroot - -ENTRYPOINT ["/function"] \ No newline at end of file +ENTRYPOINT ["/function"] diff --git a/fn.go b/fn.go index 0fc0860..7161787 100644 --- a/fn.go +++ b/fn.go @@ -3,11 +3,12 @@ package main import ( "context" + "google.golang.org/protobuf/types/known/structpb" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/crossplane/crossplane-runtime/pkg/errors" "github.com/crossplane/crossplane-runtime/pkg/logging" "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" - "google.golang.org/protobuf/types/known/structpb" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" fncontext "github.com/crossplane/function-sdk-go/context" fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1" diff --git a/patches_test.go b/patches_test.go index 9042774..9c702af 100644 --- a/patches_test.go +++ b/patches_test.go @@ -14,6 +14,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/resource" "github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/composed" "github.com/crossplane/crossplane-runtime/pkg/test" + "github.com/crossplane/function-sdk-go/resource/composite" "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1"