import { writeFileSync } from 'node:fs'; import { spawnSync } from 'node:child_process'; import { parseFetchurl, replaceInFile } from './lib'; /* Constants */ const FLAKE = process.env.FLAKE; const genVueText = ( version: string, hash: string, url: string, ) => `# This file was autogenerated. DO NOT EDIT! { version = "${version}"; url = "${url}"; hash = "${hash}"; } `; export const updateVuetorrent = () => { const FILE = `${FLAKE}/configurations/nos/modules/qbittorrent/vuetorrent.nix`; const OLD_VERSION = JSON.parse(spawnSync('nix', ['eval', '-f', FILE, '--json'], { shell: true }).stdout.toString()).version; const VERSION = JSON.parse(spawnSync('curl', ['-s', 'https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest'], { shell: true }).stdout.toString()).tag_name.replace('v', ''); const URL = `https://github.com/VueTorrent/VueTorrent/releases/download/v${VERSION}/vuetorrent.zip`; const HASH = parseFetchurl(URL); const fileText = genVueText(VERSION, HASH, URL); writeFileSync(FILE, fileText); return OLD_VERSION !== VERSION ? `Vuetorrent: ${OLD_VERSION} -> ${VERSION}` : ''; }; export const updateCustomPackage = (pkg: string) => spawnSync( `nix run ${FLAKE}#${pkg}.update`, [], { shell: true }, ).stderr.toString(); const getAttrVersion = (attr: string): string => spawnSync('nix', ['eval', '--raw', `${FLAKE}#${attr}.version`], { shell: true }).stdout.toString(); export const runNixUpdate = ( attr: string, options: string[] = [], ): { stdout: string, stderr: string } => { const OLD_VERSION = getAttrVersion(attr); const execution = spawnSync( `nix-update --flake ${attr} --write-commit-message >(head -n 1 -) > /dev/null`, options, { shell: true, cwd: FLAKE }, ); const NEW_VERSION = getAttrVersion(attr); return { stdout: OLD_VERSION !== NEW_VERSION ? execution.stdout.toString() : '', stderr: execution.stderr.toString(), }; }; const genPluginsText = ( plugins: Record, ) => `# This file was autogenerated. DO NOT EDIT! { plugins = { ${Object.entries(plugins) .map(([key, value]) => ` ${key} = { url = "${value.url}"; version = "${value.version}"; }; `) .join('')} }; hash = ""; } `; export const updateCaddyPlugins = () => { let updates = ''; const dir = `${FLAKE}/configurations/cluster/modules/caddy`; // Setup workspace spawnSync( [ 'rm -rf /tmp/update-caddy', 'mkdir -p /tmp/update-caddy', 'cd /tmp/update-caddy || exit 1', 'go mod init temp', ].join('; '), [], { shell: true, cwd: '/tmp' }, ); const plugins = JSON.parse(spawnSync('nix', ['eval', '-f', `${dir}/plugins.nix`, '--json'], { shell: true }).stdout.toString()).plugins as Record; // Get most recent versions of plugins Object.entries(plugins).forEach(([key, value]) => { const NEW_VERSION = spawnSync([ 'go mod init temp > /dev/null', `go get ${value.url} > /dev/null`, `grep '${value.url}' go.mod`, ].join('; '), [], { shell: true, cwd: '/tmp/update-caddy' }) .stdout .toString() .trim() .replace(' // indirect', '') .split(' ')[1]; if (plugins[key].version !== NEW_VERSION) { updates += `${key}: ${plugins[key].version} -> ${NEW_VERSION}`; plugins[key].version = NEW_VERSION; } }); writeFileSync(`${dir}/plugins.nix`, genPluginsText(plugins)); // Get new hash const caddyPkgAttr = 'nixosConfigurations.thingone.config.services.caddy.package'; const NEW_HASH = spawnSync( `nix build "$FLAKE#${caddyPkgAttr}" |& sed -n 's/.*got: *//p'`, [], { shell: true }, ).stdout.toString().trim(); replaceInFile(/hash = ".*";/, `hash = "${NEW_HASH}";`, `${dir}/plugins.nix`); return updates; };