-
Notifications
You must be signed in to change notification settings - Fork 29
chore: switch to container build #2118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # | ||
| # Copyright (C) 2023-2024 Red Hat, Inc. | ||
| # Copyright (C) 2023-2025 Red Hat, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
|
|
@@ -23,37 +23,111 @@ on: | |
| - 'main' | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-22.04 | ||
| check-builder-changes: | ||
| runs-on: ubuntu-24.04 | ||
| outputs: | ||
| builder_required: ${{ steps.check.outputs.builder_required }} | ||
| steps: | ||
| - name: Checkout Repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 2 # Ensure we have at least one previous commit for diff check | ||
|
|
||
| - name: Check for builder-related changes | ||
| id: check | ||
| run: | | ||
| if git diff --name-only HEAD^ HEAD | grep -E '^(package.json|pnpm-lock.yaml|build/Containerfile.builder|.github/workflows/build-next.yaml)$'; then | ||
| echo "builder_required=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "builder_required=false" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| builder-image: | ||
| needs: check-builder-changes | ||
| if: needs.check-builder-changes.outputs.builder_required == 'true' | ||
| name: Build and publish builder OCI images only if pnpm-lock.yaml or package.json changes | ||
| runs-on: ubuntu-24.04 | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: pnpm/action-setup@v4 | ||
| name: Install pnpm | ||
| - name: build builder image | ||
| id: builder-image | ||
| uses: redhat-actions/buildah-build@v2 | ||
| with: | ||
| run_install: false | ||
| image: extension-bootc-builder | ||
| tags: next ${{ github.sha }} | ||
| platforms: linux/amd64, linux/arm64 | ||
| containerfiles: | | ||
| build/Containerfile.builder | ||
| context: . | ||
| oci: true | ||
|
|
||
| - uses: actions/setup-node@v6 | ||
| - name: Log in to ghcr.io | ||
| uses: redhat-actions/podman-login@v1 | ||
| with: | ||
| node-version: 22 | ||
| cache: 'pnpm' | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| registry: ghcr.io | ||
|
|
||
| - name: Execute pnpm | ||
| run: pnpm install | ||
| - name: publish builder to ghcr.io | ||
| id: push-to-ghcr | ||
| uses: redhat-actions/push-to-registry@v2 | ||
| with: | ||
| image: ${{ steps.builder-image.outputs.image }} | ||
| tags: ${{ steps.builder-image.outputs.tags }} | ||
| registry: ghcr.io/${{ github.repository_owner }} | ||
|
|
||
| - name: Run Build | ||
| run: pnpm build | ||
| - name: Generate artifact attestation | ||
| uses: actions/attest-build-provenance@v3 | ||
| with: | ||
| subject-name: ghcr.io/${{ github.repository_owner }}/extension-bootc-builder | ||
| subject-digest: ${{ steps.push-to-ghcr.outputs.digest }} | ||
| push-to-registry: true | ||
|
Comment on lines
+83
to
+88
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very interesting 👁️ |
||
|
|
||
| - name: Login to ghcr.io | ||
| run: podman login --username ${{ github.repository_owner }} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io | ||
| extension-image: | ||
| name: Build and publish extension OCI image | ||
| if: always() | ||
| runs-on: ubuntu-24.04 | ||
| needs: builder-image | ||
|
|
||
| - name: Publish Image | ||
| id: publish-image | ||
| run: | | ||
| IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/podman-desktop-extension-bootc | ||
| IMAGE_NIGHTLY=${IMAGE_NAME}:nightly | ||
| IMAGE_SHA=${IMAGE_NAME}:${GITHUB_SHA} | ||
| podman build -t $IMAGE_NIGHTLY . | ||
| podman push $IMAGE_NIGHTLY | ||
| podman tag $IMAGE_NIGHTLY $IMAGE_SHA | ||
| podman push $IMAGE_SHA | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: build extension image | ||
| id: extension-image | ||
| uses: redhat-actions/buildah-build@v2 | ||
| with: | ||
| image: extension-bootc | ||
| tags: next ${{ github.sha }} | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a tag with space?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is a list of tags:
|
||
| archs: amd64, arm64 | ||
| containerfiles: | | ||
| build/Containerfile | ||
| context: . | ||
| oci: true | ||
|
|
||
| - name: Log in to ghcr.io | ||
| uses: redhat-actions/podman-login@v1 | ||
| with: | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| registry: ghcr.io | ||
|
|
||
| - name: publish extension to ghcr.io | ||
| id: push-to-ghcr | ||
| uses: redhat-actions/push-to-registry@v2 | ||
| with: | ||
| image: ${{ steps.extension-image.outputs.image }} | ||
| tags: ${{ steps.extension-image.outputs.tags }} | ||
| registry: ghcr.io/${{ github.repository_owner }} | ||
|
|
||
| - name: Generate artifact attestation | ||
| uses: actions/attest-build-provenance@v3 | ||
| with: | ||
| subject-name: ghcr.io/${{ github.repository_owner }}/extension-bootc | ||
| subject-digest: ${{ steps.push-to-ghcr.outputs.digest }} | ||
| push-to-registry: true | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # | ||
| # Copyright (C) 2023-2024 Red Hat, Inc. | ||
| # Copyright (C) 2023-2025 Red Hat, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
|
|
@@ -103,32 +103,104 @@ jobs: | |
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - uses: pnpm/action-setup@v4 | ||
| name: Install pnpm | ||
| builder-image: | ||
| needs: tag | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| run_install: false | ||
| ref: ${{ needs.tag.outputs.githubTag }} | ||
|
|
||
| - uses: actions/setup-node@v6 | ||
| - name: build builder image | ||
| id: builder-image | ||
| uses: redhat-actions/buildah-build@v2 | ||
| with: | ||
| node-version: 22 | ||
| cache: 'pnpm' | ||
| image: extension-bootc-builder | ||
| tags: latest ${{ needs.tag.outputs.bootcExtensionVersion }} | ||
| platforms: linux/amd64, linux/arm64 | ||
| containerfiles: | | ||
| build/Containerfile.builder | ||
| context: . | ||
| oci: true | ||
|
|
||
| - name: Execute pnpm | ||
| run: pnpm install | ||
| - name: Log in to ghcr.io | ||
| uses: redhat-actions/podman-login@v1 | ||
| with: | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| registry: ghcr.io | ||
|
|
||
| - name: Run Build | ||
| run: pnpm build | ||
| - name: publish builder to ghcr.io | ||
| id: push-to-ghcr | ||
| uses: redhat-actions/push-to-registry@v2 | ||
| with: | ||
| image: ${{ steps.builder-image.outputs.image }} | ||
| tags: ${{ steps.builder-image.outputs.tags }} | ||
| registry: ghcr.io/${{ github.repository_owner }} | ||
|
|
||
| - name: Login to ghcr.io | ||
| run: podman login --username ${{ github.repository_owner }} --password ${{ secrets.GITHUB_TOKEN }} ghcr.io | ||
| - name: Generate artifact attestation | ||
| uses: actions/attest-build-provenance@v3 | ||
| with: | ||
| subject-name: ghcr.io/${{ github.repository_owner }}/extension-bootc-builder | ||
| subject-digest: ${{ steps.push-to-ghcr.outputs.digest }} | ||
| push-to-registry: true | ||
|
|
||
| - name: Publish Image | ||
| id: publish-image | ||
| run: | | ||
| IMAGE_NAME=ghcr.io/${{ github.repository_owner }}/podman-desktop-extension-bootc | ||
| IMAGE_WITH_TAG=${IMAGE_NAME}:${{ steps.TAG_UTIL.outputs.bootcExtensionVersion }} | ||
| IMAGE_LATEST=${IMAGE_NAME}:latest | ||
| podman build -t $IMAGE_WITH_TAG . | ||
| podman push $IMAGE_WITH_TAG | ||
| podman tag $IMAGE_WITH_TAG $IMAGE_LATEST | ||
| podman push $IMAGE_LATEST | ||
| extension-image: | ||
| name: Build and publish extension OCI image | ||
|
|
||
| runs-on: ubuntu-24.04 | ||
| needs: [builder-image, tag] | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
Comment on lines
+155
to
+157
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent fetch-depth between jobs. The extension-image job uses Apply this diff if full history is needed for builder-image: - uses: actions/checkout@v6
with:
ref: ${{ needs.tag.outputs.githubTag }}
+ fetch-depth: 0Otherwise, remove
🤖 Prompt for AI Agents |
||
|
|
||
| - name: build extension image | ||
| id: extension-image | ||
| uses: redhat-actions/buildah-build@v2 | ||
| with: | ||
| image: extension-bootc | ||
| tags: latest ${{ needs.tag.outputs.bootcExtensionVersion }} | ||
| archs: amd64, arm64 | ||
| containerfiles: | | ||
| build/Containerfile | ||
| context: . | ||
| oci: true | ||
|
|
||
| - name: Log in to ghcr.io | ||
| uses: redhat-actions/podman-login@v1 | ||
| with: | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| registry: ghcr.io | ||
|
|
||
| - name: publish extension to ghcr.io | ||
| id: push-to-ghcr | ||
| uses: redhat-actions/push-to-registry@v2 | ||
| with: | ||
| image: ${{ steps.extension-image.outputs.image }} | ||
| tags: ${{ steps.extension-image.outputs.tags }} | ||
| registry: ghcr.io/${{ github.repository_owner }} | ||
|
|
||
| - name: Generate artifact attestation | ||
| uses: actions/attest-build-provenance@v3 | ||
| with: | ||
| subject-name: ghcr.io/${{ github.repository_owner }}/extension-bootc | ||
| subject-digest: ${{ steps.push-to-ghcr.outputs.digest }} | ||
| push-to-registry: true | ||
|
|
||
| release: | ||
| needs: [tag, builder-image, extension-image] | ||
| name: Release | ||
| runs-on: ubuntu-24.04 | ||
| steps: | ||
| - name: id | ||
| run: echo the release id is ${{ needs.tag.outputs.releaseId}} | ||
|
|
||
| - name: Publish release | ||
| uses: StuYarrow/[email protected] | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| with: | ||
| id: ${{ needs.tag.outputs.releaseId}} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| # | ||
| # Copyright (C) 2025 Red Hat, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| FROM ghcr.io/podman-desktop/extension-bootc-builder:next AS builder | ||
|
|
||
| WORKDIR /opt/app-root/extension-source | ||
|
|
||
| # copy source code | ||
| COPY --chown=1001:root *.js /opt/app-root/extension-source/ | ||
| COPY --chown=1001:root .gitignore /opt/app-root/extension-source/ | ||
| COPY --chown=1001:root *.json /opt/app-root/extension-source/ | ||
| COPY --chown=1001:root packages /opt/app-root/extension-source/packages | ||
| COPY --chown=1001:root .npmrc /opt/app-root/extension-source/ | ||
| COPY --chown=1001:root .gitignore /opt/app-root/extension-source/ | ||
| COPY --chown=1001:root types /opt/app-root/extension-source/types | ||
|
|
||
| # refresh dependencies (if needed) | ||
| # and build the extension | ||
| RUN pnpm install && \ | ||
| pnpm build | ||
|
|
||
| # copy output of the build + required files | ||
| RUN mkdir /opt/app-root/extension && \ | ||
| cp -r packages/backend/dist /opt/app-root/extension/ && \ | ||
| cp packages/backend/package.json /opt/app-root/extension/ && \ | ||
| cp packages/backend/bootable.woff2 /opt/app-root/extension/ && \ | ||
| cp packages/backend/icon.png /opt/app-root/extension/ && \ | ||
| cp -r packages/backend/media/ /opt/app-root/extension/media | ||
|
|
||
| COPY LICENSE /opt/app-root/extension/ | ||
| COPY README.md /opt/app-root/extension/ | ||
|
|
||
| # TEMPORARY. Permanent fix will be in the future when we can add all of this to vite script. | ||
| # We require the macadam.js binaries and library, so we will manually copy this over to the container image. | ||
| # we rely on `pnpm build` before creating the container image, so we can safely assume that the macadam.js binaries are already present in the node_modules directory | ||
| # and can copy them over to the container image. | ||
| COPY node_modules/@crc-org/macadam.js /opt/app-root/extension/node_modules/@crc-org/macadam.js | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: I am a little bit concerned why those dependencies are handled manually and not through pnpm like the RHEL extension ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Me too, but this is unchanged from the current containerfile. As someone we know would say 'one PR one change'. :) I see what the RHEL extension did and can replicate in a following PR.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure to understand as Containerfile(s) are new in this PR ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There is an existing Containerfile at the root of the repository
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. non-blocker, but a concern. But any changes to the Containerfile that's outside-the-norm we should also check to see if it's correctly adding the arm64 madacam binary when building an arm64 container image. Same for amd64, etc. There were issues in the past where you would build this container image with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to this. I think I have a changeset that replicates what the RHEL extension build does, but that path changes where node_modules ends up in the final image and the structure of it (plus adds a few Mb). It would change this PR from 'it generates the identical extension as today, but we should still test' to 'the build output is fundamentally different so the only way to validate is testing on every platform'. I've opened #2136 to track this as a separate issue. |
||
| # Copy over ssh2 and it's dependencies (run jq '.dependencies' node_modules/ssh2/package.json locally to see) | ||
| COPY node_modules/ssh2 /opt/app-root/extension/node_modules/ssh2 | ||
| COPY node_modules/asn1 /opt/app-root/extension/node_modules/asn1 | ||
| COPY node_modules/bcrypt-pbkdf /opt/app-root/extension/node_modules/bcrypt-pbkdf | ||
| COPY node_modules/safer-buffer /opt/app-root/extension/node_modules/safer-buffer | ||
| COPY node_modules/tweetnacl /opt/app-root/extension/node_modules/tweetnacl | ||
|
|
||
| # Copy the extension to a new image | ||
| FROM scratch | ||
|
|
||
| LABEL org.opencontainers.image.title="Bootable Container Extension" \ | ||
| org.opencontainers.image.description="Podman Desktop extension for bootable OS containers (bootc) and generating disk images" \ | ||
| org.opencontainers.image.vendor="Red Hat" \ | ||
| io.podman-desktop.api.version=">= 1.18.0" | ||
|
|
||
| COPY --from=builder /opt/app-root/extension /extension | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. out of the context of this PR, but we need to revise the usage of a builder container, multi stage container exists, and we could use caching mechanism to make them as fast, and avoid publishing a builder image |
||
| # Copyright (C) 2025 Red Hat, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| FROM registry.access.redhat.com/ubi10/nodejs-22-minimal:10.1-1764649415 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check image version information from registry metadata if available
# and search for Node.js 22 security status
# First, let's check if there's any documentation in the repo about why this version was chosen
echo "=== Checking for any documentation about image versioning ==="
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "Dockerfile*" -o -name "Containerfile*" \) -exec grep -l "nodejs-22\|ubi10.*nodejs\|10\.1-1764649415" {} \;
# Search for any version management files
echo -e "\n=== Checking for version pinning rationale ==="
find . -type f \( -name ".dockerignore" -o -name "*.env" -o -name "versions.txt" -o -name "VERSIONS" \)
# Check the Containerfile for any comments about version pinning
echo -e "\n=== Full Containerfile.builder content ==="
cat build/Containerfile.builder
# Check git history for when this version was pinned
echo -e "\n=== Recent git history for this file ==="
git log --oneline -10 build/Containerfile.builder 2>/dev/null || echo "Git history not available"Repository: podman-desktop/extension-bootc Length of output: 204 🌐 Web query:
💡 Result: Short answer: The UBI10 nodejs-22-minimal images for RHEL 10.1 have received multiple security updates in 2025 (Important/High) addressing several Node.js CVEs — you should pull the latest 10.1 nodejs-22-minimal image and apply those updates. See Red Hat’s RHEL 10.1 notes and the RHSA advisories for nodejs:22 (examples: RHSA-2025:8493, RHSA-2025:1613; additional RHSA advisories exist). [1][2][3] References
If you want, I can: (a) check the exact image digest/tag in the Red Hat Catalog for ubi10/nodejs-22-minimal:10.1, or (b) list the specific CVEs and RHSA IDs affecting the 10.1 build. Which would you prefer? 🌐 Web query:
💡 Result: Short summary — Node.js 22.x (LTS) security issues in 2025
Actionable steps
Sources If you want, I can: (A) check the exact latest 22.x patch version for your platform and provide upgrade commands, or (B) fetch the full Node.js release notes and CVE text. Which would you prefer? Citations:
Update the base image to the latest 10.1- build.* The pinned version 🧰 Tools🪛 RuboCop (1.81.7)[fatal] 18-18: unexpected token tCOLON (Lint/Syntax) 🤖 Prompt for AI Agents |
||
|
|
||
| # change home directory to be at /opt/app-root | ||
| ENV HOME=/opt/app-root | ||
|
|
||
| # copy the application files to the /opt/app-root/extension-source directory | ||
| WORKDIR /opt/app-root/extension-source | ||
| RUN mkdir -p /opt/app-root/extension-source | ||
| COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc /opt/app-root/extension-source/ | ||
| COPY packages/backend/package.json /opt/app-root/extension-source/packages/backend/package.json | ||
| COPY packages/frontend/package.json /opt/app-root/extension-source/packages/frontend/package.json | ||
|
|
||
| RUN npm install --global pnpm@10 && \ | ||
| pnpm --frozen-lockfile install | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit septic, are we sure we will not in a near future have this not covering all cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, but following the pattern from Apple and RHEL extensions. So I'd prefer to defer due to 'existing pattern' and I think we need a 'build epic' for future sprint where someone would look at multi-stage build, sharing workflow jobs, etc.