Skip to content

Commit

Permalink
fix(build): use known working node version
Browse files Browse the repository at this point in the history
- fix npm links fallback
- fix npm links handling for installer too
- use matching npm version for node version when building
- GitHub workflows: allow triggering of installer creation without tagging
  • Loading branch information
Mairu committed Nov 26, 2023
1 parent e4e67cd commit 08874a9
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 66 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-*'
workflow_dispatch:


jobs:
run-build:
Expand All @@ -23,7 +25,14 @@ jobs:
run: Copy-Item (Get-Command node.exe | Select-Object -ExpandProperty Definition) .
- run: npm test
- run: npm run build
- name: Archive build artifact
if: github.ref_type == 'branch'
uses: actions/upload-artifact@v3
with:
name: Installer
path: "build/out/NodistSetup-*.exe"
- name: Create release draft
if: github.ref_type == 'tag'
uses: ncipollo/release-action@v1
with:
artifacts: "build/out/NodistSetup-*.exe"
Expand Down
40 changes: 10 additions & 30 deletions build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var fs = require('fs');
var mkdirp = require('mkdirp');
var ncp = require('ncp');
var path = require('path');
var semver = require('semver');
var recursiveReaddir = require('recursive-readdir');
var request = require('request');
var rimraf = require('rimraf');
Expand Down Expand Up @@ -83,6 +84,7 @@ var npm = new (require('../lib/npm'))({nodistDir: stagingDir});
//default npm version to the latest at the time of writing
var npmVersion = '6.14.16';
var nodeVersion = '16.15.0';
var maxNodeMainVersion = '^20';

var versionPathx86 = '';
var versionPathx64 = '';
Expand All @@ -102,31 +104,14 @@ console.log('Welcome to the Nodist Builder');
console.log(' before going further we need to prep our staging folder');

