diff --git a/.github/actions/build-custom-image-with-apko/action.yml b/.github/actions/build-custom-image-with-apko/action.yml deleted file mode 100644 index 799b376403..0000000000 --- a/.github/actions/build-custom-image-with-apko/action.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: 'Build and push a custom image with apko' -description: 'Composite action for building and pushing a custom image with apko' -inputs: - context: - description: 'Path to the context directory' - required: true - - component: - description: 'Name of the component (e.g. kotsadm, kurl-proxy, etc...)' - required: true - - git-tag: - description: 'Git tag' - required: true - - image-name: - description: 'Full destination image name' - required: true - - registry-username: - description: 'Username to login to registry' - default: '' - required: false - - registry-password: - description: 'Password to login to registry' - default: '' - required: false - -runs: - using: "composite" - steps: - - uses: actions/download-artifact@v8 - with: - pattern: ${{ inputs.component }}-melange-packages-* - path: ./packages/ - merge-multiple: true - - - uses: actions/download-artifact@v8 - with: - pattern: ${{ inputs.component }}-melange-rsa-pub-* - merge-multiple: true - - - name: template apko config - shell: bash - run: | - export GIT_TAG=${{ inputs.git-tag }} - envsubst '${GIT_TAG}' < ${{ inputs.context }}/apko.yaml.tmpl > ${{ inputs.context }}/apko.yaml - - - uses: chainguard-images/actions/apko-publish@v1.0.37 - with: - config: ${{ inputs.context }}/apko.yaml - archs: amd64,arm64 - tag: ${{ inputs.image-name }} - vcs-url: true - generic-user: ${{ inputs.registry-username }} - generic-pass: ${{ inputs.registry-password }} diff --git a/.github/actions/build-custom-melange-package/action.yml b/.github/actions/build-custom-melange-package/action.yml deleted file mode 100644 index 8c6af7cb00..0000000000 --- a/.github/actions/build-custom-melange-package/action.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: 'Build a custom melange package' -description: 'Composite action for building a custom melange package' -inputs: - context: - description: 'Path to the context directory' - required: true - - component: - description: 'Name of the component (e.g. kotsadm, kurl-proxy, etc...)' - required: true - - git-tag: - description: 'Git tag' - required: true - - arch: - description: 'Architecture to build for' - required: true - -runs: - using: "composite" - steps: - - name: configure packages for arm64 - if: inputs.arch == 'arm64' - shell: bash - run: | - sudo apt-get update -y - sudo apt-get install -y curl jq gettext-base pkg-config apparmor - # ARC container runners don't run systemd as PID 1, so 'systemctl reload apparmor' - # (called by setup-melange) fails. Shim it to use apparmor_parser directly. - sudo tee /usr/local/bin/systemctl > /dev/null << 'SHIM' - #!/bin/bash - if [[ "$1" == "reload" && "$2" == "apparmor" ]]; then - apparmor_parser -r /etc/apparmor.d/ 2>/dev/null || true - exit 0 - fi - exec /usr/bin/systemctl "$@" - SHIM - sudo chmod +x /usr/local/bin/systemctl - - # build the melange package - - - name: template melange config - shell: bash - run: | - export GIT_TAG=${{ inputs.git-tag }} - envsubst '${GIT_TAG}' < ${{ inputs.context }}/melange.yaml.tmpl > ${{ inputs.context }}/melange.yaml - - - uses: chainguard-dev/actions/melange-build@v1.6.30 - with: - config: ${{ inputs.context }}/melange.yaml - archs: ${{ inputs.arch }} - git-commit: ${{ github.sha }} - git-repo-url: ${{ github.server_url }}/${{ github.repository }} - sign-with-temporary-key: true - signing-key-path: ./melange-${{ inputs.arch }}.rsa - - # upload artifacts generated by the melange build so they can later be used by apko - - - uses: actions/upload-artifact@v7 - with: - name: ${{ inputs.component }}-melange-packages-${{ inputs.arch }} - path: ./packages - - - uses: actions/upload-artifact@v7 - with: - name: ${{ inputs.component }}-melange-rsa-pub-${{ inputs.arch }} - path: ./melange-${{ inputs.arch }}.rsa.pub diff --git a/.github/actions/build-securebuild-image-locally/action.yml b/.github/actions/build-securebuild-image-locally/action.yml new file mode 100644 index 0000000000..f01827225c --- /dev/null +++ b/.github/actions/build-securebuild-image-locally/action.yml @@ -0,0 +1,43 @@ +name: Build a SecureBuild image locally +description: Publish an image locally from a SecureBuild APKO spec and local Melange packages + +inputs: + config: + description: Path to the SecureBuild APKO config + required: true + image-name: + description: Full destination image name + required: true + registry-username: + description: Username used to log in to the registry + default: '' + required: false + registry-password: + description: Password used to log in to the registry + default: '' + required: false + +runs: + using: composite + steps: + - uses: actions/download-artifact@v8 + with: + pattern: securebuild-melange-packages-* + path: ./packages/ + merge-multiple: true + + - uses: actions/download-artifact@v8 + with: + pattern: securebuild-melange-rsa-pub-* + merge-multiple: true + + - uses: chainguard-images/actions/apko-publish@v1.0.37 + with: + config: ${{ inputs.config }} + archs: amd64,arm64 + tag: ${{ inputs.image-name }} + repository-append: ./packages + keyring-append: ./melange-amd64.rsa.pub,./melange-arm64.rsa.pub + vcs-url: true + generic-user: ${{ inputs.registry-username }} + generic-pass: ${{ inputs.registry-password }} diff --git a/.github/actions/build-securebuild-package-locally/action.yml b/.github/actions/build-securebuild-package-locally/action.yml new file mode 100644 index 0000000000..5bb6998449 --- /dev/null +++ b/.github/actions/build-securebuild-package-locally/action.yml @@ -0,0 +1,76 @@ +name: Build the SecureBuild package locally +description: Build the SecureBuild Melange spec locally for prerelease versions + +inputs: + git-tag: + description: Version tag to embed in the binaries + required: true + arch: + description: Architecture to build for + required: true + source-ref: + description: Exact source commit used for package provenance; defaults to the workflow commit + required: false + default: '' + +runs: + using: composite + steps: + - name: Configure packages for arm64 + if: inputs.arch == 'arm64' + shell: bash + run: | + sudo apt-get update -y + sudo apt-get install -y curl jq gettext-base pkg-config apparmor + # ARC container runners don't run systemd as PID 1, so 'systemctl reload apparmor' + # (called by setup-melange) fails. Shim it to use apparmor_parser directly. + sudo tee /usr/local/bin/systemctl > /dev/null << 'SHIM' + #!/bin/bash + if [[ "$1" == "reload" && "$2" == "apparmor" ]]; then + apparmor_parser -r /etc/apparmor.d/ 2>/dev/null || true + exit 0 + fi + exec /usr/bin/systemctl "$@" + SHIM + sudo chmod +x /usr/local/bin/systemctl + + - uses: chainguard-dev/actions/setup-melange@v1.6.30 + + - name: Build packages + shell: bash + env: + ARCH: ${{ inputs.arch }} + GIT_TAG: ${{ inputs.git-tag }} + SOURCE_REF: ${{ inputs.source-ref || github.sha }} + run: | + env_file="$RUNNER_TEMP/melange.env" + signing_key="$RUNNER_TEMP/melange-${ARCH}.rsa" + + # SecureBuild replaces the package version when it runs the spec. Melange cannot + # use our prerelease version as an APK version, so retain the spec's valid placeholder. + # The local git-checkout pipeline override keeps the source already populated from + # actions/checkout instead of cloning the release tag referenced by the unchanged spec. + printf 'export GIT_TAG=%q\nexport VERSION=%q\n' "$GIT_TAG" "$GIT_TAG" > "$env_file" + + sudo melange keygen "$signing_key" + sudo melange build securebuild/package/melange.yaml \ + --arch "$ARCH" \ + --env-file "$env_file" \ + --git-commit "$SOURCE_REF" \ + --git-repo-url "${{ github.server_url }}/${{ github.repository }}" \ + --out-dir "$GITHUB_WORKSPACE/packages" \ + --pipeline-dir "${{ github.action_path }}/pipelines" \ + --signing-key "$signing_key" \ + --source-dir "$GITHUB_WORKSPACE" + sudo cp "$signing_key.pub" "$GITHUB_WORKSPACE/melange-${ARCH}.rsa.pub" + sudo chown -R "$(id -u):$(id -g)" "$GITHUB_WORKSPACE/packages" "$GITHUB_WORKSPACE/melange-${ARCH}.rsa.pub" + + - uses: actions/upload-artifact@v7 + with: + name: securebuild-melange-packages-${{ inputs.arch }} + path: ./packages + + - uses: actions/upload-artifact@v7 + with: + name: securebuild-melange-rsa-pub-${{ inputs.arch }} + path: ./melange-${{ inputs.arch }}.rsa.pub diff --git a/.github/actions/build-securebuild-package-locally/pipelines/git-checkout.yaml b/.github/actions/build-securebuild-package-locally/pipelines/git-checkout.yaml new file mode 100644 index 0000000000..2ab4bbbdbb --- /dev/null +++ b/.github/actions/build-securebuild-package-locally/pipelines/git-checkout.yaml @@ -0,0 +1,12 @@ +name: Use source from the local workspace + +inputs: + repository: + description: Unused; the repository has already been checked out by the workflow + required: true + tag: + description: Unused; the workflow checkout determines the source revision + +pipeline: + - runs: | + echo "Using source already checked out by the workflow" diff --git a/.github/workflows/alpha.yaml b/.github/workflows/alpha.yaml index 556eb6c046..70c3c891da 100644 --- a/.github/workflows/alpha.yaml +++ b/.github/workflows/alpha.yaml @@ -19,7 +19,7 @@ jobs: uses: ./.github/actions/version-tag - build-migrations-melange-packages: + build-melange-packages: needs: [generate-tag] strategy: fail-fast: true @@ -31,91 +31,43 @@ jobs: runs-on: ${{ matrix.runner.name }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package + - uses: ./.github/actions/build-securebuild-package-locally with: - context: migrations/deploy - component: kotsadm-migrations git-tag: ${{ needs.generate-tag.outputs.tag }} arch: ${{ matrix.runner.arch }} build-migrations: runs-on: ubuntu-latest - needs: [generate-tag, build-migrations-melange-packages] + needs: [generate-tag, build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: migrations/deploy - component: kotsadm-migrations - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm-migrations.yaml image-name: index.docker.io/kotsadm/kotsadm-migrations:alpha registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} - - build-kotsadm-melange-packages: - needs: [generate-tag] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-latest, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: deploy - component: kotsadm - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kotsadm: runs-on: ubuntu-latest - needs: [generate-tag, build-kotsadm-melange-packages] + needs: [generate-tag, build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: deploy - component: kotsadm - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm.yaml image-name: index.docker.io/kotsadm/kotsadm:alpha registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} - - build-kurl-proxy-melange-packages: - needs: [generate-tag] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-latest, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kurl-proxy: runs-on: ubuntu-latest - needs: [generate-tag, build-kurl-proxy-melange-packages] + needs: [generate-tag, build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kurl-proxy.yaml image-name: index.docker.io/kotsadm/kurl-proxy:alpha registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} @@ -330,4 +282,3 @@ jobs: uses: github/codeql-action/upload-sarif@v4 with: sarif_file: kotsadm-migration-scan-output.sarif - diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 5d6826d93c..1259150d2e 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -254,7 +254,7 @@ jobs: path: ./bin/kots - build-kotsadm-melange-packages: + build-melange-packages: needs: [ can-run-ci, generate-tag ] strategy: fail-fast: false @@ -269,26 +269,23 @@ jobs: with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-melange-package + - uses: ./.github/actions/build-securebuild-package-locally with: - context: deploy - component: kotsadm git-tag: ${{ needs.generate-tag.outputs.tag }} arch: ${{ matrix.runner.arch }} + source-ref: ${{ github.event.pull_request.head.sha }} build-kotsadm: runs-on: ubuntu-24.04 - needs: [ can-run-ci, generate-tag, build-kotsadm-melange-packages ] + needs: [ can-run-ci, generate-tag, build-melange-packages ] steps: - uses: actions/checkout@v7 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: deploy - component: kotsadm - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm.yaml image-name: ttl.sh/automated-${{ github.run_id }}/kotsadm:24h @@ -352,79 +349,31 @@ jobs: path: e2e/bin/ - build-kurl-proxy-melange-packages: - needs: [ can-run-ci, generate-tag ] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-24.04, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - with: - ref: ${{github.event.pull_request.head.ref}} - repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-melange-package - with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kurl-proxy: runs-on: ubuntu-24.04 - needs: [ can-run-ci, generate-tag, build-kurl-proxy-melange-packages ] + needs: [ can-run-ci, generate-tag, build-melange-packages ] steps: - uses: actions/checkout@v7 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kurl-proxy.yaml image-name: ttl.sh/automated-${{ github.run_id }}/kurl-proxy:24h - build-migrations-melange-packages: - needs: [ can-run-ci, generate-tag ] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-24.04, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - with: - ref: ${{github.event.pull_request.head.ref}} - repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-melange-package - with: - context: migrations/deploy - component: kotsadm-migrations - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-migrations: runs-on: ubuntu-24.04 - needs: [ can-run-ci, generate-tag, build-migrations-melange-packages ] + needs: [ can-run-ci, generate-tag, build-melange-packages ] steps: - uses: actions/checkout@v7 with: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: migrations/deploy - component: kotsadm-migrations - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm-migrations.yaml image-name: ttl.sh/automated-${{ github.run_id }}/kotsadm-migrations:24h push-minio: diff --git a/.github/workflows/publish-securebuild.yml b/.github/workflows/publish-securebuild.yml index b66f48f292..97d36786a6 100644 --- a/.github/workflows/publish-securebuild.yml +++ b/.github/workflows/publish-securebuild.yml @@ -1,9 +1,15 @@ name: publish-securebuild on: - push: - tags: - - "v*.*.*" + workflow_call: + inputs: + version: + description: 'Stable version tag to build (e.g. v1.2.3)' + required: true + type: string + secrets: + SECUREBUILD_API_TOKEN: + required: true workflow_dispatch: inputs: version: @@ -12,20 +18,28 @@ on: type: string jobs: + validate-version: + runs-on: ubuntu-22.04 + steps: + - name: Require a stable release version + env: + VERSION: ${{ inputs.version }} + run: | + if ! [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "SecureBuild only supports stable release versions (for example, v1.2.3): $VERSION" + exit 1 + fi + build-package: + needs: validate-version runs-on: ubuntu-22.04 - continue-on-error: true outputs: version: ${{ steps.version.outputs.version }} steps: - name: Set version id: version run: | - if [ -n "${{ inputs.version }}" ]; then - echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT" - else - echo "version=${{ github.ref_name }}" >> "$GITHUB_OUTPUT" - fi + echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT" - name: Install securebuild CLI run: | @@ -43,7 +57,6 @@ jobs: build-image: needs: build-package runs-on: ubuntu-22.04 - continue-on-error: true if: ${{ !cancelled() && needs.build-package.result == 'success' }} strategy: matrix: diff --git a/.github/workflows/release-for-ec.yaml b/.github/workflows/release-for-ec.yaml index 15fe3e99ca..2816d10336 100644 --- a/.github/workflows/release-for-ec.yaml +++ b/.github/workflows/release-for-ec.yaml @@ -27,7 +27,7 @@ jobs: fi echo "Tag format is valid: ${{ inputs.tag }}" - build-migrations-melange-packages: + build-melange-packages: needs: [validate-tag] strategy: fail-fast: true @@ -40,91 +40,43 @@ jobs: runs-on: ${{ matrix.runner.name }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package + - uses: ./.github/actions/build-securebuild-package-locally with: - context: migrations/deploy - component: kotsadm-migrations git-tag: ${{ inputs.tag }} arch: ${{ matrix.runner.arch }} build-migrations: runs-on: ubuntu-latest - needs: [build-migrations-melange-packages] + needs: [build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: migrations/deploy - component: kotsadm-migrations - git-tag: ${{ inputs.tag }} + config: securebuild/image/apko-kotsadm-migrations.yaml image-name: index.docker.io/kotsadm/kotsadm-migrations:${{ inputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} - build-kurl-proxy-melange-packages: - needs: [validate-tag] - strategy: - fail-fast: true - matrix: - runner: - [ - { name: ubuntu-latest, arch: amd64 }, - { name: arm64-runner-set, arch: arm64 }, - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ inputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kurl-proxy: runs-on: ubuntu-latest - needs: [build-kurl-proxy-melange-packages] + needs: [build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ inputs.tag }} + config: securebuild/image/apko-kurl-proxy.yaml image-name: index.docker.io/kotsadm/kurl-proxy:${{ inputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} - build-kotsadm-melange-packages: - needs: [validate-tag] - strategy: - fail-fast: true - matrix: - runner: - [ - { name: ubuntu-latest, arch: amd64 }, - { name: arm64-runner-set, arch: arm64 }, - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: deploy - component: kotsadm - git-tag: ${{ inputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kotsadm: runs-on: ubuntu-latest - needs: [build-kotsadm-melange-packages] + needs: [build-melange-packages] steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - uses: ./.github/actions/build-securebuild-image-locally with: - context: deploy - component: kotsadm - git-tag: ${{ inputs.tag }} + config: securebuild/image/apko-kotsadm.yaml image-name: index.docker.io/kotsadm/kotsadm:${{ inputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9d7a2ae41f..652bd094c9 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -29,8 +29,9 @@ jobs: git tag "$GIT_TAG" git push origin "$GIT_TAG" - build-migrations-melange-packages: + build-melange-packages: needs: [generate-tag] + if: contains(needs.generate-tag.outputs.tag, '-') strategy: fail-fast: true matrix: @@ -41,23 +42,29 @@ jobs: runs-on: ${{ matrix.runner.name }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package + - uses: ./.github/actions/build-securebuild-package-locally with: - context: migrations/deploy - component: kotsadm-migrations git-tag: ${{ needs.generate-tag.outputs.tag }} arch: ${{ matrix.runner.arch }} + build-securebuild: + needs: [generate-tag] + if: github.ref_type == 'tag' && !contains(needs.generate-tag.outputs.tag, '-') + uses: ./.github/workflows/publish-securebuild.yml + with: + version: ${{ needs.generate-tag.outputs.tag }} + secrets: inherit + build-migrations: runs-on: ubuntu-latest - needs: [generate-tag, build-migrations-melange-packages] + needs: [generate-tag, build-melange-packages, build-securebuild] + if: ${{ !cancelled() && needs.generate-tag.result == 'success' && (needs.build-melange-packages.result == 'success' || needs.build-securebuild.result == 'success') }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - if: contains(needs.generate-tag.outputs.tag, '-') + uses: ./.github/actions/build-securebuild-image-locally with: - context: migrations/deploy - component: kotsadm-migrations - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm-migrations.yaml image-name: index.docker.io/kotsadm/kotsadm-migrations:${{ needs.generate-tag.outputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} @@ -82,35 +89,16 @@ jobs: name: web path: ./web/dist - build-kurl-proxy-melange-packages: - needs: [generate-tag] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-latest, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kurl-proxy: runs-on: ubuntu-latest - needs: [generate-tag, build-kurl-proxy-melange-packages] + needs: [generate-tag, build-melange-packages, build-securebuild] + if: ${{ !cancelled() && needs.generate-tag.result == 'success' && (needs.build-melange-packages.result == 'success' || needs.build-securebuild.result == 'success') }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - if: contains(needs.generate-tag.outputs.tag, '-') + uses: ./.github/actions/build-securebuild-image-locally with: - context: kurl_proxy/deploy - component: kurl-proxy - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kurl-proxy.yaml image-name: index.docker.io/kotsadm/kurl-proxy:${{ needs.generate-tag.outputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} @@ -155,35 +143,16 @@ jobs: name: kots path: ./bin/kots - build-kotsadm-melange-packages: - needs: [generate-tag] - strategy: - fail-fast: true - matrix: - runner: [ - {name: ubuntu-latest, arch: amd64}, - {name: arm64-runner-set, arch: arm64} - ] - runs-on: ${{ matrix.runner.name }} - steps: - - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-melange-package - with: - context: deploy - component: kotsadm - git-tag: ${{ needs.generate-tag.outputs.tag }} - arch: ${{ matrix.runner.arch }} - build-kotsadm: runs-on: ubuntu-latest - needs: [generate-tag, build-kotsadm-melange-packages] + needs: [generate-tag, build-melange-packages, build-securebuild] + if: ${{ !cancelled() && needs.generate-tag.result == 'success' && (needs.build-melange-packages.result == 'success' || needs.build-securebuild.result == 'success') }} steps: - uses: actions/checkout@v7 - - uses: ./.github/actions/build-custom-image-with-apko + - if: contains(needs.generate-tag.outputs.tag, '-') + uses: ./.github/actions/build-securebuild-image-locally with: - context: deploy - component: kotsadm - git-tag: ${{ needs.generate-tag.outputs.tag }} + config: securebuild/image/apko-kotsadm.yaml image-name: index.docker.io/kotsadm/kotsadm:${{ needs.generate-tag.outputs.tag }} registry-username: ${{ secrets.DOCKERHUB_USER }} registry-password: ${{ secrets.DOCKERHUB_PASSWORD }} diff --git a/deploy/apko.yaml.tmpl b/deploy/apko.yaml.tmpl deleted file mode 100644 index d5614b1876..0000000000 --- a/deploy/apko.yaml.tmpl +++ /dev/null @@ -1,49 +0,0 @@ -contents: - repositories: - - https://apk.cve0.io - - ./packages/ - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - - ./melange-arm64.rsa.pub - - ./melange-amd64.rsa.pub - packages: - - kotsadm-head # This is expected to be built locally by `melange`. - - kubectl - - bash - - busybox - - curl - - git - - kustomize - - py3-magic - - py3-six - - s3cmd - - securebuild-baselayout - - helm~4 - -accounts: - groups: - - groupname: kotsadm - gid: 1001 - users: - - username: kotsadm - uid: 1001 - gid: 1001 - run-as: kotsadm - -environment: - VERSION: ${GIT_TAG} - -paths: - - path: /usr/local/bin/helm - type: symlink - source: /usr/bin/helm - permissions: 0o755 - - path: /usr/local/bin/kustomize - type: symlink - source: /usr/bin/kustomize - permissions: 0o755 - -entrypoint: - command: /kotsadm - -cmd: api diff --git a/deploy/apko_melange_build.md b/deploy/apko_melange_build.md index 4d682a598a..5ec822fb80 100644 --- a/deploy/apko_melange_build.md +++ b/deploy/apko_melange_build.md @@ -2,7 +2,14 @@ ## What? -This doc describes a non-production-ready process for building a minimal `kots` image using `melange` and `apko`: +KOTS packages and images are defined by the SecureBuild Melange and APKO specs: + +- [`securebuild/package/melange.yaml`](../securebuild/package/melange.yaml) +- [`securebuild/image/apko-kotsadm.yaml`](../securebuild/image/apko-kotsadm.yaml) +- [`securebuild/image/apko-kotsadm-migrations.yaml`](../securebuild/image/apko-kotsadm-migrations.yaml) +- [`securebuild/image/apko-kurl-proxy.yaml`](../securebuild/image/apko-kurl-proxy.yaml) + +Stable releases build these specs with the SecureBuild CLI. Prerelease and CI builds run the same specs locally with `melange` and `apko`: - [`melange`](https://github.com/chainguard-dev/melange) is a tool for reproducibly building APK packages from source - [`apko`](https://github.com/chainguard-dev/apko) is a tool for reproducibly building container images from APK packages @@ -13,38 +20,16 @@ Building with `melange` and `apko` produces smaller, more reproducible images, w ## How? -First, build the package from source, using `melange`. - -To start, if there isn't already a signing key for the package, we need to generate one: - -```sh -melange keygen -``` - -We only need to build for x86_64, which is faster than building for arm64 since it doesn't require qemu. - -```sh -melange build melange.yaml --arch=x86_64 -``` - -> 💡 Only building for your local platform makes builds faster, since it doesn't have to emulate with qemu. -> If you're on an arm64 machine (e.g., Apple Silicon), use `--arch=aarch64` here and below. - -Then, build the image from the newly built `kotsadm` package, and the other packages needed by the image, using `apko`: - -```sh -apko publish apko.yaml ttl.sh/kotsadm --arch=x86_64 -``` +The local build is implemented by these composite actions: -This will print the image to stdout, so you can run it: +- [`build-securebuild-package-locally`](../.github/actions/build-securebuild-package-locally/action.yml) adapts the package spec to build an exact source commit with an APK-compatible placeholder version, embeds the requested prerelease version, signs the packages, and uploads the local APK repository. +- [`build-securebuild-image-locally`](../.github/actions/build-securebuild-image-locally/action.yml) downloads that repository and publishes the three APKO images from it. -```sh -docker run $(apko publish ...) -``` +See the `build-melange-packages`, `build-kotsadm`, `build-migrations`, and `build-kurl-proxy` jobs in [`build-test.yaml`](../.github/workflows/build-test.yaml) for a complete TTL registry example. ### Presubmit GitHub Actions -The above steps are automated in [GitHub Actions](./.github/actions/build-kotsadm-image/action.yml) as a presubmit check for PRs. +The above steps are automated in GitHub Actions as a presubmit check for PRs. The image this workflow produces is only meant for validation, and not meant for production use cases at this time. diff --git a/deploy/melange.yaml.tmpl b/deploy/melange.yaml.tmpl deleted file mode 100644 index 39b84ea5ef..0000000000 --- a/deploy/melange.yaml.tmpl +++ /dev/null @@ -1,53 +0,0 @@ -package: - name: kotsadm-head - version: "0.0.1" # our versioning is not compatible with apk - epoch: 0 - description: Kotsadm package - copyright: - - license: Apache-2.0 - -environment: - contents: - repositories: - - https://apk.cve0.io - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - packages: - - ca-certificates-bundle - - bash - - busybox - - curl - - git - - go - - nodejs~24 - - icu-data-full~77 - - yarn - -pipeline: - - runs: | - set -x - export DESTDIR="${{targets.destdir}}" - mkdir -p "${DESTDIR}" - - # Scripts etc. - mv deploy/assets "${DESTDIR}/scripts" - - # kotsadm and kots binaries - export VERSION=${GIT_TAG} - export GIT_TAG=${GIT_TAG} - - # Set environment variables from repository - . ./.image.env - - # TODO: fix pact build error on arm https://github.com/pact-foundation/pact-js-core/issues/264 - export PACT_SKIP_BINARY_INSTALL=true - - # Configure Yarn - yarn config set httpTimeout 300000 - yarn install --pure-lockfile --network-concurrency 1 - - make -C web deps build-kotsadm - make kots build - - mv bin/kotsadm "${DESTDIR}/kotsadm" - mv bin/kots "${DESTDIR}/kots" diff --git a/kurl_proxy/deploy/apko.yaml.tmpl b/kurl_proxy/deploy/apko.yaml.tmpl deleted file mode 100644 index 437e40c499..0000000000 --- a/kurl_proxy/deploy/apko.yaml.tmpl +++ /dev/null @@ -1,30 +0,0 @@ -contents: - repositories: - - https://apk.cve0.io - - ./packages/ - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - - ./melange-arm64.rsa.pub - - ./melange-amd64.rsa.pub - packages: - - kurl-proxy-head # This is expected to be built locally by `melange`. - - bash - - busybox - - curl - - git - - securebuild-baselayout - -accounts: - groups: - - groupname: kotsadm - gid: 1001 - users: - - username: kotsadm - uid: 1001 - gid: 1001 - run-as: kotsadm - -environment: - VERSION: ${GIT_TAG} - -cmd: /kurl_proxy diff --git a/kurl_proxy/deploy/melange.yaml.tmpl b/kurl_proxy/deploy/melange.yaml.tmpl deleted file mode 100644 index f8f0131236..0000000000 --- a/kurl_proxy/deploy/melange.yaml.tmpl +++ /dev/null @@ -1,31 +0,0 @@ -package: - name: kurl-proxy-head - version: "0.0.1" # our versioning is not compatible with apk - epoch: 0 - description: kurl-proxy package - copyright: - - license: Apache-2.0 - -environment: - contents: - repositories: - - https://apk.cve0.io - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - packages: - - ca-certificates-bundle - - busybox - - git - - bash - - go - -pipeline: - - runs: | - set -x - export DESTDIR="${{targets.destdir}}" - mkdir -p "${DESTDIR}" - - make -C kurl_proxy build - - mv kurl_proxy/bin/kurl_proxy "${DESTDIR}/kurl_proxy" - mv kurl_proxy/assets "${DESTDIR}/assets" diff --git a/migrations/deploy/apko.yaml.tmpl b/migrations/deploy/apko.yaml.tmpl deleted file mode 100644 index 5339c7ce64..0000000000 --- a/migrations/deploy/apko.yaml.tmpl +++ /dev/null @@ -1,36 +0,0 @@ -contents: - repositories: - - https://apk.cve0.io - - ./packages/ - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - - ./melange-arm64.rsa.pub - - ./melange-amd64.rsa.pub - packages: - - kotsadm-migrations-head # This is expected to be built locally by `melange`. - - bash - - busybox - - curl - - git - - ca-certificates - - securebuild-baselayout - - schemahero - - schemahero-rqlite - -accounts: - groups: - - groupname: schemahero - gid: 1001 - users: - - username: schemahero - uid: 1001 - gid: 1001 - run-as: schemahero - -environment: - VERSION: ${GIT_TAG} - -entrypoint: - command: /usr/bin/schemahero - -cmd: apply diff --git a/migrations/deploy/melange.yaml.tmpl b/migrations/deploy/melange.yaml.tmpl deleted file mode 100644 index 41744ba615..0000000000 --- a/migrations/deploy/melange.yaml.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -package: - name: kotsadm-migrations-head - version: "0.0.1" # our versioning is not compatible with apk - epoch: 0 - description: kotsadm-migrations package - copyright: - - license: Apache-2.0 - -environment: - contents: - repositories: - - https://apk.cve0.io - keyring: - - https://apk.cve0.io/key/cve0-signing.rsa.pub - packages: - - busybox - -pipeline: - - runs: | - set -x - export DESTDIR="${{targets.destdir}}" - mkdir -p "${DESTDIR}" - - mv migrations/tables "${DESTDIR}/tables"