Skip to content

Commit 3e35ffe

Browse files
committed
experiments
1 parent 621b9bf commit 3e35ffe

9 files changed

Lines changed: 424 additions & 43 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Output Test - Main Marker
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
main-output:
8+
runs-on: ubuntu-latest
9+
outputs:
10+
main_marker: ${{ steps.monitor.outputs.main_marker }}
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Start monitor
15+
id: monitor
16+
uses: ./.
17+
with:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
20+
- name: Wait for polls (30s total)
21+
run: sleep 30
22+
23+
main-output-diag:
24+
runs-on: ubuntu-latest
25+
needs: [main-output]
26+
if: always()
27+
steps:
28+
- name: Assert main marker output
29+
run: |
30+
echo "main_marker=${{ needs.main-output.outputs.main_marker }}"
31+
if [ "${{ needs.main-output.outputs.main_marker }}" != "main-marker" ]; then
32+
echo "Expected main-marker from main step"
33+
exit 1
34+
fi
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Output Test - Payload Size
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
output-payload:
8+
runs-on: ubuntu-latest
9+
outputs:
10+
post_state_json_bytes: ${{ steps.monitor.outputs.post_state_json_bytes }}
11+
post_poll_log_json_bytes: ${{ steps.monitor.outputs.post_poll_log_json_bytes }}
12+
post_poll_log_entries: ${{ steps.monitor.outputs.post_poll_log_entries }}
13+
post_github_output_bytes: ${{ steps.monitor.outputs.post_github_output_bytes }}
14+
post_github_output_path: ${{ steps.monitor.outputs.post_github_output_path }}
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Start monitor
19+
id: monitor
20+
uses: ./.
21+
with:
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
24+
- name: Wait for polls (30s total)
25+
run: sleep 30
26+
27+
output-payload-diag:
28+
runs-on: ubuntu-latest
29+
needs: [output-payload]
30+
if: always()
31+
steps:
32+
- name: Report output payload sizes
33+
run: |
34+
echo "post_state_json_bytes=${{ needs.output-payload.outputs.post_state_json_bytes }}"
35+
echo "post_poll_log_json_bytes=${{ needs.output-payload.outputs.post_poll_log_json_bytes }}"
36+
echo "post_poll_log_entries=${{ needs.output-payload.outputs.post_poll_log_entries }}"
37+
echo "post_github_output_bytes=${{ needs.output-payload.outputs.post_github_output_bytes }}"
38+
echo "post_github_output_path=${{ needs.output-payload.outputs.post_github_output_path }}"
39+
40+
- name: Assert GITHUB_OUTPUT size is numeric
41+
run: |
42+
bytes="${{ needs.output-payload.outputs.post_github_output_bytes }}"
43+
if ! echo "$bytes" | grep -Eq '^[0-9]+$'; then
44+
echo "Expected numeric bytes, got: $bytes"
45+
exit 1
46+
fi
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Output Test - Poll Log File
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
poll-log-file:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
12+
- name: Start monitor
13+
id: monitor
14+
uses: ./.
15+
with:
16+
token: ${{ secrets.GITHUB_TOKEN }}
17+
18+
- name: Generate a few API calls
19+
env:
20+
TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
REPO: ${{ github.repository }}
22+
run: |
23+
for i in $(seq 1 3); do
24+
echo "--- core call $i ---"
25+
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
26+
-D - \
27+
-H "Authorization: Bearer $TOKEN" \
28+
"https://api.github.com/repos/${REPO}" \
29+
2>&1 | grep -iE '(^HTTP|x-ratelimit)'
30+
sleep 2
31+
done
32+
33+
- name: Wait for polls (30s total)
34+
run: sleep 30
35+
36+
- name: Snapshot poll log to workspace
37+
run: |
38+
poll_log_path="$RUNNER_TEMP/github-api-usage-monitor/poll-log.jsonl"
39+
if [ ! -f "$poll_log_path" ]; then
40+
echo "Poll log not found at: $poll_log_path"
41+
exit 1
42+
fi
43+
cp "$poll_log_path" poll-log.jsonl
44+
echo "Poll log size: $(wc -c < poll-log.jsonl) bytes"
45+
46+
- name: Upload poll log artifact
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: poll-log-jsonl
50+
path: poll-log.jsonl
51+
if-no-files-found: error
52+
53+
poll-log-file-diag:
54+
runs-on: ubuntu-latest
55+
needs: [poll-log-file]
56+
if: always()
57+
steps:
58+
- name: Download poll log artifact
59+
uses: actions/download-artifact@v4
60+
with:
61+
name: poll-log-jsonl
62+
63+
- name: Inspect poll log
64+
run: |
65+
if [ ! -f poll-log.jsonl ]; then
66+
echo "poll-log.jsonl not found after download"
67+
exit 1
68+
fi
69+
echo "Downloaded poll log size: $(wc -c < poll-log.jsonl) bytes"
70+
echo "First 3 lines:"
71+
head -n 3 poll-log.jsonl
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Output Test - Post Marker
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
post-output:
8+
runs-on: ubuntu-latest
9+
outputs:
10+
post_marker: ${{ steps.monitor.outputs.post_marker }}
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Start monitor
15+
id: monitor
16+
uses: ./.
17+
with:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
20+
- name: Wait for polls (30s total)
21+
run: sleep 30
22+
23+
post-output-diag:
24+
runs-on: ubuntu-latest
25+
needs: [post-output]
26+
if: always()
27+
steps:
28+
- name: Assert post marker output
29+
run: |
30+
echo "post_marker=${{ needs.post-output.outputs.post_marker }}"
31+
if [ "${{ needs.post-output.outputs.post_marker }}" != "post-marker" ]; then
32+
echo "Expected post-marker from post step"
33+
exit 1
34+
fi

