-
-
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 3 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 |
|---|---|---|
|
|
@@ -47,6 +47,11 @@ jobs: | |
| - uses: oven-sh/setup-bun@635640504f6d7197d3bb29876a652f671028dc97 | ||
| - run: bun install | ||
|
|
||
| - name: Download versions.json | ||
| run: gh release download versions -p versions.json || echo "{}" > versions.json | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Check for new releases of nodejs and bun | ||
| if: ${{ inputs.nodejs-version == '' && inputs.bun-versions == '' && inputs.distros == '' }} | ||
| run: | | ||
|
|
@@ -77,18 +82,12 @@ jobs: | |
| BUN_VERSIONS_TO_BUILD: ${{ env.BUN_VERSIONS_TO_BUILD || inputs.bun-versions }} | ||
| DISTROS: ${{ env.DISTROS || inputs.distros }} | ||
|
|
||
| - name: Commit changes | ||
| run: ./commit_changes.sh | ||
| - name: Upload versions.json | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| run: | | ||
| gh release create versions versions.json --title "Versions State" --notes "Stores the current versions.json state" || \ | ||
| gh release upload versions versions.json --clobber | ||
|
Comment on lines
+154
to
+156
|
||
| env: | ||
| BUN_VERSIONS_TO_BUILD: ${{ env.BUN_VERSIONS_TO_BUILD }} | ||
| NODE_VERSIONS_TO_BUILD: ${{ env.NODE_VERSIONS_TO_BUILD }} | ||
| DISTROS: ${{ env.DISTROS }} | ||
| - name: Pull changes | ||
| run: git pull -r | ||
| - name: Push changes | ||
| uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa | ||
| with: | ||
| github_token: ${{ secrets.GITHUB_TOKEN }} | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
Comment on lines
153
to
158
|
||
| rerun-failed-jobs: | ||
| runs-on: ubuntu-latest | ||
| needs: [build-job] | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,26 +43,24 @@ IFS=',' read -ra DISTROS <<<"$DISTROS" | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| # If NODE_VERSIONS_TO_BUILD is empty, but BUN_VERSIONS_TO_BUILD is not, | ||||||||||||||||||||||
| # build all versions from versions.json | ||||||||||||||||||||||
| # If NODE_VERSIONS_TO_BUILD is empty, but BUN_VERSIONS_TO_BUILD is not, | ||||||||||||||||||||||
| # we used to build all versions from versions.json. | ||||||||||||||||||||||
| # But for automatic updates, we want to build NOTHING if no Node versions are updated. | ||||||||||||||||||||||
| if [ -z "$NODE_VERSIONS_TO_BUILD" ]; then | ||||||||||||||||||||||
| IFS=',' read -ra NODE_MAJOR_VERSIONS <<<"$NODE_MAJOR_VERSIONS_TO_CHECK" | ||||||||||||||||||||||
| log "No Node.js versions to build." | ||||||||||||||||||||||
| NODE_VERSIONS=() | ||||||||||||||||||||||
| for node_major_version in "${NODE_MAJOR_VERSIONS[@]}"; do | ||||||||||||||||||||||
| node_version=$(cat versions.json | jq -r ".nodejs.\"${node_major_version}\".version") | ||||||||||||||||||||||
| if [ "$node_version" != "null" ]; then | ||||||||||||||||||||||
| NODE_VERSIONS+=("${node_version//v/}") | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
| done | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| log "Building Node versions: ${NODE_VERSIONS[*]}" | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # If BUN_VERSIONS_TO_BUILD is empty, but NODE_VERSIONS_TO_BUILD is not, | ||||||||||||||||||||||
| # build all versions from versions.json | ||||||||||||||||||||||
| # If BUN_VERSIONS_TO_BUILD is empty, but NODE_VERSIONS_TO_BUILD is not, | ||||||||||||||||||||||
| # we used to build all versions from versions.json. | ||||||||||||||||||||||
| # But for automatic updates, we want to build NOTHING if no Bun versions are updated. | ||||||||||||||||||||||
|
||||||||||||||||||||||
| if [ -z "$BUN_VERSIONS_TO_BUILD" ]; then | ||||||||||||||||||||||
| log "No Bun versions to build." | ||||||||||||||||||||||
cursor[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||
| BUN_VERSIONS=() | ||||||||||||||||||||||
| for bun_version in $(cat versions.json | jq -r '.bun | keys[]'); do | ||||||||||||||||||||||
| BUN_VERSIONS+=("${bun_version//v/}") | ||||||||||||||||||||||
| done | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| log "Building Bun versions: ${BUN_VERSIONS[*]}" | ||||||||||||||||||||||
|
|
@@ -116,7 +114,19 @@ generate_tags() { | |||||||||||||||||||||
| echo "$REGISTRY/bun-node:latest-${codename}-${distro}" | ||||||||||||||||||||||
| fi | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if [[ $is_canary == false && "$node_major" == "20" && $distro == "debian" ]]; then | ||||||||||||||||||||||
| # Only tag "latest" if this is the latest Node.js version and Debian distro | ||||||||||||||||||||||
cursor[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||
| # We need to check if the current node_major is the latest one in versions.json | ||||||||||||||||||||||
| # This is a bit tricky in bash without parsing JSON again, but we can assume the loop order or check against a known latest. | ||||||||||||||||||||||
| # Better approach: The caller knows if it's the latest. | ||||||||||||||||||||||
| # For now, let's restrict it to the highest known major version we support (e.g. 25) or check if it's the last one in the list? | ||||||||||||||||||||||
| # Actually, the issue says "latest tag should be the last tag built". | ||||||||||||||||||||||
| # If we build in order, the last one overwrites 'latest'. | ||||||||||||||||||||||
| # BUT, if we build multiple versions, we might overwrite 'latest' with an older version if the loop isn't sorted or if we build an old version update. | ||||||||||||||||||||||
| # A safer way is to explicitly check if this node version is the "latest" defined in versions.json. | ||||||||||||||||||||||
|
||||||||||||||||||||||
| # Only tag "latest" if this is the latest Node.js version and Debian distro | |
| # We need to check if the current node_major is the latest one in versions.json | |
| # This is a bit tricky in bash without parsing JSON again, but we can assume the loop order or check against a known latest. | |
| # Better approach: The caller knows if it's the latest. | |
| # For now, let's restrict it to the highest known major version we support (e.g. 25) or check if it's the last one in the list? | |
| # Actually, the issue says "latest tag should be the last tag built". | |
| # If we build in order, the last one overwrites 'latest'. | |
| # BUT, if we build multiple versions, we might overwrite 'latest' with an older version if the loop isn't sorted or if we build an old version update. | |
| # A safer way is to explicitly check if this node version is the "latest" defined in versions.json. | |
| # Tag "latest" only if this is the highest Node.js major version in versions.json and the distro is Debian. |
Outdated
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 latest tag logic depends on versions.json existing and having the correct structure to determine latest_node_major. However, on first run or when the GitHub Release doesn't exist, the downloaded file will be {}, causing jq to return null for the max calculation.
This will cause the comparison "$node_major" == "$latest_node_major" to potentially fail or behave unexpectedly. Consider handling the case when versions.json is empty or malformed:
local latest_node_major=$(echo "${json_data}" | jq -r '.nodejs | keys | map(tonumber) | max // 25')This provides a fallback value of 25 if the calculation fails.
| local latest_node_major=$(echo "${json_data}" | jq -r '.nodejs | keys | map(tonumber) | max') | |
| local latest_node_major=$(echo "${json_data}" | jq -r '.nodejs | keys | map(tonumber) | max // 25') |
cursor[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -203,12 +203,24 @@ const main = async () => { | |||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if (process.argv.includes("--node")) { | ||||||||||||
| console.log( | ||||||||||||
| (await generateReleaseData()) | ||||||||||||
| .filter((release) => [20, 22, 24, 25].includes(release?.major || 0)) | ||||||||||||
| .map((release) => release?.versionWithPrefix.replace("v", "")) | ||||||||||||
| .join(",") | ||||||||||||
| ); | ||||||||||||
| const releases = await generateReleaseData(); | ||||||||||||
| const versionsJson = await Bun.file("versions.json").json(); | ||||||||||||
|
|
||||||||||||
| const newVersions = releases | ||||||||||||
| .filter((release) => [20, 22, 24, 25].includes(release?.major || 0)) | ||||||||||||
| .filter((release) => { | ||||||||||||
| if (!release) return false; | ||||||||||||
| const currentVersion = versionsJson.nodejs[release.major]?.version; | ||||||||||||
|
||||||||||||
| const currentVersion = versionsJson.nodejs[release.major]?.version; | |
| const nodejs = versionsJson.nodejs || {}; | |
| const currentVersion = nodejs[release.major]?.version; |
Outdated
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 optional chaining crashes on empty versions.json
When versions.json is downloaded and the GitHub release doesn't exist, the fallback creates an empty object {}. Accessing versionsJson.nodejs[release.major]?.version throws a TypeError because versionsJson.nodejs is undefined, and the optional chaining only applies to the .version access, not to [release.major]. This crashes on first run or when the release doesn't exist. The fix requires optional chaining on versionsJson.nodejs itself, like versionsJson.nodejs?.[release.major]?.version.
Outdated
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 inline comments on lines 214-217 are overly verbose and redundant. The core logic—comparing current version with the latest from nodevu—is clear from the code itself. Consider condensing to:
// Only build if the version has changed
return currentVersion !== release.versionWithPrefix;| // If current version is not set, or is different (assuming we only get newer versions from nodevu), it's an update. | |
| // Actually, nodevu returns the LATEST version for that major. | |
| // So if versions.json has v20.10.0 and nodevu says v20.11.0, we want to build. | |
| // If versions.json has v20.11.0 and nodevu says v20.11.0, we don't want to build. | |
| // Only build if the version has changed |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Research: Workflow Matrix vs Single Builder | ||
|
|
||
| ## Context | ||
| The current build system uses a "Single Builder" pattern where a single job runs a script (`build_updated.sh`) that iterates over all versions and builds them sequentially. Issue #24 suggests investigating if a GitHub Actions Matrix strategy would be better. | ||
|
|
||
| ## Comparison | ||
|
|
||
| | Feature | Single Builder (Current) | Workflow Matrix | | ||
| | :--- | :--- | :--- | | ||
| | **Parallelism** | Low (Sequential builds in loop) | High (Concurrent jobs) | | ||
| | **Failures** | One failure can stop the whole loop (unless handled carefully) | Isolated failures per job | | ||
| | **Resource Usage** | Single runner, longer duration | Multiple runners, shorter duration (burst) | | ||
| | **Complexity** | High (Bash script logic) | Medium (YAML configuration) | | ||
| | **Cost** | Lower (1 runner time) | Higher (Multiple runners init time overhead) | | ||
| | **Logs** | Mixed in one huge log | Separated per job | | ||
| | **Dynamic** | Hard (Need to generate JSON for matrix) | Native support for dynamic matrix | | ||
|
|
||
| ## Analysis for bun-node | ||
|
|
||
| ### Pros of Matrix | ||
| 1. **Speed:** Building multiple Docker images is time-consuming. Parallelizing this would significantly reduce total build time. | ||
| 2. **Isolation:** If one image build fails (e.g., specific Node version issue), it won't block others. | ||
| 3. **Clarity:** GitHub UI shows exactly which build failed. | ||
|
|
||
| ### Cons of Matrix | ||
| 1. **Complexity of Dynamic Matrix:** Since we only want to build *updated* versions, we need a "setup" job that calculates the matrix (JSON) and passes it to the build job. | ||
| 2. **Concurrency Limits:** GitHub Free tier has concurrency limits (20 jobs). If we have many versions, we might queue. | ||
| 3. **Shared State:** The current script updates `versions.json` after each build. In a matrix, we'd need to aggregate these updates or handle them differently (e.g., one final commit job). | ||
|
|
||
| ## Recommendation | ||
| **Migrate to Matrix.** | ||
| The benefits of parallelism and isolation outweigh the setup complexity. | ||
| The `versions.json` update issue (Issue 35) actually helps here: if we move `versions.json` to Releases, we don't need to commit to git from every job. We can have a final "Release" job that aggregates the successful builds and updates the `versions.json` in the Release assets. | ||
|
|
||
| ## Implementation Strategy | ||
| 1. **Job 1: Check Versions** | ||
| - Runs `check-bun-node.ts`. | ||
| - Outputs a JSON matrix of versions to build. | ||
| 2. **Job 2: Build (Matrix)** | ||
| - `needs: [check-versions]` | ||
| - `strategy: matrix: ${{ fromJson(needs.check-versions.outputs.matrix) }}` | ||
| - Builds and pushes single image. | ||
| 3. **Job 3: Update Release** | ||
| - `needs: [build]` | ||
| - Updates `versions.json` and uploads to GitHub Release. |
This file was deleted.
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 fallback
echo "{}" > versions.jsonwhen the release doesn't exist creates an empty JSON object, which will cause multiple downstream issues:check-bun-node.tswill fail when accessingversionsJson.nodejs[release.major](see related comment)build_updated.shwill fail when trying to extract codename and latest_node_major from the JSONConsider creating a proper initial structure with empty nodejs and bun objects: