Skip to content

Commit

The Actions release reads its token from ACTIONS_PUBLISH_TOKEN. It asked for G1T_ACTIONS_PUBLISH_TOKEN, a name g1t keeps for its own and refuses when a secret is saved, so the secret it needed could never be set. A test now fails any of g1t's workflows that reads a secret named G1T_ or GITHUB_ other than the job's own token.

syntaqxcommitted Parentd28ad69Browse files
2 files+26−50/2 viewed
+4−4
2222 #
2323 # Runs on a push to main that changes actions/ or workflows/, and by hand.
2424 #
25−# Needs the repository secret G1T_ACTIONS_PUBLISH_TOKEN: an access token of
25+# Needs the repository secret ACTIONS_PUBLISH_TOKEN: an access token of
2626 # the workspace g1t leads to (flagon-io), with the scopes repo:write (to
2727 # create a missing repository) and code:write (to push and move tags).
2828 # A token without repo:write still publishes to repositories
6161 fetch-depth: 0
6262 - name: Push each action and move its major tag
6363 env:
64− PUBLISH_TOKEN: ${{ secrets.G1T_ACTIONS_PUBLISH_TOKEN }}
64+ PUBLISH_TOKEN: ${{ secrets.ACTIONS_PUBLISH_TOKEN }}
6565 SERVER: ${{ github.server_url }}
6666 API: ${{ github.api_url }}
6767 run: |
6868 set -euo pipefail
6969 if [ -z "${PUBLISH_TOKEN}" ]; then
70− echo "::error::Set the repository secret G1T_ACTIONS_PUBLISH_TOKEN (this workflow's header says what it needs)."
70+ echo "::error::Set the repository secret ACTIONS_PUBLISH_TOKEN (this workflow's header says what it needs)."
7171 exit 1
7272 fi
7373 echo "::add-mask::${PUBLISH_TOKEN}"
101101 | curl -sS -o "${found}" -w '%{http_code}' -X POST -H "${bearer}" -H "Content-Type: application/json" \
102102 --data-binary @- "${API}/repos")"
103103 if [ "${status}" != "201" ] && [ "${status}" != "200" ]; then
104− echo "::error::Creating ${NAMESPACE}/${name} answered ${status}: $(cat "${found}"). Give G1T_ACTIONS_PUBLISH_TOKEN the repo:write scope, or create ${NAMESPACE}/${name} once by hand, public."
104+ echo "::error::Creating ${NAMESPACE}/${name} answered ${status}: $(cat "${found}"). Give ACTIONS_PUBLISH_TOKEN the repo:write scope, or create ${NAMESPACE}/${name} once by hand, public."
105105 exit 1
106106 fi
107107 echo "- Created \`$(jq -r '.namespace + "/" + .name' "${found}")\` for \`${NAMESPACE}/${name}\`" >> "${GITHUB_STEP_SUMMARY}"
+22−1
306306 assert!(release.trigger("workflow_dispatch").is_some());
307307 let source = std::fs::read_to_string(workflows_dir().join("actions-release.yml")).unwrap();
308308 assert!(source.contains("actions/**"));
309− assert!(source.contains("secrets.G1T_ACTIONS_PUBLISH_TOKEN"));
309+ assert!(source.contains("secrets.ACTIONS_PUBLISH_TOKEN"));
310310 // Every action is a composite one with its README, and the copies of
311311 // the script that finds g1t-runner are the same file.
312312 let actions = workflows_dir().join("../../actions");
349349 assert_eq!(workflow.triggers.iter().map(|t| t.event.as_str()).collect::<Vec<_>>(), ["workflow_dispatch"]);
350350 assert!(!ours.contains("secrets."));
351351 }
352+
353+/// No workflow of g1t's asks for a secret no one can set. Secret names
354+/// starting with G1T_ or GITHUB_ are g1t's own and refused when saved, so a
355+/// workflow reading one gets nothing: the Actions release asked for
356+/// G1T_ACTIONS_PUBLISH_TOKEN, which could never exist. G1T_TOKEN, the job's
357+/// own token, is the one g1t gives every job.
358+#[test]
359+fn workflows_read_only_secrets_that_can_be_set() {
360+ for entry in std::fs::read_dir(workflows_dir()).unwrap() {
361+ let path = entry.unwrap().path();
362+ if path.extension().is_none_or(|ext| ext != "yml") {
363+ continue;
364+ }
365+ let source = std::fs::read_to_string(&path).unwrap();
366+ for (at, _) in source.match_indices("secrets.") {
367+ let name: String = source[at + "secrets.".len()..].chars().take_while(|c| c.is_ascii_alphanumeric() || *c == '_').collect();
368+ let reserved = name.starts_with("G1T_") || name.starts_with("GITHUB_");
369+ assert!(!reserved || name == "G1T_TOKEN" || name == "GITHUB_TOKEN", "{} reads secrets.{name}, a name g1t keeps for its own", path.display());
370+ }
371+ }
372+}