From 97bdc4692c8ac05355800970d5528f733e3e8208 Mon Sep 17 00:00:00 2001 From: vadimenovikau Date: Fri, 21 Aug 2026 13:28:17 +0000 Subject: [PATCH] feat(ci): support explicit runtime secret mapping --- .gitea/actions/quickstack-oci/deploy.mjs | 36 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/.gitea/actions/quickstack-oci/deploy.mjs b/.gitea/actions/quickstack-oci/deploy.mjs index 0725130..2d9bea6 100644 --- a/.gitea/actions/quickstack-oci/deploy.mjs +++ b/.gitea/actions/quickstack-oci/deploy.mjs @@ -87,6 +87,33 @@ export function mergeEnvironment(source, overrides = {}) { return rows.map((row) => row.raw ?? `${row.key}=${row.value}`).join("\n"); } +export function resolveSecretEnvironment(secretEnvironment = {}, environment = process.env) { + if ( + secretEnvironment === null || + typeof secretEnvironment !== "object" || + Array.isArray(secretEnvironment) + ) { + throw new Error("secretEnvironment must be an object."); + } + + const resolved = {}; + for (const [runtimeKey, rawSecretName] of Object.entries(secretEnvironment)) { + if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(runtimeKey)) { + throw new Error(`Invalid secret environment key ${runtimeKey}.`); + } + const secretName = String(rawSecretName); + if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(secretName)) { + throw new Error(`Invalid Actions secret name for ${runtimeKey}.`); + } + const value = environment[secretName]; + if (value === undefined || String(value).length === 0) { + throw new Error(`Missing Actions secret ${secretName} for runtime environment ${runtimeKey}.`); + } + resolved[runtimeKey] = String(value); + } + return resolved; +} + async function readBody(response) { const text = await response.text(); if (!text) return null; @@ -605,9 +632,12 @@ function promoteArtifactAliases(artifacts, releaseTag, options) { async function deployApplications({ applications, artifacts, sha, client }) { for (const application of applications) { const artifact = artifacts.get(application.artifact); - const environment = Object.fromEntries( - Object.entries(application.environment ?? {}).map(([key, value]) => [key, expandTokens(value, { sha })]), - ); + const environment = { + ...Object.fromEntries( + Object.entries(application.environment ?? {}).map(([key, value]) => [key, expandTokens(value, { sha })]), + ), + ...resolveSecretEnvironment(application.secretEnvironment), + }; const result = await deployExactImage({ client, appId: application.appId,