diff --git a/.github/workflows/publish-provider-family.yml b/.github/workflows/publish-provider-family.yml new file mode 100644 index 0000000..1887c7e --- /dev/null +++ b/.github/workflows/publish-provider-family.yml @@ -0,0 +1,174 @@ +name: Publish Provider Family + +on: + workflow_dispatch: + inputs: + repository: + description: 'Official provider family repository to build and publish, e.g., crossplane-contrib/provider-upjet-aws' + required: true + type: string + ref: + description: "The branch, tag or SHA to checkout" + default: 'main' + required: false + type: string + subpackages: + description: 'Subpackages to be built individually (e.g. monolith config ec2)' + default: 'monolith' + required: false + type: string + regorg: + description: 'Package registry and organization where the packages will be pushed or (e.g. xpkg.upbound.io/upbound)' + default: 'xpkg.upbound.io/upbound' + required: false + type: string + size: + description: "Number of packages to build and push with each matrix build job" + default: '30' + required: true + type: string + concurrency: + description: "Number of parallel package builds in each matrix job" + default: '1' + required: false + type: string + branch_name: + description: "Branch name to use while publishing the packages" + default: '' + required: false + type: string + version: + description: "Version string to use while publishing the packages" + default: '' + required: false + type: string + go-version: + description: 'Go version to use if building needs to be done' + default: '1.21' + required: false + type: string + cleanup-disk: + description: "If set to true, an initial step will be run to reclaim some extra disk space for the build/test jobs in this workflow" + required: false + type: boolean + default: false + +env: + # Common versions + DOCKER_BUILDX_VERSION: 'v0.8.2' + UP_VERSION: 'v0.24.2' + # Common users. We can't run a step 'if secrets.XXX != ""' but we can run a + # step 'if env.XXX' != ""', so we copy these to succinctly test whether + # credentials have been provided before trying to run steps that need them. + UPBOUND_MARKETPLACE_PUSH_ROBOT_USR: ${{ secrets.UPBOUND_MARKETPLACE_PUSH_ROBOT_USR }} + +jobs: + index: + runs-on: [e2-standard-8, linux] + outputs: + indices: ${{ steps.calc.outputs.indices }} + steps: + - id: calc + run: | + python3 -c "import math; print(f'indices={list(range(0, math.ceil(len(\"${{ inputs.subpackages }}\".split()) / int(\"${{ inputs.size }}\"))))}')" >> "$GITHUB_OUTPUT" + + publish-service-artifacts: + strategy: + matrix: + index: ${{ fromJSON(needs.index.outputs.indices) }} + + needs: index + runs-on: [e2-standard-8, linux] + steps: + - name: Cleanup Disk + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 + if: ${{ inputs.cleanup-disk }} + with: + android: true + dotnet: true + haskell: true + tool-cache: true + large-packages: false + swap-storage: false + + - name: Setup QEMU + uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2 + with: + platforms: all + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v2 + with: + version: ${{ env.DOCKER_BUILDX_VERSION }} + install: true + + - name: Login to Upbound + if: env.UPBOUND_MARKETPLACE_PUSH_ROBOT_USR != '' + env: + UP_TOKEN: ${{ secrets.UPBOUND_MARKETPLACE_PUSH_ROBOT_PSW }} + run: | + curl -fsSLo /tmp/up --create-dirs 'https://cli.upbound.io/stable/${{ env.UP_VERSION }}/bin/linux_amd64/up' && \ + chmod +x /tmp/up && \ + /tmp/up login + + - name: Checkout + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4 + with: + submodules: true + repository: ${{ inputs.repository }} + ref: ${{ inputs.ref }} + + - name: Fetch History + run: git fetch --prune --unshallow + + - name: Setup Go + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 # v3 + with: + go-version: ${{ inputs.go-version }} + + - name: Find the Go Build Cache + id: go_cache + run: | + echo "cache=$(make go.cachedir)" >> $GITHUB_OUTPUT && \ + echo "mod_cache=$(make go.mod.cachedir)" >> $GITHUB_OUTPUT + + - name: Cache the Go Build Cache + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3 + with: + path: ${{ steps.go_cache.outputs.cache }} + key: ${{ runner.os }}-build-publish-artifacts-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-build-publish-artifacts- + + - name: Cache Go Dependencies + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3 + with: + path: ${{ steps.go_cache.outputs.mod_cache }} + key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} + restore-keys: ${{ runner.os }}-pkg- + + - name: Vendor Dependencies + run: make vendor vendor.check + + - name: Calculate packages to build & push + id: packages + run: | + echo target=$(python3 -c "print(' '.join(\"${{ inputs.subpackages }}\".split()[int(\"${{ matrix.index }}\") * int(\"${{ inputs.size }}\"): (int(\"${{ matrix.index }}\")+1) * int(\"${{ inputs.size }}\")]))") >> "$GITHUB_OUTPUT" + + - name: Build Artifacts + id: build_artifacts + run: | + packages=($(echo ${{ steps.packages.outputs.target }} | tr ' ' '\n')) + num_packages=${#packages[@]} + if [ $num_packages -gt 10 ]; then + num_packages=10 + fi + make -j $num_packages SUBPACKAGES="${{ steps.packages.outputs.target }}" XPKG_REG_ORGS="${{ inputs.regorg }}" XPKG_REG_ORGS_NO_PROMOTE="${{ inputs.regorg }}" ${{ inputs.branch_name != '' && format('BRANCH_NAME={0}', inputs.branch_name) || '' }} ${{ inputs.version != '' && format('VERSION={0}', inputs.version) || '' }} build.all + echo "num_packages=$num_packages" >> $GITHUB_OUTPUT + env: + # We're using docker buildx, which doesn't actually load the images it + # builds by default. Specifying --load does so. + BUILD_ARGS: "--load" + + - name: Publish Artifacts + run: | + make -j ${{ steps.build_artifacts.outputs.num_packages }} SUBPACKAGES="${{ steps.packages.outputs.target }}" XPKG_REG_ORGS="${{ inputs.regorg }}" XPKG_REG_ORGS_NO_PROMOTE="${{ inputs.regorg }}" CONCURRENCY="${{ inputs.concurrency }}" ${{ inputs.branch_name != '' && format('BRANCH_NAME={0}', inputs.branch_name) || '' }} ${{ inputs.version != '' && format('VERSION={0}', inputs.version) || '' }} publish