-
-
Notifications
You must be signed in to change notification settings - Fork 6
fix: resolve 5 open issues #45
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
base: main
Are you sure you want to change the base?
Changes from all commits
bf70049
e6bb370
f874a97
06c5731
c3a4bad
77977ef
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -36,62 +36,130 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # TODO: To be implemented | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # test-job: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # uses: ./.github/workflows/ci.yml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| build-job: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # TODO: To be implemented | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # needs: test-job | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setup: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrix: ${{ steps.set-matrix.outputs.matrix }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: oven-sh/setup-bun@v1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: oven-sh/setup-bun@635640504f6d7197d3bb29876a652f671028dc97 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - run: bun install | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Download versions.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: gh release download versions -p versions.json || echo "{}" > versions.json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: gh release download versions -p versions.json || echo "{}" > versions.json | |
| run: gh release download versions -p versions.json || echo '{"bun":{},"nodejs":{}}' > versions.json |
Copilot
AI
Nov 23, 2025
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.
[nitpick] The cleanup step commits and pushes directly to the main branch without creating a pull request or obtaining approval. This automated cleanup could accidentally delete version folders that are still in use if the Node.js version detection has issues or if the external API returns incorrect data.
Consider one of the following safer approaches:
- Create a pull request for the cleanup changes instead of direct push
- Add a dry-run mode that logs what would be deleted without actually deleting
- Require manual workflow dispatch approval for cleanup operations
- Add better validation that the versions being deleted are truly EOL
| git push | |
| # Instead of pushing directly, create a pull request for the cleanup changes | |
| gh pr create --title "chore: cleanup unsupported versions" --body "Automated cleanup of unsupported versions." --base main --head ${{ github.ref_name }} |
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.
Bug: Missing git pull creates race condition risk
The cleanup step commits and pushes changes without pulling first. The previous workflow included a git pull -r step before pushing. If multiple workflow runs execute concurrently (e.g., scheduled run and manual trigger), the push operation will fail when the remote has been updated by another run, causing the cleanup step to error.
Copilot
AI
Nov 23, 2025
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.
The cleanup step commits and pushes changes to the repository during the workflow. This can cause race conditions if multiple workflow runs happen simultaneously (e.g., scheduled and manual triggers). Additionally, pushing commits from within a workflow can trigger new workflow runs, potentially causing an infinite loop if not properly guarded.
Consider either:
- Using a separate workflow run for cleanup that runs less frequently
- Using branch protection rules or checking if changes were actually made to unsupported versions
- Using a lock mechanism to prevent concurrent cleanup operations
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.
Bug: Workflow manual trigger inputs completely ignored
The workflow defines manual trigger inputs for bun-versions, nodejs-version, and distros, but these inputs are never referenced in the new implementation. The generateMatrix function only reads from environment variables, not workflow inputs. This breaks manual workflow dispatch functionality where users expect to build specific versions by providing inputs, as was possible in the previous version that used ${{ env.NODE_VERSIONS_TO_BUILD || inputs.nodejs-version }}.
Copilot
AI
Nov 23, 2025
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.
The workflow defines workflow_dispatch inputs for bun-versions, nodejs-version, and distros (lines 8-19), but these inputs are not actually used in the new matrix-based workflow. The setup job generates the matrix dynamically from environment variables and doesn't consider the manual inputs.
This means manual workflow triggers with custom versions will be ignored. If this is intentional (forcing all builds to go through the automatic detection), the inputs should be removed from the workflow. Otherwise, the matrix generation logic needs to incorporate these inputs when provided.
| DISTROS: ${{ env.DISTROS }} | |
| NODE_MAJOR_VERSIONS_TO_CHECK: ${{ env.NODE_MAJOR_VERSIONS_TO_CHECK }} | |
| DISTROS: ${{ github.event.inputs.distros != '' && github.event.inputs.distros || env.DISTROS }} | |
| NODE_MAJOR_VERSIONS_TO_CHECK: ${{ env.NODE_MAJOR_VERSIONS_TO_CHECK }} | |
| NODE_VERSIONS_TO_BUILD: ${{ github.event.inputs.nodejs-version != '' && github.event.inputs.nodejs-version || env.NODE_VERSIONS_TO_BUILD }} | |
| BUN_VERSIONS_TO_BUILD: ${{ github.event.inputs['bun-versions'] != '' && github.event.inputs['bun-versions'] || env.BUN_VERSIONS_TO_BUILD }} |
Copilot
AI
Nov 23, 2025
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.
The condition if: ${{ fromJson(needs.setup.outputs.matrix).include[0] }} will fail if the matrix JSON is malformed or if accessing .include[0] on an empty array. This can cause the workflow to fail with a cryptic error instead of gracefully skipping the build job.
Use a more robust condition:
if: ${{ needs.setup.outputs.matrix != '' && needs.setup.outputs.matrix != '{"include":[]}' }}Or better yet, add a dedicated output flag in the setup job to indicate whether builds are needed.
| if: ${{ fromJson(needs.setup.outputs.matrix).include[0] }} | |
| if: ${{ needs.setup.outputs.matrix != '' && needs.setup.outputs.matrix != '{"include":[]}' }} |
Copilot
AI
Nov 23, 2025
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.
Missing executable permission. The script is being called directly with ./build_single.sh but there's no step to make it executable. While this might work if the file is already committed with executable permissions, it's safer to ensure it explicitly in the workflow.
Add before the build step:
- name: Make build script executable
run: chmod +x build_single.shCheck warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 9 days ago
To fix this problem, add an explicit permissions block to the workflow configuration. Assign the minimal permissions required for the workflow/features used in each job. The workflow performs a variety of operations:
- Uses
ghCLI insetup,update-release(e.g. downloading/creating/uploading releases, which requirecontentswrite), - Commits and pushes in
setup(requirescontents: write), - Uses
actions/checkout, uploads and downloads artifacts, but does not write to the repository inbuildorrerun-failed-jobs.
Therefore, set contents: write for the jobs that use gh release commands and/or push to the repo, and set contents: read for jobs that only require read access (like build and rerun-failed-jobs).
For clarity and security, add a permissions: block to each of the four jobs:
setup:contents: writebuild:contents: readupdate-release:contents: writererun-failed-jobs:contents: read
Perform these additions at the top of each job definition in the file.
-
Copy modified lines R40-R41 -
Copy modified lines R79-R80 -
Copy modified lines R122-R123 -
Copy modified lines R167-R168
| @@ -37,6 +37,8 @@ | ||
| # test-job: | ||
| # uses: ./.github/workflows/ci.yml | ||
| setup: | ||
| permissions: | ||
| contents: write | ||
| runs-on: ubuntu-latest | ||
| outputs: | ||
| matrix: ${{ steps.set-matrix.outputs.matrix }} | ||
| @@ -74,6 +76,8 @@ | ||
|
|
||
| build: | ||
| needs: setup | ||
| permissions: | ||
| contents: read | ||
| runs-on: ubuntu-latest | ||
| if: ${{ fromJson(needs.setup.outputs.matrix).include[0] }} | ||
| strategy: | ||
| @@ -115,6 +119,8 @@ | ||
|
|
||
| update-release: | ||
| needs: build | ||
| permissions: | ||
| contents: write | ||
| runs-on: ubuntu-latest | ||
| if: always() && needs.build.result == 'success' | ||
| steps: | ||
| @@ -158,6 +164,8 @@ | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| rerun-failed-jobs: | ||
| permissions: | ||
| contents: read | ||
| runs-on: ubuntu-latest | ||
| needs: [build] | ||
| if: failure() |
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.
Bug: Matrix job success check prevents partial updates
The update-release job checks needs.build.result == 'success', but since build is a matrix job, this requires ALL matrix jobs to succeed. If any single build fails (e.g., one distro out of 12 combinations), the entire result is failure, preventing the update-release job from running. This means successful builds won't update versions.json in the release, losing track of which versions were actually built.
Copilot
AI
Nov 23, 2025
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.
The condition if: always() && needs.build.result == 'success' is logically contradictory. If any build job in the matrix fails, needs.build.result will be either 'failure' or 'cancelled', not 'success'. This means the update-release job will never run if any build fails, even though some builds may have succeeded.
If you want to update versions.json with partial successes, use:
if: always() && contains(needs.build.result, 'success')Or if you only want to proceed when ALL builds succeed:
if: needs.build.result == 'success'The always() is redundant in the latter case.
| if: always() && needs.build.result == 'success' | |
| if: always() && contains(needs.build.result, 'success') |
Copilot
AI
Nov 23, 2025
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.
The merge logic in the Update versions.json step doesn't handle the case where no build artifacts exist (e.g., if all builds failed or the matrix was empty). The glob pattern updates/*.json will fail to match any files, causing the loop to execute once with file set to the literal string "updates/*.json".
Add a check to handle this case:
shopt -s nullglob # Prevent glob from matching itself if no files found
for file in updates/*.json; do
if [ -f "$file" ]; then
jq -s '.[0] * .[1]' versions.json "$file" > versions.json.tmp && mv versions.json.tmp versions.json
fi
done
# Check if any updates were applied
if [ ! -f versions.json.tmp ]; then
echo "No build artifacts found, skipping versions.json update"
fi
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
Copilot
AI
Nov 23, 2025
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.
The gh release create command will fail if a release named "versions" already exists (which it will after the first run). The fallback with || will then try to upload, but the error from the first command might cause confusion in logs.
Additionally, using a release tag named "versions" is unconventional and might conflict with actual version tags in the future. Consider using a more specific tag like "state" or "metadata".
Improve the logic:
# Check if release exists first
if gh release view versions >/dev/null 2>&1; then
gh release upload versions versions.json --clobber
else
gh release create versions versions.json --title "Versions State" --notes "Stores the current versions.json state"
fiCheck warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,144 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Exit on error | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Logging function | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check warning on line 7 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')] $@" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Retry function | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| retry() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local retries=${RETRIES:-3} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local count=0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| until "$@"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit_code=$? | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| count=$((count + 1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ $count -lt $retries ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 18 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| log "Retrying ($count/$retries)..." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| sleep 5 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log "Failed after $count attempts." | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return $exit_code | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Parse arguments | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| while [[ "$#" -gt 0 ]]; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| case $1 in | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --bun) BUN_VERSION="$2"; shift ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --node) NODE_VERSION="$2"; shift ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| --distro) DISTRO="$2"; shift ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| *) echo "Unknown parameter passed: $1"; exit 1 ;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| esac | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$BUN_VERSION" ] || [ -z "$NODE_VERSION" ] || [ -z "$DISTRO" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 40 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "Usage: $0 --bun <version> --node <version> --distro <distro>" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| log "Building image for Bun version $BUN_VERSION, Node version $NODE_VERSION, Distro $DISTRO" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Read versions.json for codename lookup (optional, but good for tagging) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # If versions.json is not present, we might miss some tags, but the matrix generation should have ensured we have what we need. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Actually, we need versions.json to know the codename (e.g. "Iron") and to check if it's "latest". | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We can expect versions.json to be present in the working directory (downloaded by workflow). | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "versions.json" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 52 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| json_data=$(cat versions.json) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| json_data="{}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| REGISTRY=${REGISTRY:-imbios} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| PLATFORMS=${PLATFORMS:-linux/amd64,linux/arm64} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| generate_tags() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check warning on line 61 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| local bun_version=$1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local node_version=$2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local distro=$3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| local node_major=${node_version%%.*} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local node_minor=${node_version%.*} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local bun_major=${bun_version%%.*} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local bun_minor=${bun_version%.*} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| local is_canary=false | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $bun_version == *"-canary"* ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_canary=true | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| bun_version="canary" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_version}-${node_version}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ $is_canary == false ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 79 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_minor}-${node_version}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_major}-${node_version}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_version}-${node_minor}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_version}-${node_major}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif [[ $bun_version == "canary" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:canary-${node_minor}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:canary-${node_major}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| local codename=$(echo "${json_data}" | jq -r ".nodejs.\"${node_major}\".name") | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$codename" != "null" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 90 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${bun_version}-${codename}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $is_canary == false ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:latest-${codename}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $is_canary == false ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:latest-${node_version}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:latest-${node_major}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Latest tag logic | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| # We rely on the caller (workflow) or check versions.json to see if this is the latest Node version. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| local latest_node_major=$(echo "${json_data}" | jq -r '.nodejs | keys | map(tonumber) | max') | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $is_canary == false && "$node_major" == "$latest_node_major" && $distro == "debian" ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:latest" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. Bug: Empty versions.json causes jq error for latest tagWhen |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [[ $is_canary == false ]]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "$REGISTRY/bun-node:${node_major}-${distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| tag_distro=$DISTRO | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$DISTRO" == "debian-slim" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 116 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| tag_distro="slim" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| tags=($(generate_tags "$BUN_VERSION" "$NODE_VERSION" "$tag_distro")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| image_name="$REGISTRY/bun-node:${BUN_VERSION}-${NODE_VERSION}-${tag_distro}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| node_major=${NODE_VERSION%%.*} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| for tag in "${tags[@]}"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| log "Tagging $image_name as $tag" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" -t "$image_name" -t "$tag" "./src/base/${node_major}/${DISTRO}" --push --provenance=mode=max | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ "$DISTRO" == "alpine" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Check failure on line 129 in build_single.sh
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| log "Building and Tagging Alpine image with Git" | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" -t "$image_name-git" -t "$tag-git" "./src/git/${node_major}/${DISTRO}" --push --provenance=mode=max | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. Bug: Docker image rebuilt for every tagThe loop rebuilds the same Docker image from scratch for each tag instead of building once with all tags. With potentially 10+ tags per image, this causes the same image to be built 10+ times, significantly increasing build time and resource usage. The |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+125
to
+134
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| for tag in "${tags[@]}"; do | |
| log "Tagging $image_name as $tag" | |
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" -t "$image_name" -t "$tag" "./src/base/${node_major}/${DISTRO}" --push --provenance=mode=max | |
| if [ "$DISTRO" == "alpine" ]; then | |
| log "Building and Tagging Alpine image with Git" | |
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" -t "$image_name-git" -t "$tag-git" "./src/git/${node_major}/${DISTRO}" --push --provenance=mode=max | |
| fi | |
| done | |
| # Build all tags in a single command | |
| tag_args="-t \"$image_name\"" | |
| for tag in "${tags[@]}"; do | |
| tag_args="$tag_args -t \"$tag\"" | |
| done | |
| log "Building and pushing image with tags: ${tags[*]}" | |
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" $tag_args "./src/base/${node_major}/${DISTRO}" --push --provenance=mode=max | |
| if [ "$DISTRO" == "alpine" ]; then | |
| log "Building and Tagging Alpine image with Git" | |
| git_tag_args="-t \"$image_name-git\"" | |
| for tag in "${tags[@]}"; do | |
| git_tag_args="$git_tag_args -t \"$tag-git\"" | |
| done | |
| retry docker buildx build --sbom=true --provenance=true --platform "$PLATFORMS" $git_tag_args "./src/git/${node_major}/${DISTRO}" --push --provenance=mode=max | |
| fi |
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.
Bug: Codename missing from build success JSON output
The build_success.json output only includes the version field for Node.js entries but omits the name field containing the codename (like "iron" or "jod"). When a new Node major version is built for the first time, the merged versions.json won't have the codename, causing tags like latest-iron-debian to be skipped during subsequent builds since generate_tags checks for non-null codenames before creating those tags.
Copilot
AI
Nov 23, 2025
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.
The build_success.json output is missing the Node.js codename field, which is present in the original versions.json structure. This will cause the merged versions.json to lose codename information (e.g., "iron", "jod", "krypton").
The output should include the codename:
codename=$(echo "${json_data}" | jq -r ".nodejs.\"${node_major}\".name")
if [ "$codename" != "null" ] && [ -n "$codename" ]; then
echo "{\"nodejs\": {\"$node_major\": {\"name\": \"$codename\", \"version\": \"v$NODE_VERSION\"}}, \"bun\": {\"$bun_tag\": \"v$BUN_VERSION\"}}" > build_success.json
else
echo "{\"nodejs\": {\"$node_major\": {\"version\": \"v$NODE_VERSION\"}}, \"bun\": {\"$bun_tag\": \"v$BUN_VERSION\"}}" > build_success.json
fi| echo "{\"nodejs\": {\"$node_major\": {\"version\": \"v$NODE_VERSION\"}}, \"bun\": {\"$bun_tag\": \"v$BUN_VERSION\"}}" > build_success.json | |
| # Extract codename from versions.json if available | |
| if [ -f versions.json ]; then | |
| json_data=$(cat versions.json) | |
| codename=$(echo "${json_data}" | jq -r ".nodejs.\"${node_major}\".name") | |
| else | |
| codename="" | |
| fi | |
| if [ "$codename" != "null" ] && [ -n "$codename" ]; then | |
| echo "{\"nodejs\": {\"$node_major\": {\"name\": \"$codename\", \"version\": \"v$NODE_VERSION\"}}, \"bun\": {\"$bun_tag\": \"v$BUN_VERSION\"}}" > build_success.json | |
| else | |
| echo "{\"nodejs\": {\"$node_major\": {\"version\": \"v$NODE_VERSION\"}}, \"bun\": {\"$bun_tag\": \"v$BUN_VERSION\"}}" > build_success.json | |
| fi |
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.
Bug: Missing dependency installation in setup job
The
setupjob removed thebun installstep that was present in the old workflow. Thecheck-bun-node.tsscript imports@nodevu/corefrompackage.jsondependencies, which won't be available without installing dependencies first. This causes the script to fail when running--cleanupor--matrixcommands in subsequent steps.