action.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ outputs:
1717
description: 'Finalized reducer state as a JSON string'
1818
poll_log_json:
1919
description: 'Poll log entries as a JSON array string'
20+
main_marker:
21+
description: 'Marker value set by the main step'
22+
post_marker:
23+
description: 'Marker value set by the post step'
24+
post_state_json_bytes:
25+
description: 'Byte length of state_json output (post)'
26+
post_poll_log_json_bytes:
27+
description: 'Byte length of poll_log_json output (post)'
28+
post_poll_log_entries:
29+
description: 'Poll log entry count observed in post'
30+
post_poll_log_path:
31+
description: 'Poll log file path observed in post'
32+
post_github_output_bytes:
33+
description: 'GITHUB_OUTPUT size in bytes observed in post (before size output write)'
34+
post_github_output_path:
35+
description: 'GITHUB_OUTPUT path observed in post'
2036

2137
runs:
2238
using: node20

dist/main.js

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27831,6 +27831,42 @@ var __webpack_exports__ = {};
2783127831

2783227832
;// CONCATENATED MODULE: external "os"
2783327833
const external_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("os");
27834+
;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/utils.js
27835+
// We use any as a valid input type
27836+
/* eslint-disable @typescript-eslint/no-explicit-any */
27837+
/**
27838+
* Sanitizes an input into a string so it can be passed into issueCommand safely
27839+
* @param input input to sanitize into a string
27840+
*/
27841+
function utils_toCommandValue(input) {
27842+
if (input === null || input === undefined) {
27843+
return '';
27844+
}
27845+
else if (typeof input === 'string' || input instanceof String) {
27846+
return input;
27847+
}
27848+
return JSON.stringify(input);
27849+
}
27850+
/**
27851+
*
27852+
* @param annotationProperties
27853+
* @returns The command properties to send with the actual annotation command
27854+
* See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646
27855+
*/
27856+
function utils_toCommandProperties(annotationProperties) {
27857+
if (!Object.keys(annotationProperties).length) {
27858+
return {};
27859+
}
27860+
return {
27861+
title: annotationProperties.title,
27862+
file: annotationProperties.file,
27863+
line: annotationProperties.startLine,
27864+
endLine: annotationProperties.endLine,
27865+
col: annotationProperties.startColumn,
27866+
endColumn: annotationProperties.endColumn
27867+
};
27868+
}
27869+
//# sourceMappingURL=utils.js.map
2783427870
;// CONCATENATED MODULE: ./node_modules/@actions/core/lib/command.js
2783527871

2783627872

