mirror of
https://github.com/Minionguyjpro/Inno-Setup-Action
synced 2026-02-18 09:31:19 +01:00
Merge pull request #130 from RyouDYFZ/main
feat: Add option to install latest Inno Setup via URL
This commit is contained in:
@@ -12,6 +12,14 @@ inputs:
|
|||||||
options:
|
options:
|
||||||
description: 'Extra arguments/options to include. Include the slashes for them.'
|
description: 'Extra arguments/options to include. Include the slashes for them.'
|
||||||
required: false
|
required: false
|
||||||
|
install_latest:
|
||||||
|
description: 'Set to true to download and install the latest Inno Setup from the installer URL before running.'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
installer_url:
|
||||||
|
description: 'URL to download the Inno Setup installer (can be overridden).'
|
||||||
|
required: false
|
||||||
|
default: 'https://jrsoftware.org/download.php/is.exe?site=1'
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: 'node20'
|
||||||
|
|||||||
115
src/index.js
115
src/index.js
@@ -1,14 +1,20 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
|
import { createWriteStream } from "fs";
|
||||||
import { exec, execFile } from "child_process";
|
import { exec, execFile } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
|
import https from "https";
|
||||||
|
import os from "os";
|
||||||
|
import pathModule from "path";
|
||||||
|
|
||||||
const execPromise = promisify(exec);
|
const execPromise = promisify(exec);
|
||||||
const execFilePromise = promisify(execFile);
|
const execFilePromise = promisify(execFile);
|
||||||
|
|
||||||
const workspacePath = process.env.GITHUB_WORKSPACE;
|
const workspacePath = process.env.GITHUB_WORKSPACE;
|
||||||
const options = core.getMultilineInput("options");
|
const options = core.getMultilineInput("options");
|
||||||
const path = core.getInput("path");
|
const scriptInput = core.getInput("path");
|
||||||
|
const installLatest = (core.getInput("install_latest") || "false").toLowerCase() === "true";
|
||||||
|
const installerUrl = core.getInput("installer_url") || "https://jrsoftware.org/download.php/is.exe?site=1";
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
@@ -35,27 +41,100 @@ async function run() {
|
|||||||
|
|
||||||
const escapedOptions = options.map((str) => str.replace(/(["'])/g, "$1"));
|
const escapedOptions = options.map((str) => str.replace(/(["'])/g, "$1"));
|
||||||
|
|
||||||
// Install Inno Setup silently
|
async function downloadFile(url, dest) {
|
||||||
try {
|
return new Promise((resolve, reject) => {
|
||||||
const { stdout, stderr } = await execPromise(`choco install innosetup`);
|
const maxRedirects = 5;
|
||||||
console.error(stderr);
|
function getUrl(u, redirects) {
|
||||||
} catch (err) {
|
if (redirects > maxRedirects) return reject(new Error("Too many redirects while downloading installer"));
|
||||||
throw new Error(
|
https.get(u, (res) => {
|
||||||
`Failed to install Inno Setup: ${err.stderr || err.message}`,
|
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
||||||
);
|
return getUrl(res.headers.location, redirects + 1);
|
||||||
|
}
|
||||||
|
if (res.statusCode !== 200) {
|
||||||
|
return reject(new Error(`Download failed with status ${res.statusCode}`));
|
||||||
|
}
|
||||||
|
const file = createWriteStream(dest);
|
||||||
|
res.pipe(file);
|
||||||
|
file.on("finish", () => file.close(resolve));
|
||||||
|
file.on("error", reject);
|
||||||
|
}).on("error", reject);
|
||||||
|
}
|
||||||
|
getUrl(url, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Inno Setup Compiler
|
async function findIscc() {
|
||||||
const isccPath = `${process.env["ProgramFiles(x86)"]}\\Inno Setup 6\\iscc.exe`;
|
const candidates = [];
|
||||||
const scriptPath = `${workspacePath}\\${path}`;
|
const pf86 = process.env["ProgramFiles(x86)"];
|
||||||
|
const pf = process.env["ProgramFiles"];
|
||||||
|
if (pf86) {
|
||||||
|
candidates.push(pathModule.join(pf86, "Inno Setup 6", "iscc.exe"));
|
||||||
|
candidates.push(pathModule.join(pf86, "Inno Setup 7", "iscc.exe"));
|
||||||
|
candidates.push(pathModule.join(pf86, "Inno Setup", "iscc.exe"));
|
||||||
|
}
|
||||||
|
if (pf) {
|
||||||
|
candidates.push(pathModule.join(pf, "Inno Setup 6", "iscc.exe"));
|
||||||
|
candidates.push(pathModule.join(pf, "Inno Setup 7", "iscc.exe"));
|
||||||
|
candidates.push(pathModule.join(pf, "Inno Setup", "iscc.exe"));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const p of candidates) {
|
||||||
|
try {
|
||||||
|
await fs.access(p);
|
||||||
|
return p;
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to 'where' to see if it's on PATH
|
||||||
|
try {
|
||||||
|
const { stdout } = await execPromise("where iscc.exe");
|
||||||
|
const line = stdout.split(/\r?\n/).find(Boolean);
|
||||||
|
if (line) return line.trim();
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install Inno Setup: either download+install latest or fallback to choco
|
||||||
|
if (installLatest) {
|
||||||
|
const tmpExe = pathModule.join(os.tmpdir(), `inno-setup-installer-${Date.now()}.exe`);
|
||||||
|
try {
|
||||||
|
core.info(`Downloading Inno Setup from ${installerUrl} ...`);
|
||||||
|
await downloadFile(installerUrl, tmpExe);
|
||||||
|
core.info(`Running installer silently: ${tmpExe}`);
|
||||||
|
await execFilePromise(tmpExe, ["/VERYSILENT", "/SUPPRESSMSGBOXES", "/NORESTART", "/SP-"]);
|
||||||
|
} catch (err) {
|
||||||
|
core.warning(`Download/install failed: ${err.message}. Falling back to Chocolatey.`);
|
||||||
|
try {
|
||||||
|
await execPromise(`choco install innosetup -y`);
|
||||||
|
} catch (err2) {
|
||||||
|
throw new Error(`Failed to install Inno Setup: ${err2.stderr || err2.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await execPromise(`choco install innosetup -y`);
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`Failed to install Inno Setup: ${err.stderr || err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate iscc.exe
|
||||||
|
const isccPath = await findIscc();
|
||||||
|
if (!isccPath) {
|
||||||
|
throw new Error("Could not locate iscc.exe after installation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const scriptPath = pathModule.join(workspacePath, scriptInput);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { stdout, stderr } = await execFilePromise(isccPath, [
|
const { stdout, stderr } = await execFilePromise(isccPath, [scriptPath, ...escapedOptions]);
|
||||||
scriptPath,
|
if (stdout) console.log(stdout);
|
||||||
...escapedOptions,
|
if (stderr) console.error(stderr);
|
||||||
]);
|
|
||||||
console.log(stdout);
|
|
||||||
console.error(stderr);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(`Execution failed: ${err.stderr || err.message}`);
|
throw new Error(`Execution failed: ${err.stderr || err.message}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user