-
Notifications
You must be signed in to change notification settings - Fork 0
/
action.yml
131 lines (106 loc) · 4.04 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
129
130
131
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
];
// Store or overwrite the key with its latest occurrence
acc[key] = value ? `${key}=${value}` : 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);