Skip to content

Conversation

@ItsHarta
Copy link

@ItsHarta ItsHarta commented Jan 15, 2026

Description

Currently, all docker images for nodejs depends on the experimental MUSL builds. This PR is a refined attempt to decouple (at least) security releases from the unofficial MUSL build dependency. This PR attempts to refine the automated pipeline by checking several things:

  1. If MUSL build is available, then either update everything (new release) or alpine-only (catch-up release)
  2. If MUSL is not available for a security update, attempt to update the non-alpine variants
  3. Else, skip the version and wait until MUSL build is available.

Assumptions:

  1. Only skips alpine variant. Currently this is the only variant that uses MUSL.
  2. Alpine versions are always a. behind mainline, or b. equal to mainline. This means releases are always either alpine catch-up, or a new release.
  3. Only skips alpine for security releases. Non-security releases are unchanged.

Motivation and Context

The automated release currently checks for MUSL builds and blocks the version update for all variants if the MUSL build is missing. Since MUSL variant is experimental, this causes delays and issues (esp. for security releases).

Further context and attributions:
Original idea at #2330 (comment) by @MikeMcC399
Initial attempt at #2348 by @bmuenzenmeyer

Testing Details

Example Output(if appropriate)

Types of changes

  • Documentation
  • Version change (Update, remove or add more Node.js versions)
  • Variant change (Update, remove or add more variants, or versions of variants)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Other (none of the above)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING.md document.
  • All new and existing tests passed.

Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
@mcollina
Copy link
Member

How is the catch-up release triggered?

@ItsHarta
Copy link
Author

How is the catch-up release triggered?

This works largely by implicitly trusting that standard release >= alpine release. So releases are either a standard or catch-up, I do not handle case where alpine is ahead.

I split the new version checking for non-alpine and alpine instead of hardcoding the first option for each major release.
ItsHarta/docker-node/build-automation.mjs#checkIfThereAreNewVersions()

      // Checks current version
      // This checks for non-alpine
      const standardVersion = baseVersions.find(v => !v.startsWith("alpine"));
      const { stdout: standardVersionOutput } = await exec(`. ./functions.sh && get_full_version ./${supportedVersion}/${standardVersion}`, { shell: "bash" });

      // This checks for alpine
      const alpineVersion = baseVersions.find(v => v.startsWith("alpine"));
      const { stdout: alpineVersionOutput } = await exec(`. ./functions.sh && get_full_version ./${supportedVersion}/${alpineVersion}`, { shell: "bash" });
      
      const fullVersion = { main : standardVersionOutput.trim(), alpine: alpineVersionOutput.trim() };
      console.log(`${supportedVersion}: main=${fullVersion.main}, alpine=${fullVersion.alpine}`);

      latestSupportedVersions[supportedVersion] = {
        fullVersion: fullVersion.main,
        alpineVersion: fullVersion.alpine,
        // Assumption: standardVersion is always equal or ahead of alpineVersion
        // So if the version differs, it must be always an alpine catch-up release
        alpineIsBehind: fullVersion.main !== fullVersion.alpine
      };

As i said before, this works on assumption that standardVersion is always ahead or equal to alpineVersion. If they differ, then it is guaranteed an alpine catch-up, hence alpineIsBehind=true.

This persistent flag will be used later on below to determine whether this version is alpine-only (catch-up) or a standard release.

      // Catch-up const checks for the whether current alpine is behind
      const isCatchup = supported.alpineIsBehind && newAlpine && availableFullVersion === supported.fullVersion;

      // Assumption: mainline/standard is always equal or ahead of alpine
      // So if new standard release is available, then alpineOnly is always false (new release/non-catchup)
      if (newMainline || isCatchup) {
        filteredNewerVersions[availableMajor] = { 
          fullVersion: availableFullVersion, 
          alpineOnly: !newMainline 
        };
      }

Later on, this alpineOnly flag can be used to scope the update.sh to alpine only by doing a simple updateScope = alpineOnly ? "alpine" : "";

Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
@ItsHarta

This comment was marked as resolved.

Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
Signed-off-by: Harta Angkasa <24356946+ItsHarta@users.noreply.github.com>
@ItsHarta
Copy link
Author

Additional fixes:

  1. Change variant check functions.sh#get_variants to prefix regex ^${variant2}.
    This allows alpine to match alpine3.22 and alpine3.23 in the actual directory structure. Also to accommodate sub-variants (such as -slim)

  2. Preserve existing YARN_VERSION when -s is specified.
    Seems like when the -s is specified, the yarn version is not fetched. Causes the ENV YARN_VERSION=0.0.0 line to carry over to the final dockerfile

update.sh
68  | if [ "${SKIP}" != true ]; then
69  |   yarnVersion="$(curl -sSL --compressed https://yarnpkg.com/latest-version)"
70  | fi
...
179 | if [ "${SKIP}" != true ]; then
180 |  sed -Ei -e 's/^(ENV YARN_VERSION)=.*/\1='"${yarnVersion}"'/' "${dockerfile}-tmp"
181 | fi
  1. Fix the broken -s updating all variants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants