6 Commits

6 changed files with 133 additions and 63 deletions

22
.vscode/launch.json vendored
View File

@@ -5,16 +5,30 @@
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"env": {
"JOB": "jobs/example.json5"
"GPGPASS": "${input:gpgpass}"
},
"program": "${workspaceFolder}/index.js"
"program": "${workspaceFolder}/bin/artix-metro.mjs",
"args": [
"--job",
"jobs/kde-01.json5"
],
"outFiles": [
"${workspaceFolder}/distribution/*"
]
}
]
],
"inputs": [
{
"id": "gpgpass",
"type": "promptString",
"description": "Enter your GPG password"
}
]
}

View File

@@ -3,7 +3,6 @@
LIBDIR=${LIBDIR:-'/usr/share/artools/lib'}
_artixpkg_pkgbase() {
source "${LIBDIR}"/pkg/git/config.sh
source "${LIBDIR}"/pkg/util.sh
ls -1 "${TREE_DIR_ARTIX}" | tr '\n' ' '
}
@@ -57,6 +56,7 @@ _artix_metro_completion() {
COMPREPLY=()
;;
"-j"|"--job")
compopt -o filenames
COMPREPLY=( $(compgen -f -- "$cur") )
;;
"--workspace")

90
package-lock.json generated
View File

