-
Notifications
You must be signed in to change notification settings - Fork 0
/
action.yml
128 lines (102 loc) · 4.06 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
name: 'Format string'
description: 'Format a string'
inputs:
string:
description: 'The string to format. Can be empty or multiple lines.'
required: true
input-separator:
description: 'The separator to use when splitting input to multiple lines.'
required: false
default: '\n'
output-separator:
description: 'The separator to use for the generated output string.'
required: false
default: ' '
deduplicate:
description: 'Whether to deduplicate the lines before joining. Always done if mode is "args".'
required: false
default: 'false'
sort:
description: 'Whether to sort the lines before joining.'
required: false
default: 'false'
mode:
description: 'The mode to use for formatting. Set to "args" to deduplicate key-value pairs.'
required: false
default: 'default'
outputs:
string:
description: 'The formatted string.'
value: ${{ steps.format.outputs.result }}
runs:
using: composite
steps:
- name: 'Format string'
id: format
uses: actions/github-script@v7
env:
INPUT_SEPARATOR: ${{ inputs.input-separator }}
OUTPUT_SEPARATOR: ${{ inputs.output-separator }}
DEDUPLICATE: ${{ inputs.deduplicate }}
SORT: ${{ inputs.sort }}
MODE: ${{ inputs.mode }}
STRING: ${{ inputs.string }}
with:
result-encoding: 'string'
#language=javascript
script: |
const MODE_ARGS = 'args';
const mode = String(process.env.MODE);
const deduplicate = MODE_ARGS === mode
|| (process.env.DEDUPLICATE !== 'false' && Boolean(process.env.DEDUPLICATE));
const sort = process.env.SORT !== 'false' && Boolean(process.env.SORT);
const inputString = process.env.STRING?.trim() ?? '';
const parseSeparator = (separator) => {
if (!separator.includes('\\')) {
return separator;
}
try {
return JSON.parse(`"${separator}"`);
} catch (e) {
// Fallback to original if it's not a valid JSON string
core.warning(`Invalid escape sequences in separator: ${e.message}`);
return separator;
}
};
// Make sure the separators are correctly parsed if they contain escape sequences
const inputSeparator = parseSeparator(String(process.env.INPUT_SEPARATOR));
const outputSeparator = parseSeparator(String(process.env.OUTPUT_SEPARATOR));
if (!inputString) {
return '';
}
let lines = inputString.split(inputSeparator).map((line) => line.trim()).filter(Boolean);
core.debug(`Split input to ${lines.length} lines: ${JSON.stringify(lines)}`);
// Handle `args` mode to keep last occurrence of key-value pairs
if (MODE_ARGS === mode) {
const uniqueArgs = lines.reduce((acc, arg) => {
// Check if it's a key-value pair
const [key, value] = arg.includes('=')
? arg.split('=')
: [arg, null];
// Unwrap quotes from value
const unwrappedValue = value?.replace(/^"(.*)"$/, '$1');
// Store or overwrite the key with its latest occurrence
acc[key] = unwrappedValue ? `${key}=${unwrappedValue}` : key;
return acc;
}, {});
// Convert the result back into an array of unique arguments
lines = Object.values(uniqueArgs);
core.debug(`Lines after args deduplication: ${JSON.stringify(lines)}`);
}
// Optionally deduplicate
if (deduplicate) {
lines = [...new Set(lines)];
core.debug(`Lines after deduplication: ${JSON.stringify(lines)}`);
}
// Optionally sort
if (sort) {
lines.sort();
core.debug(`Lines after sorting: ${JSON.stringify(lines)}`);
}
// Join result by output separator and set output
return lines.join(outputSeparator);