Skip to content

Commit eac5084

Browse files
dgibbs64Copilot
andcommitted
feat(labeler): implement SteamCMD Linux support check
* Added a new function `runSteamCmdLinuxCheck` to assess Linux platform support using SteamCMD. * Enhanced existing logic to incorporate SteamCMD results alongside Steam API checks. * Updated comments to clarify the distinction between server tool AppIDs and client platform support. * Improved error handling and logging for SteamCMD assessments. Co-authored-by: Copilot <copilot@github.com>
1 parent 29e7f26 commit eac5084

1 file changed

Lines changed: 124 additions & 6 deletions

File tree

.github/workflows/labeler.yml

Lines changed: 124 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ jobs:
8383
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8484
with:
8585
script: |
86+
const { execFileSync } = require('node:child_process');
8687
const owner = context.repo.owner;
8788
const repo = context.repo.repo;
8889
const eventName = context.eventName;
@@ -227,6 +228,88 @@ jobs:
227228
return false;
228229
}
229230
231+
function runSteamCmdLinuxCheck(appId) {
232+
if (!appId) {
233+
return { status: 'skipped', reason: 'No Steam AppID provided.' };
234+
}
235+
236+
const image = 'gameservermanagers/steamcmd:latest';
237+
const args = [
238+
'run',
239+
'--rm',
240+
'-e',
241+
'PUID=1001',
242+
'-e',
243+
'PGID=1001',
244+
image,
245+
'+@ShutdownOnFailedCommand',
246+
'1',
247+
'+@NoPromptForPassword',
248+
'1',
249+
'+login',
250+
'anonymous',
251+
'+app_info_update',
252+
'1',
253+
'+app_info_print',
254+
String(appId),
255+
'+quit',
256+
];
257+
258+
try {
259+
const output = execFileSync('docker', args, {
260+
encoding: 'utf8',
261+
stdio: ['ignore', 'pipe', 'pipe'],
262+
timeout: 120000,
263+
maxBuffer: 10 * 1024 * 1024,
264+
});
265+
266+
const normalized = output.toLowerCase();
267+
const linuxSignals = [
268+
/"oslist"\s+"linux"/i,
269+
/"oslist"\s+"linux,windows"/i,
270+
/"oslist"\s+"windows,linux"/i,
271+
/"platforms"[\s\S]*?"linux"\s+"1"/i,
272+
/linux32/i,
273+
/linux64/i,
274+
];
275+
const windowsOnlySignals = [
276+
/"oslist"\s+"windows"/i,
277+
/"platforms"[\s\S]*?"windows"\s+"1"/i,
278+
];
279+
280+
const hasLinuxSignal = linuxSignals.some((re) => re.test(normalized));
281+
const hasWindowsOnlySignal =
282+
!hasLinuxSignal && windowsOnlySignals.some((re) => re.test(normalized));
283+
284+
if (hasLinuxSignal) {
285+
return {
286+
status: 'linux',
287+
reason: `SteamCMD app_info contains Linux platform/depot metadata for AppID ${appId}.`,
288+
};
289+
}
290+
291+
if (hasWindowsOnlySignal) {
292+
return {
293+
status: 'windows-only',
294+
reason: `SteamCMD app_info contains Windows-only platform metadata for AppID ${appId}.`,
295+
};
296+
}
297+
298+
return {
299+
status: 'unknown',
300+
reason: `SteamCMD app_info returned no clear Linux server metadata for AppID ${appId}.`,
301+
};
302+
} catch (err) {
303+
const stderr = err.stderr ? String(err.stderr).trim() : '';
304+
const stdout = err.stdout ? String(err.stdout).trim() : '';
305+
const message = stderr || stdout || err.message;
306+
return {
307+
status: 'error',
308+
reason: `SteamCMD lookup failed: ${message}`,
309+
};
310+
}
311+
}
312+
230313
function parseServerlistCsv(csvText) {
231314
const rows = [];
232315
const lines = (csvText || '').split(/\r?\n/);
@@ -809,9 +892,13 @@ jobs:
809892
810893
// Steam API check: platforms.linux for the given AppID.
811894
// Note: dedicated server tool AppIDs (e.g. 403240, 869800) return success:false
812-
// because they have no store page. This is NOT evidence of no Linux support.
895+
// because they have no store page — this is NOT evidence of no Linux support.
896+
// We do NOT fall back to checking the game client AppID because client and server
897+
// platform support are independent: a game can have no Linux client but still
898+
// ship a native Linux dedicated server binary (and vice versa).
813899
let steamLinuxSupport = null; // true=yes, false=no, null=unknown/inconclusive
814-
let steamAppIsServerTool = false; // success:false from store API
900+
let steamAppIsServerTool = false; // success:false from store API = likely server-tool AppID
901+
let steamCmdAssessment = null;
815902
if (steamAppId) {
816903
try {
817904
const steamRes = await fetch(
@@ -833,6 +920,11 @@ jobs:
833920
} catch (err) {
834921
console.log(`Steam API check failed: ${err.message}`);
835922
}
923+
924+
if (steamLinuxSupport === null) {
925+
steamCmdAssessment = runSteamCmdLinuxCheck(steamAppId);
926+
console.log(`SteamCMD assessment: ${JSON.stringify(steamCmdAssessment)}`);
927+
}
836928
}
837929
838930
// AI analysis of official docs/guides for Linux evidence.
@@ -892,13 +984,15 @@ jobs:
892984
(deterministicWineRequired && !hasLinuxEvidence) ||
893985
(windowsBinaryHint && !hasLinuxEvidence);
894986
const noLinuxFromSteam = steamLinuxSupport === false;
987+
const noLinuxFromSteamCmd = steamCmdAssessment?.status === 'windows-only';
895988
const noLinuxFromAi =
896989
aiLinuxAssessment?.linux_support === 'no' &&
897990
(aiLinuxAssessment?.confidence === 'high' || aiLinuxAssessment?.confidence === 'medium');
898991
899-
const confirmedNoLinux = noLinuxFromDeterministicText || noLinuxFromSteam;
992+
const confirmedNoLinux = noLinuxFromDeterministicText || noLinuxFromSteam || noLinuxFromSteamCmd;
900993
const suggestsNoLinux = noLinuxFromAi && !confirmedNoLinux;
901994
const confirmedLinuxFromSteam = steamLinuxSupport === true;
995+
const confirmedLinuxFromSteamCmd = steamCmdAssessment?.status === 'linux';
902996
const linuxYesFromAi =
903997
aiLinuxAssessment?.linux_support === 'yes' &&
904998
(aiLinuxAssessment?.confidence === 'high' || aiLinuxAssessment?.confidence === 'medium');
@@ -909,6 +1003,7 @@ jobs:
9091003
!confirmedNoLinux &&
9101004
!suggestsNoLinux &&
9111005
!confirmedLinuxFromSteam &&
1006+
!confirmedLinuxFromSteamCmd &&
9121007
!linuxYesFromAi;
9131008
9141009
const NO_LINUX_LABEL = 'status: no linux support';
@@ -947,7 +1042,11 @@ jobs:
9471042
if (isSteamNo) reasons.push('request is marked as non-Steam, so Steam platform checks were intentionally skipped');
9481043
if (noLinuxFromSteam) reasons.push(`Steam API reports no Linux platform support for AppID ${steamAppId}`);
9491044
if (confirmedLinuxFromSteam) reasons.push(`Steam API reports Linux platform support for AppID ${steamAppId}`);
950-
if (steamAppIsServerTool) reasons.push(`AppID ${steamAppId} has no Steam store page (common for dedicated server tools) — Steam platform check inconclusive`);
1045+
if (steamAppIsServerTool) reasons.push(`AppID ${steamAppId} has no Steam store page (typical for dedicated server tool AppIDs) — Steam client platform check is not applicable to server support`);
1046+
if (noLinuxFromSteamCmd && steamCmdAssessment?.reason) reasons.push(steamCmdAssessment.reason);
1047+
if (confirmedLinuxFromSteamCmd && steamCmdAssessment?.reason) reasons.push(steamCmdAssessment.reason);
1048+
if (steamCmdAssessment?.status === 'unknown' && steamCmdAssessment?.reason) reasons.push(steamCmdAssessment.reason);
1049+
if (steamCmdAssessment?.status === 'error' && steamCmdAssessment?.reason) reasons.push(steamCmdAssessment.reason);
9511050
if (noLinuxFromAi && aiLinuxAssessment?.reason) reasons.push(`AI analysis of provided documentation: ${aiLinuxAssessment.reason}`);
9521051
if (linuxYesFromAi && aiLinuxAssessment?.reason) reasons.push(`AI analysis indicates Linux support: ${aiLinuxAssessment.reason}`);
9531052
if (likelySupportedByCheckbox) reasons.push('requester confirmed Linux support via the form checkbox; no contradicting evidence found');
@@ -959,6 +1058,8 @@ jobs:
9591058
verdictLine = 'This server request **may not** have native Linux support based on submitted evidence.';
9601059
} else if (confirmedLinuxFromSteam) {
9611060
verdictLine = 'Steam metadata confirms this server has Linux platform support.';
1061+
} else if (confirmedLinuxFromSteamCmd) {
1062+
verdictLine = 'SteamCMD metadata indicates this server has Linux platform/depot support.';
9621063
} else if (linuxYesFromAi) {
9631064
verdictLine = 'Submitted documentation appears to indicate Linux server support.';
9641065
} else if (likelySupportedByCheckbox) {
@@ -975,16 +1076,33 @@ jobs:
9751076
? 'Inconclusive — AppID has no store page (typical for dedicated server tools)'
9761077
: 'No definitive platform response';
9771078
1079+
const steamCmdStatus = isSteamNo
1080+
? 'Not applicable'
1081+
: !steamAppId
1082+
? 'Skipped until valid AppID is provided'
1083+
: steamLinuxSupport !== null
1084+
? 'Not needed (Steam API returned a definitive result)'
1085+
: steamCmdAssessment?.status === 'linux'
1086+
? 'Linux platform/depot metadata found'
1087+
: steamCmdAssessment?.status === 'windows-only'
1088+
? 'Windows-only platform metadata found'
1089+
: steamCmdAssessment?.status === 'unknown'
1090+
? 'No clear Linux server metadata found'
1091+
: steamCmdAssessment?.status === 'error'
1092+
? 'Lookup failed'
1093+
: 'Not run';
1094+
9781095
const steamBlock = isSteamNo
9791096
? '**Steam:** No (non-Steam request)\n**Steam API:** Not applicable\n\n'
9801097
: steamAppId
9811098
? `**Steam:** ${isSteamYes ? 'Yes' : 'Unspecified'}\n` +
9821099
`**Steam AppID:** ${steamAppId}\n` +
9831100
`**Steam API:** ${steamApiStatus}\n` +
1101+
`**SteamCMD:** ${steamCmdStatus}\n` +
9841102
`**SteamDB:** ${steamDbLink}\n\n`
9851103
: `**Steam:** ${isSteamYes ? 'Yes' : 'Unspecified'}\n` +
9861104
'**Steam AppID:** Not provided in the issue form.\n' +
987-
(isSteamYes ? '**Steam API:** Skipped until valid AppID is provided.\n\n' : '\n');
1105+
(isSteamYes ? '**Steam API:** Skipped until valid AppID is provided.\n**SteamCMD:** Skipped until valid AppID is provided.\n\n' : '\n');
9881106
9891107
const linuxCommentBody =
9901108
`${LINUX_MARKER}\n` +
@@ -999,7 +1117,7 @@ jobs:
9991117
`- Official Linux dedicated server documentation\n` +
10001118
`- Linux server binaries or release notes\n` +
10011119
`- Linux startup instructions or commands\n\n` +
1002-
`_This check was performed automatically using Steam API and submitted issue details (with AI assistance for document interpretation)._`;
1120+
`_This check was performed automatically using Steam API, SteamCMD, and submitted issue details (with AI assistance for document interpretation)._`;
10031121
10041122
try {
10051123
const allComments = await github.paginate(github.rest.issues.listComments, {

0 commit comments

Comments
 (0)