refactor: migrate to screeps-api v2 and update actions to node 22
Test / Run Tests (push) Failing after 1s
Recompile dist/ on Renovate PR / recompile (pull_request) Failing after 0s
Test / Run Tests (pull_request) Failing after 0s
Philipp/Global-Workflows: Pre-commit Lint (Scoped) / pre-commit (pull_request) Failing after 1s

This commit is contained in:
2026-09-04 23:56:04 +02:00
parent d644b19b47
commit cfb97819ae
8 changed files with 68 additions and 33 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
- uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with: with:
node-version: '24' node-version: '22'
cache: pnpm cache: pnpm
- run: pnpm install --frozen-lockfile - run: pnpm install --frozen-lockfile
shell: bash shell: bash
+1
View File
@@ -34,6 +34,7 @@ repos:
hooks: hooks:
- id: check-renovate - id: check-renovate
- id: check-github-actions - id: check-github-actions
exclude: ^action\.yaml$
- id: check-github-workflows - id: check-github-workflows
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
+19 -9
View File
@@ -24,16 +24,23 @@ vi.mock("../monitor.js", () => ({
vi.mock("screeps-api", () => { vi.mock("screeps-api", () => {
const mockApi = { const mockApi = {
auth: vi.fn().mockResolvedValue(), auth: vi.fn().mockResolvedValue(),
authSignin: vi.fn().mockResolvedValue({ ok: 1, token: "test_token" }),
userCodeGet: vi
.fn()
.mockResolvedValue({ ok: 1, modules: { main: "old_code" } }),
userCodeSet: vi.fn().mockResolvedValue({ ok: 1 }),
code: { code: {
get: vi.fn().mockResolvedValue({ ok: 1, modules: { main: "old_code" } }), get: vi.fn().mockResolvedValue({ ok: 1, modules: { main: "old_code" } }),
set: vi.fn().mockResolvedValue({ ok: 1 }), set: vi.fn().mockResolvedValue({ ok: 1 }),
}, },
}; };
// Use a regular function so it can be called with `new` // Use a regular function so it can be called with `new`
const MockClient = vi.fn(function () {
return mockApi;
});
return { return {
ScreepsAPI: vi.fn(function () { ScreepsHttpClient: MockClient,
return mockApi; ScreepsAPI: MockClient,
}),
}; };
}); });
@@ -48,7 +55,7 @@ import {
applyOnAction, applyOnAction,
postCode, postCode,
} from "../index.js"; } from "../index.js";
import { ScreepsAPI } from "screeps-api"; import { ScreepsHttpClient } from "screeps-api";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import os from "os"; import os from "os";
@@ -330,14 +337,17 @@ describe("postCode — monitor wiring", () => {
await postCode(); await postCode();
// Verify rollback was performed // Verify rollback was performed
const mockApiInstance = new ScreepsAPI(); const mockApiInstance = new ScreepsHttpClient();
// `code.set` should be called twice: // `userCodeSet` should be called twice:
// 1st time: uploading the new files // 1st time: uploading the new files
// 2nd time: rolling back to oldCode // 2nd time: rolling back to oldCode
expect(mockApiInstance.code.set).toHaveBeenCalledTimes(2); expect(mockApiInstance.userCodeSet).toHaveBeenCalledTimes(2);
expect(mockApiInstance.code.set).toHaveBeenNthCalledWith(2, "default", { expect(mockApiInstance.userCodeSet).toHaveBeenNthCalledWith(2, {
main: "old_code", branch: "default",
modules: {
main: "old_code",
},
}); });
// Verify it called core.setFailed due to traceback // Verify it called core.setFailed due to traceback
+13 -5
View File
@@ -382,13 +382,21 @@ function buildMockApi({
disconnect: vi.fn(), disconnect: vi.fn(),
}; };
const getTime = vi.fn().mockImplementation(() => {
const t = ticks[Math.min(tickIndex, ticks.length - 1)];
tickIndex++;
return Promise.resolve({ time: t });
});
const api = { const api = {
opts: { hostname }, opts: { hostname },
time: vi.fn().mockImplementation(() => { time: getTime,
const t = ticks[Math.min(tickIndex, ticks.length - 1)]; get gameTime() {
tickIndex++; return this.time;
return Promise.resolve({ time: t }); },
}), set gameTime(fn) {
this.time = fn;
},
socket, socket,
// Expose so tests can fire console events // Expose so tests can fire console events
_fireConsole: (eventData) => { _fireConsole: (eventData) => {
+1 -1
View File
@@ -79,5 +79,5 @@ outputs:
saw_warning_log: saw_warning_log:
description: true if console.warn output was detected during monitoring. description: true if console.warn output was detected during monitoring.
runs: runs:
using: node20 using: node22
main: dist/index.js main: dist/index.js
+7 -7
View File
File diff suppressed because one or more lines are too long
+18 -6
View File
@@ -1,4 +1,4 @@
import { ScreepsAPI } from "screeps-api"; import { ScreepsHttpClient } from "screeps-api";
import * as core from "@actions/core"; import * as core from "@actions/core";
import fs from "fs"; import fs from "fs";
import { glob } from "glob"; import { glob } from "glob";
@@ -180,12 +180,16 @@ export async function postCode() {
core.error(errorMessage); core.error(errorMessage);
return; return;
} }
let api = new ScreepsAPI(login_arguments); let api = new ScreepsHttpClient(login_arguments);
if (!token) { if (!token) {
core.info(`Logging in as user ${username}`); core.info(`Logging in as user ${username}`);
try { try {
await api.auth(username, password, login_arguments); if (typeof api.authSignin === "function") {
await api.authSignin(username, password);
} else {
await api.auth(username, password, login_arguments);
}
} catch (err) { } catch (err) {
core.error(`Authentication error: ${err}`); core.error(`Authentication error: ${err}`);
throw err; throw err;
@@ -205,7 +209,9 @@ export async function postCode() {
`Downloading existing code from branch ${branch} for potential rollback...`, `Downloading existing code from branch ${branch} for potential rollback...`,
); );
try { try {
const getResponse = await api.code.get(branch); const getResponse = await (api.userCodeGet
? api.userCodeGet(branch)
: api.code.get(branch));
if (getResponse && getResponse.ok && getResponse.modules) { if (getResponse && getResponse.ok && getResponse.modules) {
oldCode = getResponse.modules; oldCode = getResponse.modules;
core.info( core.info(
@@ -226,7 +232,9 @@ export async function postCode() {
} }
try { try {
const response = await api.code.set(branch, files_to_push); const response = await (api.userCodeSet
? api.userCodeSet({ branch, modules: files_to_push })
: api.code.set(branch, files_to_push));
core.info(JSON.stringify(response, null, 2)); core.info(JSON.stringify(response, null, 2));
core.info(`Code set successfully to ${branch}`); core.info(`Code set successfully to ${branch}`);
} catch (err) { } catch (err) {
@@ -279,7 +287,11 @@ export async function postCode() {
"Action failed based on monitor configuration. Rolling back to previous code...", "Action failed based on monitor configuration. Rolling back to previous code...",
); );
try { try {
await api.code.set(branch, oldCode); if (typeof api.userCodeSet === "function") {
await api.userCodeSet({ branch, modules: oldCode });
} else {
await api.code.set(branch, oldCode);
}
core.info( core.info(
`Successfully rolled back to previous code on branch ${branch}.`, `Successfully rolled back to previous code on branch ${branch}.`,
); );
+8 -4
View File
@@ -250,7 +250,7 @@ function sleep(ms) {
* Calls `onProgress(elapsed, targetTicks)` on every poll so the caller can * Calls `onProgress(elapsed, targetTicks)` on every poll so the caller can
* log progress at whatever cadence it chooses. * log progress at whatever cadence it chooses.
* *
* @param {import('screeps-api').ScreepsAPI} api * @param {import('screeps-api').ScreepsHttpClient} api
* @param {number} startTick - Tick number recorded before monitoring started * @param {number} startTick - Tick number recorded before monitoring started
* @param {number} targetTicks - Stop when (currentTick - startTick) >= this * @param {number} targetTicks - Stop when (currentTick - startTick) >= this
* @param {string|undefined} shard - "shard0" for official, undefined for private * @param {string|undefined} shard - "shard0" for official, undefined for private
@@ -270,7 +270,9 @@ export async function pollUntilDone(
let elapsed = 0; let elapsed = 0;
while (elapsed < targetTicks && !shouldStop()) { while (elapsed < targetTicks && !shouldStop()) {
await sleep(intervalMs); await sleep(intervalMs);
const { time } = await api.time(shard); const { time } = await (typeof api.gameTime === "function"
? api.gameTime(shard)
: api.time(shard));
elapsed = time - startTick; elapsed = time - startTick;
onProgress(elapsed, targetTicks); onProgress(elapsed, targetTicks);
} }
@@ -309,7 +311,7 @@ export async function pollUntilDone(
* 6. If logToFile=true: write buffered stdout to a temp file and upload artifact. * 6. If logToFile=true: write buffered stdout to a temp file and upload artifact.
* 7. Return MonitorResult. * 7. Return MonitorResult.
* *
* @param {import('screeps-api').ScreepsAPI} api * @param {import('screeps-api').ScreepsHttpClient} api
* @param {MonitorOptions} opts * @param {MonitorOptions} opts
* @returns {Promise<MonitorResult>} * @returns {Promise<MonitorResult>}
*/ */
@@ -337,7 +339,9 @@ export async function monitorConsole(api, opts) {
let lastProgressTick = 0; let lastProgressTick = 0;
// Step 1: record starting tick // Step 1: record starting tick
const { time: startTick } = await api.time(shard); const { time: startTick } = await (typeof api.gameTime === "function"
? api.gameTime(shard)
: api.time(shard));
// Step 2: connect socket + subscribe // Step 2: connect socket + subscribe
await api.socket.connect(); await api.socket.connect();