@@ -1,19 +1,19 @@
{
"name": "artix-metro",
"version": "3.1.0",
"version": "3.1.4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "artix-metro",
"version": "3.1.0",
"version": "3.1.4",
"license": "MIT",
"dependencies": {
"artix-checkupdates": "1.0.1",
"artix-checkupdates": "1.0.2",
"cli-color": "2.0.4",
"glob": "11.0.1",
"glob": "11.0.2",
"json5": "2.2.3",
"ky": "1.7.4"
"ky": "1.8.1"
},
"bin": {
"artix-metro": "bin/artix-metro.mjs"
@@ -21,8 +21,8 @@
"devDependencies": {
"@sindresorhus/tsconfig": "7.0.0",
"@types/cli-color": "2.0.6",
"@types/node": "22.10.7",
"typescript": "5.7.3"
"@types/node": "22.15.14",
"typescript": "5.8.3"
}
},
"node_modules/@isaacs/cliui": {
@@ -63,13 +63,13 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.10.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
"version": "22.15.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.14.tgz",
"integrity": "sha512-BL1eyu/XWsFGTtDWOYULQEs4KR0qdtYfCxYAUYRoB7JP7h9ETYLgQTww6kH8Sj2C0pFGgrpM0XKv6/kbIzYJ1g==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.20.0"
"undici-types": "~6.21.0"
}
},
"node_modules/ansi-regex": {
@@ -97,9 +97,9 @@
}
},
"node_modules/artix-checkupdates": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/artix-checkupdates/-/artix-checkupdates-1.0.1.tgz",
"integrity": "sha512-C0AxI3SfoUUekYg3ft/y4+tRjIe8uuDLvBQRSmkfNsRuBLNlEHaxhY/93JB6G4AGXp5RFLZYDnbgjakgbTLhkw==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/artix-checkupdates/-/artix-checkupdates-1.0.2.tgz",
"integrity": "sha512-VTLeMVysGeZ3QiLtEyWoVM8D57YyeYhYQoL3vcW9b0dZE+zhE4di80PYEFGeQzIBcCStcBFnI1uSBoAEHMVHAQ==",
"license": "MIT"
},
"node_modules/balanced-match": {
@@ -288,9 +288,9 @@
}
},
"node_modules/glob": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz",
"integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -357,9 +357,9 @@
}
},
"node_modules/ky": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/ky/-/ky-1.7.4.tgz",
"integrity": "sha512-zYEr/gh7uLW2l4su11bmQ2M9xLgQLjyvx58UyNM/6nuqyWFHPX5ktMjvpev3F8QWdjSsHUpnWew4PBCswBNuMQ==",
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/ky/-/ky-1.8.1.tgz",
"integrity": "sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -604,9 +604,9 @@
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
},
"node_modules/typescript": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -618,9 +618,9 @@
}
},
"node_modules/undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
@@ -758,12 +758,12 @@
"dev": true
},
"@types/node": {
"version": "22.10.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
"version": "22.15.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.14.tgz",
"integrity": "sha512-BL1eyu/XWsFGTtDWOYULQEs4KR0qdtYfCxYAUYRoB7JP7h9ETYLgQTww6kH8Sj2C0pFGgrpM0XKv6/kbIzYJ1g==",
"dev": true,
"requires": {
"undici-types": "~6.20.0"
"undici-types": "~6.21.0"
}
},
"ansi-regex": {
@@ -777,9 +777,9 @@
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
},
"artix-checkupdates": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/artix-checkupdates/-/artix-checkupdates-1.0.1.tgz",
"integrity": "sha512-C0AxI3SfoUUekYg3ft/y4+tRjIe8uuDLvBQRSmkfNsRuBLNlEHaxhY/93JB6G4AGXp5RFLZYDnbgjakgbTLhkw=="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/artix-checkupdates/-/artix-checkupdates-1.0.2.tgz",
"integrity": "sha512-VTLeMVysGeZ3QiLtEyWoVM8D57YyeYhYQoL3vcW9b0dZE+zhE4di80PYEFGeQzIBcCStcBFnI1uSBoAEHMVHAQ=="
},
"balanced-match": {
"version": "1.0.2",
@@ -941,9 +941,9 @@
}
},
"glob": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz",
"integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==",
"requires": {
"foreground-child": "^3.1.0",
"jackspeak": "^4.0.1",
@@ -982,9 +982,9 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
"ky": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/ky/-/ky-1.7.4.tgz",
"integrity": "sha512-zYEr/gh7uLW2l4su11bmQ2M9xLgQLjyvx58UyNM/6nuqyWFHPX5ktMjvpev3F8QWdjSsHUpnWew4PBCswBNuMQ=="
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/ky/-/ky-1.8.1.tgz",
"integrity": "sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw=="
},
"lru-cache": {
"version": "11.0.2",
@@ -1147,15 +1147,15 @@
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
},
"typescript": {
"version": "5.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true
},
"undici-types": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true
},
"which": {

View File

@@ -1,6 +1,6 @@
{
"name": "artix-metro",
"version": "3.1.0",
"version": "3.1.4",
"description": "Automate pushing packages to Artix",
"keywords": [
"artix",
@@ -31,16 +31,16 @@
},
"license": "MIT",
"dependencies": {
"artix-checkupdates": "1.0.1",
"artix-checkupdates": "1.0.2",
"cli-color": "2.0.4",
"ky": "1.7.4",
"ky": "1.8.1",
"json5": "2.2.3",
"glob": "11.0.1"
"glob": "11.0.2"
},
"devDependencies": {
"typescript": "5.7.3",
"typescript": "5.8.3",
"@sindresorhus/tsconfig": "7.0.0",
"@types/cli-color": "2.0.6",
"@types/node": "22.10.7"
"@types/node": "22.15.14"
}
}

View File

@@ -1,7 +1,7 @@
import ky from 'ky';
import { snooze } from './snooze.mjs';
type CiStatus = "pending" | "success" | "error" | "failure";
type CiStatus = "pending" | "success" | "error" | "failure" | "";
interface GiteaConfig {
protocol?: string;
@@ -16,7 +16,12 @@ interface Commit {
interface Status {
sha: string;
state: CiStatus
state: CiStatus;
}
interface Hook {
active: boolean;
id: number;
}
class Gitea {
@@ -95,7 +100,43 @@ class Gitea {
}
}
async getHooks(...args: string[]): Promise<Hook[]> {
try {
let headers: HeadersInit = {};
if (this._token) {
headers['Authorization'] = `token ${this._token}`
}
const resp = await ky.get(`${this.getUrlPrefix()}/repos/${args.join('/')}/hooks`, {
headers
});
return await resp.json();
}
catch (err) {
throw err;
}
}
async sendTestWebhook(...args: string[]): Promise<void> {
try {
let headers: HeadersInit = {};
if (this._token) {
headers['Authorization'] = `token ${this._token}`
}
const hook = (await this.getHooks(...args)).find(hook => hook.active === true);
if (!hook) {
throw new Error('No active webhook found');
}
await ky.post(`${this.getUrlPrefix()}/repos/${args.join('/')}/hooks/${hook.id}/tests`, {
headers
});
}
catch (err) {
throw err;
}
}
async waitForBuild(lastHash: string, ...args: string[]): Promise<void> {
let missingStatusCount = 0;
while (true) {
let status: Status | null;
try {
@@ -108,7 +149,15 @@ class Gitea {
await snooze(30000);
continue;
}
if (status.sha !== lastHash) {
if (!status.sha && !status.state) {
if (++missingStatusCount > 3) {
console.log('No build info detected. Sending test webhook...');
missingStatusCount = 0;
await this.sendTestWebhook(...args);
}
await snooze(30000);
}
else if (status.sha !== lastHash) {
if (status.state === 'success') {
break;
}

View File

@@ -55,14 +55,21 @@ class Pusher {
}
async refreshGpg() {
if (await isPasswordRequired()) {
const sshSignMode = 'SSHKEYSIGN' in process.env;
if (sshSignMode || await isPasswordRequired()) {
console.log(clc.cyan('Refreshing signature...'));
this._createdSignfile ||= await runCommand('touch', [SIGNFILE]);
await runCommand('gpg', ['-a', '--passphrase', escapeCommandParam(this._config.gpgpass || ''), '--batch', '--pinentry-mode', 'loopback', '--detach-sign', SIGNFILE]);
await fsp.rm(`${SIGNFILE}.asc`);
if (sshSignMode) {
await runCommand('ssh-keygen', ['-Y', 'sign', '-f', path.resolve(process.env['SSHKEYSIGN'] as string), '-n', ' git', SIGNFILE]);
}
else {
await runCommand('gpg', ['-a', '--passphrase', escapeCommandParam(this._config.gpgpass || ''), '--batch', '--pinentry-mode', 'loopback', '--detach-sign', SIGNFILE]);
}
await fsp.rm(`${SIGNFILE}.${sshSignMode ? 'sig' : 'asc'}`)
}
}
increment(pkg: string): Promise<void> {
return new Promise(async (res, _) => {
const pkgbuild = path.join(this._artools.workspace, 'artixlinux', pkg, 'PKGBUILD');
@@ -133,7 +140,7 @@ class Pusher {
}
console.log(clc.yellowBright('Running artix-checkupdates'));
const actionable = job.increment ? job.packages : (await (!!job.source ? checkupdates.fetchMovable() : checkupdates.fetchUpgradable())).map(res => res.basename);
const actionable = job.increment ? job.packages : (await (!!job.source ? checkupdates.fetchLooseMovable() : checkupdates.fetchUpgradable())).map(res => res.basename);
// order is IMPORTANT. Must be BLOCKING.
for (let i = 0; i < (job.packages || []).length; i++) {