mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 07:24:52 +09:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71feb86ce8 | ||
|
|
346e1acc97 | ||
|
|
46e6445973 | ||
|
|
28eb3a07e0 |
No files matched your search
@@ -31,6 +31,17 @@ Many thanks to the following for contributing to this release:
|
|||||||
[@username](https://github.com/username)
|
[@username](https://github.com/username)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## Version 2.0.1
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Removed obsolete development-branch warnings from controller, host and ctl startup. [#1078](<https://github.com/clusterio/clusterio/pull/1078>)
|
||||||
|
- Removed the obsolete alpha label and development warning from the Clusterio Library mod title and description. [#1079](<https://github.com/clusterio/clusterio/pull/1079>)
|
||||||
|
- Fixed Factorio mod release uploads to use valid multipart requests and files from the requested output directory, uploading variants in version order. [#1080](<https://github.com/clusterio/clusterio/pull/1080>)
|
||||||
|
|
||||||
|
Many thanks to the following for contributing to this release:
|
||||||
|
[@psihius](<https://github.com/psihius>)
|
||||||
|
|
||||||
## Version 2.0.0
|
## Version 2.0.0
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -503,14 +503,6 @@ async function startup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function bootstrap() {
|
export function bootstrap() {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn(`
|
|
||||||
+==========================================================+
|
|
||||||
I WARNING: This is the development branch for the 2.0 I
|
|
||||||
I version of clusterio. Expect things to break. I
|
|
||||||
+==========================================================+
|
|
||||||
`
|
|
||||||
);
|
|
||||||
startup().catch(err => {
|
startup().catch(err => {
|
||||||
if (err instanceof lib.StartupError || err.code === "InstallationError") {
|
if (err instanceof lib.StartupError || err.code === "InstallationError") {
|
||||||
logger.fatal(`
|
logger.fatal(`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/controller",
|
"name": "@clusterio/controller",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Implementation of Clusterio controller",
|
"description": "Implementation of Clusterio controller",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/create",
|
"name": "@clusterio/create",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Installer for clusterio",
|
"description": "Installer for clusterio",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -327,14 +327,6 @@ async function startCtl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function bootstrap() {
|
export function bootstrap() {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn(`
|
|
||||||
+==========================================================+
|
|
||||||
I WARNING: This is the development branch for the 2.0 I
|
|
||||||
I version of clusterio. Expect things to break. I
|
|
||||||
+==========================================================+
|
|
||||||
`
|
|
||||||
);
|
|
||||||
startCtl().catch(err => {
|
startCtl().catch(err => {
|
||||||
if (err.errors) {
|
if (err.errors) {
|
||||||
logger.fatal(JSON.stringify(err.errors, null, "\t"));
|
logger.fatal(JSON.stringify(err.errors, null, "\t"));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/ctl",
|
"name": "@clusterio/ctl",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio command line management tool",
|
"description": "Clusterio command line management tool",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -267,14 +267,6 @@ async function startHost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function bootstrap() {
|
export function bootstrap() {
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.warn(`
|
|
||||||
+==========================================================+
|
|
||||||
I WARNING: This is the development branch for the 2.0 I
|
|
||||||
I version of clusterio. Expect things to break. I
|
|
||||||
+==========================================================+
|
|
||||||
`
|
|
||||||
);
|
|
||||||
startHost().catch(err => {
|
startHost().catch(err => {
|
||||||
if (err instanceof lib.WebSocketError) {
|
if (err instanceof lib.WebSocketError) {
|
||||||
// Already handled by connector.on("error") within Host
|
// Already handled by connector.on("error") within Host
|
||||||
|
|||||||
@@ -1,4 +1,29 @@
|
|||||||
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Version: 2.1.21
|
||||||
|
Date: 2026-10-14
|
||||||
|
Changes:
|
||||||
|
- Removed the obsolete alpha label and development warning from the mod title and description.
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Version: 2.1.20
|
||||||
|
Date: 2026-10-14
|
||||||
|
Changes:
|
||||||
|
- Removed the obsolete alpha label and development warning from the mod title and description.
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Version: 2.1.18
|
||||||
|
Date: 2026-10-14
|
||||||
|
Changes:
|
||||||
|
- Removed the obsolete alpha label and development warning from the mod title and description.
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Version: 2.1.17
|
||||||
|
Date: 2026-10-14
|
||||||
|
Changes:
|
||||||
|
- Removed the obsolete alpha label and development warning from the mod title and description.
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
|
Version: 2.1.11
|
||||||
|
Date: 2026-10-14
|
||||||
|
Changes:
|
||||||
|
- Removed the obsolete alpha label and development warning from the mod title and description.
|
||||||
|
---------------------------------------------------------------------------------------------------
|
||||||
Version: 2.0.20
|
Version: 2.0.20
|
||||||
Date: 25. 02. 2025
|
Date: 25. 02. 2025
|
||||||
Features:
|
Features:
|
||||||
|
|||||||
@@ -2,30 +2,30 @@
|
|||||||
"name": "clusterio_lib",
|
"name": "clusterio_lib",
|
||||||
"variants": [
|
"variants": [
|
||||||
{
|
{
|
||||||
"version": "2.0.17",
|
"version": "2.1.17",
|
||||||
"factorio_version": "0.17"
|
"factorio_version": "0.17"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "2.0.18",
|
"version": "2.1.18",
|
||||||
"factorio_version": "0.18"
|
"factorio_version": "0.18"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "2.0.11",
|
"version": "2.1.11",
|
||||||
"factorio_version": "1.1"
|
"factorio_version": "1.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "2.0.20",
|
"version": "2.1.20",
|
||||||
"factorio_version": "2.0"
|
"factorio_version": "2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"version": "2.0.21",
|
"version": "2.1.21",
|
||||||
"factorio_version": "2.1"
|
"factorio_version": "2.1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"title": "Clusterio Library (Alpha)",
|
"title": "Clusterio Library",
|
||||||
"author": "Clusterio Team",
|
"author": "Clusterio Team",
|
||||||
"homepage": "https://github.com/clusterio/clusterio",
|
"homepage": "https://github.com/clusterio/clusterio",
|
||||||
"description": "Library for interfacing with Clusterio. Warning: work in progress alpha.",
|
"description": "Library for interfacing with Clusterio.",
|
||||||
"additional_files": {
|
"additional_files": {
|
||||||
"compat.lua": ["..", "..", "modules", "clusterio", "compat.lua"],
|
"compat.lua": ["..", "..", "modules", "clusterio", "compat.lua"],
|
||||||
"serialize.lua": ["..", "..", "modules", "clusterio", "serialize.lua"],
|
"serialize.lua": ["..", "..", "modules", "clusterio", "serialize.lua"],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/host",
|
"name": "@clusterio/host",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Implementation of Clusterio host server",
|
"description": "Implementation of Clusterio host server",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/lib",
|
"name": "@clusterio/lib",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Shared library for Clusterio",
|
"description": "Shared library for Clusterio",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/web_ui",
|
"name": "@clusterio/web_ui",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio web interface implementation",
|
"description": "Clusterio web interface implementation",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser",
|
"author": "Hornwitser",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-global_chat",
|
"name": "@clusterio/plugin-global_chat",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin forwarding between Factorio servers",
|
"description": "Clusterio plugin forwarding between Factorio servers",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-player_auth",
|
"name": "@clusterio/plugin-player_auth",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin authenticating logged in players to the web interface",
|
"description": "Clusterio plugin authenticating logged in players to the web interface",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-player_sync",
|
"name": "@clusterio/plugin-player_sync",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin forwarding between Factorio servers",
|
"description": "Clusterio plugin forwarding between Factorio servers",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Danielv <danielv@danielv.no>",
|
"author": "Danielv <danielv@danielv.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-research_sync",
|
"name": "@clusterio/plugin-research_sync",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin for synchronizing research between Factorio servers",
|
"description": "Clusterio plugin for synchronizing research between Factorio servers",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-statistics_exporter",
|
"name": "@clusterio/plugin-statistics_exporter",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin for gathering statistics from Factorio servers",
|
"description": "Clusterio plugin for gathering statistics from Factorio servers",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@clusterio/plugin-subspace_storage",
|
"name": "@clusterio/plugin-subspace_storage",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"description": "Clusterio plugin for sharing storage between Factorio servers",
|
"description": "Clusterio plugin for sharing storage between Factorio servers",
|
||||||
"homepage": "https://github.com/clusterio/clusterio#readme",
|
"homepage": "https://github.com/clusterio/clusterio#readme",
|
||||||
"author": "Hornwitser <github@hornwitser.no>",
|
"author": "Hornwitser <github@hornwitser.no>",
|
||||||
|
|||||||
+9
-9
@@ -2,8 +2,9 @@
|
|||||||
* Publish any mods that need to be published
|
* Publish any mods that need to be published
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import FormData from "form-data";
|
import { openAsBlob } from "node:fs";
|
||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
import yargs from "yargs";
|
import yargs from "yargs";
|
||||||
|
|
||||||
let DRY = false;
|
let DRY = false;
|
||||||
@@ -34,7 +35,7 @@ async function requestModReleases(mod) {
|
|||||||
/**
|
/**
|
||||||
* Upload a mod to the mod portal
|
* Upload a mod to the mod portal
|
||||||
*/
|
*/
|
||||||
async function uploadModRelease(file, name) {
|
export async function uploadModRelease(file, name) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Uploading new release ${file}`);
|
console.log(`Uploading new release ${file}`);
|
||||||
if (DRY) {
|
if (DRY) {
|
||||||
@@ -61,7 +62,7 @@ async function uploadModRelease(file, name) {
|
|||||||
// Upload the new version of the mod
|
// Upload the new version of the mod
|
||||||
const uploadUrl = (await initResponse.json()).upload_url;
|
const uploadUrl = (await initResponse.json()).upload_url;
|
||||||
const uploadFormData = new FormData();
|
const uploadFormData = new FormData();
|
||||||
uploadFormData.append("file", (await fs.open(file)).createReadStream(file));
|
uploadFormData.append("file", await openAsBlob(file), path.basename(file));
|
||||||
|
|
||||||
const uploadResponse = await fetch(uploadUrl, {
|
const uploadResponse = await fetch(uploadUrl, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -77,25 +78,24 @@ const regexModZip = /(\w+)_\d+.\d+.\d+\.zip/;
|
|||||||
/**
|
/**
|
||||||
* Publishes all mods that require publishing
|
* Publishes all mods that require publishing
|
||||||
*/
|
*/
|
||||||
async function publishMods(dir) {
|
export async function publishMods(dir) {
|
||||||
const files = await fs.readdir(dir);
|
const files = await fs.readdir(dir);
|
||||||
const mods = files
|
const mods = files
|
||||||
|
.sort((a, b) => a.localeCompare(b, "en", { numeric: true }))
|
||||||
.map(file => regexModZip.exec(file))
|
.map(file => regexModZip.exec(file))
|
||||||
.filter(file => Boolean(file));
|
.filter(file => Boolean(file));
|
||||||
|
|
||||||
const uploading = [];
|
|
||||||
for (const mod of mods) {
|
for (const mod of mods) {
|
||||||
const [file, name] = mod;
|
const [file, name] = mod;
|
||||||
const releases = await requestModReleases(name);
|
const releases = await requestModReleases(name);
|
||||||
if (!releases.some(release => release.file_name === file)) {
|
if (!releases.some(release => release.file_name === file)) {
|
||||||
uploading.push(uploadModRelease(file, name));
|
// Upload in version order so the newest variant is published last.
|
||||||
|
await uploadModRelease(path.join(dir, file), name);
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Skipped ${file}`);
|
console.log(`Skipped ${file}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Promise.all(uploading);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,7 +121,7 @@ async function main() {
|
|||||||
.demandOption("mods-dir", "A path to the mods dir must be specified");
|
.demandOption("mods-dir", "A path to the mods dir must be specified");
|
||||||
}, async argv => {
|
}, async argv => {
|
||||||
DRY = argv.dry;
|
DRY = argv.dry;
|
||||||
publishMods(argv.modsDir);
|
await publishMods(argv.modsDir);
|
||||||
})
|
})
|
||||||
.strict()
|
.strict()
|
||||||
.parse();
|
.parse();
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ before(async function() {
|
|||||||
testPack.factorioVersion = latestFactorioVersion;
|
testPack.factorioVersion = latestFactorioVersion;
|
||||||
|
|
||||||
const [major, minor] = lib.normaliseMajorMinorVersion(latestFactorioVersion).split(".");
|
const [major, minor] = lib.normaliseMajorMinorVersion(latestFactorioVersion).split(".");
|
||||||
testPack.mods.set("clusterio_lib", { name: "clusterio_lib", enabled: true, version: `2.0.${major}${minor}` });
|
testPack.mods.set("clusterio_lib", { name: "clusterio_lib", enabled: true, version: `2.1.${major}${minor}` });
|
||||||
|
|
||||||
await control.sendTo("controller", new lib.ModPackCreateRequest(testPack));
|
await control.sendTo("controller", new lib.ModPackCreateRequest(testPack));
|
||||||
await control.sendTo(
|
await control.sendTo(
|
||||||
|
|||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { execFile } from "node:child_process";
|
||||||
|
import fs from "node:fs/promises";
|
||||||
|
import path from "node:path";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
|
import { publishMods, uploadModRelease } from "../publish.js";
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
|
|
||||||
|
describe("mod publishing", function() {
|
||||||
|
let originalFetch;
|
||||||
|
let directory;
|
||||||
|
|
||||||
|
beforeEach(async function() {
|
||||||
|
originalFetch = global.fetch;
|
||||||
|
await fs.mkdir("temp", { recursive: true });
|
||||||
|
directory = await fs.mkdtemp("temp/publish-test-");
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async function() {
|
||||||
|
global.fetch = originalFetch;
|
||||||
|
await fs.rm(directory, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sends multipart mod and file fields accepted by native fetch", async function() {
|
||||||
|
const name = "multipart_test";
|
||||||
|
const filename = `${name}_1.0.0.zip`;
|
||||||
|
const contents = Buffer.from([0x50, 0x4b, 0x03, 0x04, 0x00, 0xff]);
|
||||||
|
const file = path.join(directory, filename);
|
||||||
|
await fs.writeFile(file, contents);
|
||||||
|
let calls = 0;
|
||||||
|
global.fetch = async (url, options) => {
|
||||||
|
calls += 1;
|
||||||
|
const request = new Request(url, options);
|
||||||
|
assert.match(request.headers.get("content-type"), /^multipart\/form-data; boundary=/);
|
||||||
|
const form = await request.formData();
|
||||||
|
if (calls === 1) {
|
||||||
|
assert.equal(url, "https://mods.factorio.com/api/v2/mods/releases/init_upload");
|
||||||
|
assert.equal(form.get("mod"), name);
|
||||||
|
return Response.json({ upload_url: "https://upload.example.test/release" });
|
||||||
|
}
|
||||||
|
assert.equal(url, "https://upload.example.test/release");
|
||||||
|
const uploaded = form.get("file");
|
||||||
|
assert.equal(uploaded.name, filename);
|
||||||
|
assert.deepEqual(Buffer.from(await uploaded.arrayBuffer()), contents);
|
||||||
|
return Response.json({ success: true });
|
||||||
|
};
|
||||||
|
await uploadModRelease(file, name);
|
||||||
|
assert.equal(calls, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("reads archives from the supplied directory and uploads unpublished versions in order", async function() {
|
||||||
|
const name = "ordered_publish_test";
|
||||||
|
for (const version of ["1.0.9", "1.0.10", "1.0.2"]) {
|
||||||
|
await fs.writeFile(path.join(directory, `${name}_${version}.zip`), version);
|
||||||
|
}
|
||||||
|
const uploaded = [];
|
||||||
|
let uploading = false;
|
||||||
|
global.fetch = async (url, options) => {
|
||||||
|
if (url === `https://mods.factorio.com/api/mods/${name}`) {
|
||||||
|
return Response.json({ releases: [{ file_name: `${name}_1.0.2.zip` }] });
|
||||||
|
}
|
||||||
|
const form = await new Request(url, options).formData();
|
||||||
|
if (url.endsWith("/init_upload")) {
|
||||||
|
assert.equal(uploading, false, "previous upload must complete first");
|
||||||
|
uploading = true;
|
||||||
|
return Response.json({ upload_url: "https://upload.example.test/release" });
|
||||||
|
}
|
||||||
|
const file = form.get("file");
|
||||||
|
uploaded.push([file.name, await file.text()]);
|
||||||
|
await new Promise(resolve => setImmediate(resolve));
|
||||||
|
uploading = false;
|
||||||
|
return Response.json({ success: true });
|
||||||
|
};
|
||||||
|
await publishMods(directory);
|
||||||
|
assert.deepEqual(uploaded, [
|
||||||
|
[`${name}_1.0.9.zip`, "1.0.9"],
|
||||||
|
[`${name}_1.0.10.zip`, "1.0.10"],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("runs the CLI in dry-run mode without uploading unpublished archives", async function() {
|
||||||
|
const filename = "cli_publish_test_1.0.0.zip";
|
||||||
|
await fs.writeFile(path.join(directory, filename), "dry-run archive");
|
||||||
|
const mockFetch = `
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
global.fetch = async (url, options = {}) => {
|
||||||
|
assert.equal(url, "https://mods.factorio.com/api/mods/cli_publish_test");
|
||||||
|
assert.equal(options.method ?? "GET", "GET", "dry-run must not upload");
|
||||||
|
return Response.json({ releases: [] });
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
const { stdout, stderr } = await execFileAsync(process.execPath, [
|
||||||
|
"--import", `data:text/javascript,${encodeURIComponent(mockFetch)}`,
|
||||||
|
"publish.js", "factorio", directory, "--dry-run",
|
||||||
|
]);
|
||||||
|
assert.equal(stderr, "");
|
||||||
|
assert(stdout.includes("Requesting current releases of cli_publish_test"));
|
||||||
|
assert(stdout.includes(path.join(directory, filename)));
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in new issue
Block a user