@@ -27869,7 +27905,7 @@ const external_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta
2786927905
*/
2787027906
function command_issueCommand(command, properties, message) {
2787127907
const cmd = new Command(command, properties, message);
27872-
process.stdout.write(cmd.toString() + os.EOL);
27908+
process.stdout.write(cmd.toString() + external_os_namespaceObject.EOL);
2787327909
}
2787427910
function command_issue(name, message = '') {
2787527911
command_issueCommand(name, {}, message);
@@ -27909,13 +27945,13 @@ class Command {
2790927945
}
2791027946
}
2791127947
function escapeData(s) {
27912-
return toCommandValue(s)
27948+
return utils_toCommandValue(s)
2791327949
.replace(/%/g, '%25')
2791427950
.replace(/\r/g, '%0D')
2791527951
.replace(/\n/g, '%0A');
2791627952
}
2791727953
function escapeProperty(s) {
27918-
return toCommandValue(s)
27954+
return utils_toCommandValue(s)
2791927955
.replace(/%/g, '%25')
2792027956
.replace(/\r/g, '%0D')
2792127957
.replace(/\n/g, '%0A')
@@ -27940,16 +27976,16 @@ function file_command_issueFileCommand(command, message) {
2794027976
if (!filePath) {
2794127977
throw new Error(`Unable to find environment variable for file command ${command}`);
2794227978
}
27943-
if (!fs.existsSync(filePath)) {
27979+
if (!external_fs_namespaceObject.existsSync(filePath)) {
2794427980
throw new Error(`Missing file at path: ${filePath}`);
2794527981
}
27946-
fs.appendFileSync(filePath, `${toCommandValue(message)}${os.EOL}`, {
27982+
external_fs_namespaceObject.appendFileSync(filePath, `${utils_toCommandValue(message)}${external_os_namespaceObject.EOL}`, {
2794727983
encoding: 'utf8'
2794827984
});
2794927985
}
2795027986
function file_command_prepareKeyValueMessage(key, value) {
27951-
const delimiter = `ghadelimiter_${crypto.randomUUID()}`;
27952-
const convertedValue = toCommandValue(value);
27987+
const delimiter = `ghadelimiter_${external_crypto_namespaceObject.randomUUID()}`;
27988+
const convertedValue = utils_toCommandValue(value);
2795327989
// These should realistically never happen, but just in case someone finds a
2795427990
// way to exploit uuid generation let's not allow keys or values that contain
2795527991
// the delimiter.
@@ -27959,7 +27995,7 @@ function file_command_prepareKeyValueMessage(key, value) {
2795927995
if (convertedValue.includes(delimiter)) {
2796027996
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
2796127997
}
27962-
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
27998+
return `${key}<<${delimiter}${external_os_namespaceObject.EOL}${convertedValue}${external_os_namespaceObject.EOL}${delimiter}`;
2796327999
}
2796428000
//# sourceMappingURL=file-command.js.map
2796528001
;// CONCATENATED MODULE: external "path"
@@ -30581,10 +30617,10 @@ function getBooleanInput(name, options) {
3058130617
function setOutput(name, value) {
3058230618
const filePath = process.env['GITHUB_OUTPUT'] || '';
3058330619
if (filePath) {
30584-
return issueFileCommand('OUTPUT', prepareKeyValueMessage(name, value));
30620+
return file_command_issueFileCommand('OUTPUT', file_command_prepareKeyValueMessage(name, value));
3058530621
}
30586-
process.stdout.write(os.EOL);
30587-
issueCommand('set-output', { name }, toCommandValue(value));
30622+
process.stdout.write(external_os_namespaceObject.EOL);
30623+
command_issueCommand('set-output', { name }, utils_toCommandValue(value));
3058830624
}
3058930625
/**
3059030626
* Enables or disables the echoing of commands into stdout for the rest of the step.
@@ -30754,6 +30790,9 @@ function getIDToken(aud) {
3075430790
// -----------------------------------------------------------------------------
3075530791
function run() {
3075630792
info('Monitor start is handled by the pre hook. Main step is a no-op.');
30793+
const mainMarker = 'main-marker';
30794+
setOutput('main_marker', mainMarker);
30795+
info(`Main marker output set: ${mainMarker}`);
3075730796
}
3075830797
// -----------------------------------------------------------------------------
3075930798
// Run

0 commit comments

Comments
 (0)