mirror of
https://github.com/softprops/action-gh-release.git
synced 2025-10-09 17:06:12 +00:00
Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
|
f38efdea4c | ||
|
cec1a1113b |
3 changed files with 134 additions and 13 deletions
|
@ -39,6 +39,18 @@ describe('util', () => {
|
||||||
'loom',
|
'loom',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
it('handles globs with brace groups containing commas', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('./**/*.{exe,deb,tar.gz}\nfoo,bar'), [
|
||||||
|
'./**/*.{exe,deb,tar.gz}',
|
||||||
|
'foo',
|
||||||
|
'bar',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
it('handles single-line brace pattern correctly', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('./**/*.{exe,deb,tar.gz}'), [
|
||||||
|
'./**/*.{exe,deb,tar.gz}',
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('releaseBody', () => {
|
describe('releaseBody', () => {
|
||||||
it('uses input body', () => {
|
it('uses input body', () => {
|
||||||
|
@ -110,6 +122,52 @@ describe('util', () => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('falls back to body when body_path is missing', () => {
|
||||||
|
assert.equal(
|
||||||
|
releaseBody({
|
||||||
|
github_ref: '',
|
||||||
|
github_repository: '',
|
||||||
|
github_token: '',
|
||||||
|
input_body: 'fallback-body',
|
||||||
|
input_body_path: '__tests__/does-not-exist.txt',
|
||||||
|
input_draft: false,
|
||||||
|
input_prerelease: false,
|
||||||
|
input_files: [],
|
||||||
|
input_overwrite_files: undefined,
|
||||||
|
input_preserve_order: undefined,
|
||||||
|
input_name: undefined,
|
||||||
|
input_tag_name: undefined,
|
||||||
|
input_target_commitish: undefined,
|
||||||
|
input_discussion_category_name: undefined,
|
||||||
|
input_generate_release_notes: false,
|
||||||
|
input_make_latest: undefined,
|
||||||
|
}),
|
||||||
|
'fallback-body',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('returns undefined when body_path is missing and body is not provided', () => {
|
||||||
|
assert.equal(
|
||||||
|
releaseBody({
|
||||||
|
github_ref: '',
|
||||||
|
github_repository: '',
|
||||||
|
github_token: '',
|
||||||
|
input_body: undefined,
|
||||||
|
input_body_path: '__tests__/does-not-exist.txt',
|
||||||
|
input_draft: false,
|
||||||
|
input_prerelease: false,
|
||||||
|
input_files: [],
|
||||||
|
input_overwrite_files: undefined,
|
||||||
|
input_preserve_order: undefined,
|
||||||
|
input_name: undefined,
|
||||||
|
input_tag_name: undefined,
|
||||||
|
input_target_commitish: undefined,
|
||||||
|
input_discussion_category_name: undefined,
|
||||||
|
input_generate_release_notes: false,
|
||||||
|
input_make_latest: undefined,
|
||||||
|
}),
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('parseConfig', () => {
|
describe('parseConfig', () => {
|
||||||
it('parses basic config', () => {
|
it('parses basic config', () => {
|
||||||
|
@ -432,3 +490,36 @@ describe('util', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('parseInputFiles edge cases', () => {
|
||||||
|
it('handles multiple brace groups on same line', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('./**/*.{exe,deb},./dist/**/*.{zip,tar.gz}'), [
|
||||||
|
'./**/*.{exe,deb}',
|
||||||
|
'./dist/**/*.{zip,tar.gz}',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles nested braces', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('path/{a,{b,c}}/file.txt'), ['path/{a,{b,c}}/file.txt']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty comma-separated values', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('foo,,bar'), ['foo', 'bar']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles commas with spaces around braces', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles(' ./**/*.{exe,deb} , file.txt '), [
|
||||||
|
'./**/*.{exe,deb}',
|
||||||
|
'file.txt',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles mixed newlines and commas with braces', () => {
|
||||||
|
assert.deepStrictEqual(parseInputFiles('file1.txt\n./**/*.{exe,deb},file2.txt\nfile3.txt'), [
|
||||||
|
'file1.txt',
|
||||||
|
'./**/*.{exe,deb}',
|
||||||
|
'file2.txt',
|
||||||
|
'file3.txt',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
54
src/util.ts
54
src/util.ts
|
@ -35,23 +35,53 @@ export const uploadUrl = (url: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const releaseBody = (config: Config): string | undefined => {
|
export const releaseBody = (config: Config): string | undefined => {
|
||||||
return (
|
if (config.input_body_path) {
|
||||||
(config.input_body_path && readFileSync(config.input_body_path).toString('utf8')) ||
|
try {
|
||||||
config.input_body
|
const contents = readFileSync(config.input_body_path, 'utf8');
|
||||||
);
|
return contents;
|
||||||
|
} catch (err: any) {
|
||||||
|
console.warn(
|
||||||
|
`⚠️ Failed to read body_path "${config.input_body_path}" (${err?.code ?? 'ERR'}). Falling back to 'body' input.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config.input_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Env = { [key: string]: string | undefined };
|
type Env = { [key: string]: string | undefined };
|
||||||
|
|
||||||
|
const smartSplit = (input: string): string[] => {
|
||||||
|
const result: string[] = [];
|
||||||
|
let current = '';
|
||||||
|
let braceDepth = 0;
|
||||||
|
|
||||||
|
for (const ch of input) {
|
||||||
|
if (ch === '{') {
|
||||||
|
braceDepth++;
|
||||||
|
}
|
||||||
|
if (ch === '}') {
|
||||||
|
braceDepth--;
|
||||||
|
}
|
||||||
|
if (ch === ',' && braceDepth === 0) {
|
||||||
|
if (current.trim()) {
|
||||||
|
result.push(current.trim());
|
||||||
|
}
|
||||||
|
current = '';
|
||||||
|
} else {
|
||||||
|
current += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current.trim()) {
|
||||||
|
result.push(current.trim());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
export const parseInputFiles = (files: string): string[] => {
|
export const parseInputFiles = (files: string): string[] => {
|
||||||
return files.split(/\r?\n/).reduce<string[]>(
|
return files
|
||||||
(acc, line) =>
|
.split(/\r?\n/)
|
||||||
acc
|
.flatMap((line) => smartSplit(line))
|
||||||
.concat(line.split(','))
|
.filter((pat) => pat.trim() !== '');
|
||||||
.filter((pat) => pat)
|
|
||||||
.map((pat) => pat.trim()),
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseConfig = (env: Env): Config => {
|
export const parseConfig = (env: Env): Config => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue