-
Notifications
You must be signed in to change notification settings - Fork 0
Description
makeConfig() fails to parse CLI arguments in GitHub Actions CI environments
Summary
The makeConfig() function from lino-arguments fails to parse CLI arguments in GitHub Actions CI environments, returning empty default values instead of the actual arguments passed. This causes scripts to fail with "Missing required arguments" errors even when arguments are correctly provided.
Environment
- Platform: GitHub Actions CI (Ubuntu runners)
- Loading method: Dynamic loading via
use-mfrom unpkg - Node.js version: v20.x (GitHub Actions default)
Reproducible Example
Minimal failing script
#!/usr/bin/env node
// Load use-m dynamically
const { use } = eval(
await (await fetch('https://unpkg.com/use-m/use.js')).text()
);
const { makeConfig } = await use('lino-arguments');
// Configure CLI arguments using lino-arguments
const config = makeConfig({
yargs: ({ yargs, getenv }) =>
yargs
.option('version', {
type: 'string',
description: 'Version to process',
default: getenv('VERSION') || '',
})
.option('repository', {
type: 'string',
description: 'Repository name',
default: getenv('REPOSITORY') || '',
})
.help()
.strict(),
});
const version = config.version;
const repository = config.repository;
if (!version || !repository) {
console.error('Error: Missing required arguments');
process.exit(1);
}
console.log('✅ Arguments parsed successfully!');How to run
# This works locally on most machines
node script.mjs --version "0.8.36" --repository "link-foundation/test-anywhere"
# This fails in GitHub Actions CI with exit code 1
# Even though the command is identical and arguments are passed correctlyExpected Behavior
When run with CLI arguments:
node script.mjs --version "0.8.36" --repository "link-foundation/test-anywhere"The script should:
- Parse
--versionas "0.8.36" - Parse
--repositoryas "link-foundation/test-anywhere" - Print "✅ Arguments parsed successfully!"
- Exit with code 0
Actual Behavior in GitHub Actions CI
When run with the same command in GitHub Actions:
makeConfig()returns empty strings (thegetenv()defaults)- Arguments are NOT parsed from CLI
- Script exits with code 1 due to missing required arguments
- No stdout produced
- No clear error message about why parsing failed
Evidence from CI logs
From GitHub Actions run logs:
{
"finalExitCode": 1,
"stdoutLength": 0,
"stderrLength": 4413,
"stdoutPreview": ""
}The script produces no output and exits early with code 1, indicating that makeConfig() silently failed to parse arguments.
Real-World Impact
This issue affected production releases in the test-anywhere repository:
- Initial occurrence: PR #115 introduced
lino-argumentsto release scripts - First failure: Release v0.8.33 failed (Issue #116) - workflow was suspected but was actually correct
- Continued failures: Multiple releases (v0.8.34, v0.8.35, v0.8.36) had broken release notes
- Root cause discovered: Issue #122 identified that
format-release-notes.mjswas failing due tolino-arguments
Affected scripts
scripts/format-release-notes.mjs(confirmed failing)scripts/create-github-release.mjs(fixed in PR #119)scripts/format-github-release.mjs(fixed in PR #119)scripts/publish-to-npm.mjs(failed silently, optional args masked the issue)
Investigation Timeline
- v0.8.36 release (December 11, 2025): Release notes not formatted properly
- Issue #122 opened: Reported missing PR links and unformatted markdown in releases
- CI logs analysis: Downloaded logs from run 20126234140, found exit code 1 with no output
- Local testing: Script worked locally but examination of CI behavior showed parsing failure
- PR #119 precedent: Previous fix for same issue in other scripts (replaced
lino-argumentswith manual parsing) - PR #123 implementation: Replaced
lino-argumentsinformat-release-notes.mjswith manual parsing
Full case study: link-foundation/test-anywhere#123
Workaround
Replace lino-arguments with manual argument parsing:
// Manual argument parser - supports both --arg=value and --arg value formats
function parseArgs(argv) {
const args = {};
for (let i = 2; i < argv.length; i++) {
const arg = argv[i];
if (arg.startsWith('--')) {
const key = arg.slice(2);
if (key.includes('=')) {
const [k, v] = key.split('=');
args[k] = v;
} else if (i + 1 < argv.length && !argv[i + 1].startsWith('--')) {
args[key] = argv[i + 1];
i++;
} else {
args[key] = true;
}
}
}
return args;
}
const args = parseArgs(process.argv);
const version = args.version || process.env.VERSION || '';
const repository = args.repository || process.env.REPOSITORY || '';This workaround:
- ✅ Works reliably in all environments (local, CI, containers)
- ✅ Supports both
--arg=valueand--arg valueformats - ✅ Falls back to environment variables
- ✅ Uses only standard Node.js APIs (no external dependencies)
- ✅ Easy to debug and maintain
Suggested Fix
Possible root causes to investigate:
- Shell interaction: The way
yargsinteracts withprocess.argvin GitHub Actions' shell environment - Dynamic loading timing: Whether
use-mloading affects argument parsing initialization - Environment detection: Whether
lino-argumentshas environment detection that behaves differently in CI - stdin/stdout/stderr: Whether CI's non-interactive terminal affects parsing
- yargs version/config: Whether the yargs configuration used by
lino-argumentshas CI-specific issues
Suggested investigation steps:
- Add debug logging to
makeConfig()to show:- Raw
process.argvat entry point - Arguments after yargs parsing
- Any errors/warnings from yargs
- Raw
- Test specifically in GitHub Actions environment with debug output
- Compare behavior between local and CI environments with identical Node.js versions
- Check if the issue is specific to
use-mdynamic loading or affects npm-installed packages too
Related Issues
- test-anywhere #116: First release failure attributed to workflow (actual root cause was
lino-arguments) - test-anywhere #118: Release failure, led to PR #119 fixing some scripts
- test-anywhere #122: Release notes formatting, led to PR #123 fixing remaining script
Additional Context
From PR #119 investigation:
The
lino-argumentslibrary'smakeConfigfunction failed to parse CLI arguments in GitHub Actions environments, returning empty default values instead of the actual arguments. This caused release scripts to fail with "Missing required arguments" errors.
The issue appears to be systematic rather than a one-time occurrence, affecting multiple scripts across multiple releases.
References:
- Test-anywhere issue #122: Fix release notes in GitHub releases test-anywhere#122
- Test-anywhere PR #123 (fix): fix: replace lino-arguments in format-release-notes.mjs test-anywhere#123
- Test-anywhere PR #119 (earlier fix): fix: replace lino-arguments with manual CLI argument parsing test-anywhere#119
- Failed CI run: https://github.com/link-foundation/test-anywhere/actions/runs/20126234140