diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b2cfb1..325c0b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,8 +3,11 @@ name: CI on: push: branches: - - main + - mima - release-* + - mima-release-* + tags: + - 'v*' pull_request: {} workflow_dispatch: inputs: @@ -18,22 +21,28 @@ env: GOLANGCI_VERSION: 'v2.12.2' DOCKER_BUILDX_VERSION: 'v0.23.0' + # The package to push, without a version tag. The default matches GitHub. For + # example xpkg.crossplane.io/crossplane/function-template-go. Note that + # xpkg.crossplane.io is just an alias for ghcr.io, so we upload to ghcr.io but + # this'll be pulled from xpkg.crossplane.io. + XPKG: ghcr.io/${{ github.repository}} + + # The package version to push. The default is 0.0.0-gitsha. + XPKG_VERSION: ${{ inputs.version }} + # These environment variables are important to the Crossplane CLI install.sh # script. They determine what version it installs. - XP_CHANNEL: master # TODO(negz): Pin to stable once v1.14 is released. + XP_CHANNEL: stable # TODO(negz): Pin to stable once v1.14 is released. XP_VERSION: current # TODO(negz): Pin to a version once v1.14 is released. # This CI job will automatically push new builds to xpkg.upbound.io if the # XPKG_ACCESS_ID and XPKG_TOKEN secrets are set in the GitHub respository (or # organization) settings. Create a token at https://accounts.upbound.io. - XPKG_ACCESS_ID: ${{ secrets.UP_ROBOT_ID }} + XPKG_ACCESS_ID: ${{ secrets.XPKG_ACCESS_ID }} # The package to push, without a version tag. The default matches GitHub. For # example xpkg.upbound.io/crossplane/function-template-go. - XPKG: xpkg.upbound.io/${{ github.repository}} - - # The package version to push. The default is 0.0.0-gitsha. - XPKG_VERSION: ${{ inputs.version }} + UPBOUND: xpkg.upbound.io/${{ github.repository}} jobs: lint: @@ -131,6 +140,9 @@ jobs: # XPKG_ACCESS_ID and XPKG_TOKEN secrets were provided. push: runs-on: ubuntu-24.04 + permissions: + contents: write + packages: write needs: - build steps: @@ -147,24 +159,81 @@ jobs: - name: Setup the Crossplane CLI run: "curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh" - - name: Login to Upbound + # Distribute to GHCR only for release branches and version tags: + # mima-release-*, release-*, and v* tags. + - name: Login to GitHub Container Registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 - if: env.XPKG_ACCESS_ID != '' + if: startsWith(github.ref, 'refs/heads/mima-release-') || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/') with: - registry: xpkg.upbound.io - username: ${{ secrets.UP_ROBOT_ID }} - password: ${{ secrets.UP_API_TOKEN }} - - # If a version wasn't explicitly passed as a workflow_dispatch input we - # default to version v0.0.0--, for example + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + # On a v* tag push (created by crossplane-gitops/release-fork.yml at the + # head of a mima-release-* branch) the image is versioned after the tag, + # e.g. v0.6.0 -> ghcr.io/mimacom/:v0.6.0. release-fork.yml then + # validates the signature of that exact image reference. + - name: Use Tag as Multi-Platform Package Version + if: env.XPKG_VERSION == '' && startsWith(github.ref, 'refs/tags/v') + run: echo "XPKG_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + + # Otherwise (branch build without an explicit input) default to + # v0.0.0--, for example # v0.0.0-20231101115142-1091066df799. This is a simple implementation of # Go's pseudo-versions: https://go.dev/ref/mod#pseudo-versions. - name: Set Default Multi-Platform Package Version if: env.XPKG_VERSION == '' run: echo "XPKG_VERSION=v0.0.0-$(date -d@$(git show -s --format=%ct) +%Y%m%d%H%M%S)-$(git rev-parse --short=12 HEAD)" >> $GITHUB_ENV + - name: Push Multi-Platform Package to GitHub Container Registry + if: startsWith(github.ref, 'refs/heads/mima-release-') || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/') + # XPKG repo name can't contain uppercase characters like UpboundCare, we need to lowercase if the GithubOrg contains them. + # See https://github.com/orgs/community/discussions/25768#discussioncomment-8057564 for XPKG@L lowercase explanation + run: "./crossplane --verbose xpkg push --package-files $(echo *.xpkg|tr ' ' ,) ${{ env.XPKG }}:${{ env.XPKG_VERSION }}" + + - name: Login to Upbound + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 + if: env.XPKG_ACCESS_ID != '' + with: + registry: xpkg.upbound.io + username: ${{ secrets.XPKG_ACCESS_ID }} + password: ${{ secrets.XPKG_TOKEN }} + - name: Push Multi-Platform Package to Upbound if: env.XPKG_ACCESS_ID != '' - # XPKG repo name can't contain uppercase characters - # See https://github.com/orgs/community/discussions/25768#discussioncomment-8057564 for XPKG@L lowercase explanation - run: "./crossplane --verbose xpkg push --package-files $(echo *.xpkg|tr ' ' ,) ${XPKG@L}:${{ env.XPKG_VERSION }}" + run: "./crossplane --verbose xpkg push --package-files $(echo *.xpkg|tr ' ' ,) ${{ env.UPBOUND }}:${{ env.XPKG_VERSION }}" + + - name: Install Cosign + if: startsWith(github.ref, 'refs/heads/mima-release-') || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/') + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3 + + - name: Sign OCI Package + if: startsWith(github.ref, 'refs/heads/mima-release-') || startsWith(github.ref, 'refs/heads/release-') || startsWith(github.ref, 'refs/tags/') + env: + COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_SIGNING_KEY }} + COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} + run: | + cosign sign \ + --key env://COSIGN_PRIVATE_KEY \ + --tlog-upload=false \ + --yes \ + ${{ env.XPKG }}:${{ env.XPKG_VERSION }} + + # On a tag build, publish the GitHub Release carrying the cosign public key + # so it can be verified (air-gapped, no Rekor). Create the release if it + # does not exist yet, otherwise just (re)attach the key. + - name: Publish GitHub Release with cosign.pub + if: startsWith(github.ref, 'refs/tags/') + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + if gh release view ${{ github.ref_name }} --repo ${{ github.repository }} >/dev/null 2>&1; then + gh release upload ${{ github.ref_name }} release/cosign.pub \ + --repo ${{ github.repository }} --clobber + else + gh release create ${{ github.ref_name }} release/cosign.pub \ + --repo ${{ github.repository }} \ + --title ${{ github.ref_name }} \ + --notes "mimacom signed release ${{ github.ref_name }}. Verify: cosign verify --key cosign.pub --insecure-ignore-tlog=true ${{ env.XPKG }}:${{ env.XPKG_VERSION }}" + fi diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..034e848 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,21 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 5.1.x | :white_check_mark: | +| 5.0.x | :x: | +| 4.0.x | :white_check_mark: | +| < 4.0 | :x: | + +## Reporting a Vulnerability + +Use this section to tell people how to report a vulnerability. + +Tell them where to go, how often they can expect to get an update on a +reported vulnerability, what to expect if the vulnerability is accepted or +declined, etc. diff --git a/release/cosign.pub b/release/cosign.pub new file mode 100644 index 0000000..5ee26bf --- /dev/null +++ b/release/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoknUlMrubsWwcu5nPbCu1qJEly96 +VofONQjtRUU8o9IkZGAT6ey3euTzu3NNuGDV3Km5TlQ9aQxyJ33XvWh+wA== +-----END PUBLIC KEY-----