1 Commits

Author SHA1 Message Date
Danny Kim 85c6c505f4 Centralize encrypted bot profiles
Check / deno (pull_request) Successful in 37s
2026-09-24 05:06:07 +09:00
4 changed files with 8 additions and 56 deletions
-7
View File
@@ -1,7 +0,0 @@
---
description: Workflow and container YAML stays declarative; operational shell belongs in separate scripts
---
Do not embed multiline operational scripts in workflow, Compose, or container
YAML. Keep YAML declarative and move shell logic into a small, named `.sh` file
that can be tested directly.
+8 -1
View File
@@ -27,7 +27,14 @@ runs:
env:
ACTION_PATH: ${{ gitea.action_path }}
RUNNER_TEMP: ${{ runner.temp }}
run: bash "${{ gitea.action_path }}/scripts/protect-source.sh"
run: |
path=$(mktemp -d "${RUNNER_TEMP}/bot-agents-source-XXXXXX")
mkdir "${path}/src"
cp -a "${ACTION_PATH}"/src/*.ts "${path}/src/"
cp -a "${ACTION_PATH}/profiles.yml" "${ACTION_PATH}/prompt.md" \
"${path}/"
chmod -R go-w "${path}"
echo "path=${path}" >> "${GITHUB_OUTPUT}"
- name: Allow isolated profiles to edit the checkout
shell: bash
run: chmod -R a+rwX "${GITHUB_WORKSPACE}"
-9
View File
@@ -1,9 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
path=$(mktemp -d "${RUNNER_TEMP}/bot-agents-source-XXXXXX")
mkdir "${path}/src"
cp -a "${ACTION_PATH}"/src/*.ts "${path}/src/"
cp -a "${ACTION_PATH}/profiles.yml" "${ACTION_PATH}/prompt.md" "${path}/"
chmod -R go-w "${path}"
printf 'path=%s\n' "${path}" >> "${GITHUB_OUTPUT}"
-39
View File
@@ -41,11 +41,6 @@ Deno.test("the action exposes only the master key and scopes it to preparation",
const action = await yaml("action.yml");
assertEquals(Object.keys(mapping(action.inputs, "inputs")), ["master-key"]);
const steps = sequence(mapping(action.runs, "runs").steps, "runs.steps");
for (const step of steps) {
if (typeof step.run === "string") {
assertEquals(step.run.includes("\n"), false, String(step.name));
}
}
const checkout = steps.find((step) => step.uses === "actions/checkout@v4");
const prepare = steps.find((step) => step.id === "prepare");
const agent = steps.find((step) => step.id === "agent");
@@ -72,40 +67,6 @@ Deno.test("the action exposes only the master key and scopes it to preparation",
}
});
Deno.test("the source protection script stages immutable action files", async () => {
const temp = await Deno.makeTempDir();
const outputFile = `${temp}/output`;
try {
const output = await new Deno.Command("/bin/bash", {
args: ["scripts/protect-source.sh"],
env: {
ACTION_PATH: Deno.cwd(),
GITHUB_OUTPUT: outputFile,
RUNNER_TEMP: temp,
},
stderr: "piped",
}).output();
assert(output.success, new TextDecoder().decode(output.stderr));
const path = (await Deno.readTextFile(outputFile)).trim().slice(5);
for (
const file of [
"src/prepare.ts",
"src/run.ts",
"src/post.ts",
"profiles.yml",
"prompt.md",
]
) {
const stat = await Deno.stat(`${path}/${file}`);
assert(stat.isFile, file);
assertEquals(stat.mode! & 0o022, 0, file);
}
} finally {
await Deno.remove(temp, { recursive: true });
}
});
Deno.test("the repository uses its trusted main action", async () => {
const workflow = await yaml(".gitea/workflows/agents.yml");
const job = mapping(mapping(workflow.jobs, "jobs").agent, "jobs.agent");