//defining helper functions
function getLatestNodeVersionFor(nodeVersions, fileType) {
function getLatestUsableNodeVersionFor(nodeVersions, fileType) {
for (var key in nodeVersions) {
if (nodeVersions[key].files.includes(fileType)) {
return nodeVersions[key].version;
if (nodeVersions[key].files.includes(fileType) && semver.satisfies(nodeVersions[key].version, maxNodeMainVersion)) {
return { nodeVersion: nodeVersions[key].version, npmVersion: nodeVersions[key].npm };
}
}
}

async function resolveLinkedWorkspaces(dirPath) {
let movedLinks = 0;
const files = await fs.readdirAsync(dirPath, { withFileTypes: true });
const dirPromises = [];
for (const file of files) {
const filePath = path.join(dirPath, file.name);
if (file.isSymbolicLink()) {
const linkTarget = await fs.readlinkAsync(filePath);
await fs.renameAsync(path.join(dirPath, linkTarget), filePath);
movedLinks++;
} else if (file.isDirectory()) {
dirPromises.push(resolveLinkedWorkspaces(filePath));
}
}
return (await Promise.all(dirPromises)).reduce((sum, num) => sum + num, movedLinks);
}

//start by clearing the staging and tmp folders
P.all([
rimraf(outDir),
Expand Down Expand Up @@ -217,7 +202,7 @@ P.all([
});
})
.then(function(res){
nodeVersion = getLatestNodeVersionFor(res.body, 'win-x86-exe');
({ nodeVersion, npmVersion } = getLatestUsableNodeVersionFor(res.body, 'win-x86-exe'));
nodeLatestUrlx86 = nodeLatestUrlx86.replace('VERSION',nodeVersion);
nodeLatestUrlx64 = nodeLatestUrlx64.replace('VERSION',nodeVersion);
console.log('Latest version of Node ' + nodeVersion);
Expand Down Expand Up @@ -253,14 +238,9 @@ P.all([
);
})
.then(function(){
console.log('Figure out the latest version of NPM');
return npm.latestVersion();
})
.then(function(version){
npmVersion = version;
var downloadLink = npm.downloadUrl(version);
console.log('Determined latest NPM as ' + npmVersion);
console.log('Downloading latest NPM from ' + downloadLink);
var downloadLink = npm.downloadUrl(npmVersion);
console.log('Determined matching NPM as ' + npmVersion);
console.log('Downloading matching NPM from ' + downloadLink);
return Promise.resolve()
.then(() => mkdirp(stagingNpmDir+'/'+npmVersion.replace('v','')))
.then(() => {
Expand Down Expand Up @@ -291,7 +271,7 @@ P.all([
})
.then(function() {
console.log('Installation complete');
return resolveLinkedWorkspaces(path.join(stagingNpmDir, npmVersion.replace('v', ''), 'node_modules'));
return helper.resolveLinkedWorkspaces(path.join(stagingNpmDir, npmVersion.replace('v', '')), false);
})
.then(function(movedLinks) {
if (movedLinks) {
Expand Down
52 changes: 52 additions & 0 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ var path = require('path');
var promisePipe = require('promisepipe');
var ProgressBar = require('progress');
var request = require('request');
const P = require('bluebird');
var debug = require('debug')('nodist:build')

//make some promising APIs
P.promisifyAll(fs);

/**
* Copy File
* @param {string} source
Expand Down Expand Up @@ -141,3 +145,51 @@ exports.downloadFileStream = function downloadFileStream(url) {
});
return req
}

/**
* Npm version >= 18 using symlinks that do not work in windows and have to be fixed
* this function replace the broken symlinks with NTFS junction or move the directory if junctions are not supported
*
* @param {string} dirPath
* @param {boolean} preferSymlink
* @returns {Promise<number>} number of changed links
*/
exports.resolveLinkedWorkspaces = async function resolveLinkedWorkspaces(dirPath, preferSymlink = true) {
let fixedLinks = 0;
const packageLockJson = JSON.parse(fs.readFileSync(path.join(dirPath, 'package-lock.json')).toString());
await Promise.all(Object.entries(packageLockJson.packages)
.filter(([pkgPath, pkg]) => pkg.link === true)
.map(async ([pkgPath, pkg]) => {

const linkPath = path.join(dirPath, pkgPath);


if (await fs.accessAsync(linkPath, fs.constants.F_OK).then(() => true).catch(() => false)) {
await fs.unlinkAsync(linkPath);
}

let linkCreated = false;
if (preferSymlink) {
const linkTarget = path.join(
...pkgPath.split('/').slice(0, -1).map(() => '..'),
pkg.resolved
);
debug('Create symlink for ', linkPath, 'with target', linkTarget);
try {
await fs.symlinkAsync(linkTarget, linkPath, 'junction');
linkCreated = true;
} catch (e) {
debug('Link ', linkPath, 'could not be created');
}
}
if (!linkCreated) {
const from = path.join(dirPath, pkg.resolved);
debug('Move', from, 'to', linkPath);
await fs.renameAsync(from, linkPath);
}

fixedLinks++;
}));

return fixedLinks;
};
37 changes: 1 addition & 36 deletions lib/npm.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,6 @@ module.exports = npmist

var NPMIST = npmist.prototype

/**
* Npm version >= 18 using symlinks that do not work in windows and have to be fixed
* this function replace the broken symlinks with NTFS junction or move the directory if junctions are not supported
*
* @param {string} dirPath
* @returns {Promise<number>} number of changed links
*/
async function resolveLinkedWorkspaces(dirPath) {
let fixedLinks = 0;
const packageLockJson = JSON.parse(fs.readFileSync(path.join(dirPath, 'package-lock.json')).toString());
await Promise.all(Object.entries(packageLockJson.packages)
.filter(([pkgPath, pkg]) => pkg.link === true)
.map(async ([pkgPath, pkg]) => {
const linkTarget = path.join(
...pkgPath.split('/').slice(0, -1).map(() => '..'),
pkg.resolved
);
const linkPath = path.join(dirPath, pkgPath);

debug('Create symlink for ', linkPath, 'with target', linkTarget);
if (await fs.accessAsync(linkPath, fs.constants.F_OK).then(() => true).catch(() => false)) {
await fs.unlinkAsync(linkPath);
}

try {
await fs.symlinkAsync(linkTarget, linkPath, 'junction');
} catch (e) {
await fs.renameAsync(path.join(dirPath, linkTarget), linkPath);
}
fixedLinks++;
}));

return fixedLinks;
}

/**
* List available NPM versions
* @return {string}
Expand Down Expand Up @@ -331,7 +296,7 @@ NPMIST.install = function(v,done){
.then(() => {
if (semver.gte(version, '8.0.0')) {
debug('Fix symlinks for npm version >= 8');
return resolveLinkedWorkspaces(path.join(archivePath))
return buildHelper.resolveLinkedWorkspaces(path.join(archivePath))
.then(fixedLinks => {
debug(`Fixed ${fixedLinks} symlinks for npm node_modules`);
});
Expand Down

0 comments on commit 08874a9

Please sign in to comment.