From c48d3cb3943fb5b263468efdc2410fc0ae0a8d34 Mon Sep 17 00:00:00 2001 From: Chivier Humber Date: Mon, 26 Oct 2026 02:14:12 +0000 Subject: [PATCH] ci: deploy docs with an SSH deploy key instead of a PAT The DEPLOY_TOKEN personal access token expired, so pushing to openmlsys.github.io failed with "Invalid username or token". Use a write-enabled deploy key scoped to that repository (DEPLOY_KEY secret), which does not expire and is not tied to a personal account. GitHub's SSH host key is pinned instead of trusting ssh-keyscan. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/update_docs.yml | 12 ++++++++++-- tests/test_update_docs_workflow.py | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update_docs.yml b/.github/workflows/update_docs.yml index 4117746..db897b5 100644 --- a/.github/workflows/update_docs.yml +++ b/.github/workflows/update_docs.yml @@ -48,9 +48,17 @@ jobs: - name: Assemble and deploy to openmlsys.github.io env: - DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }} + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} run: | - git clone https://x-access-token:${DEPLOY_TOKEN}@github.com/openmlsys/openmlsys.github.io.git + # DEPLOY_KEY is the private half of a write-enabled deploy key on openmlsys.github.io. + key_file="${RUNNER_TEMP}/deploy_key" + known_hosts="${RUNNER_TEMP}/known_hosts" + printf '%s\n' "${DEPLOY_KEY}" > "${key_file}" + chmod 600 "${key_file}" + echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" > "${known_hosts}" + export GIT_SSH_COMMAND="ssh -i ${key_file} -o IdentitiesOnly=yes -o UserKnownHostsFile=${known_hosts} -o StrictHostKeyChecking=yes" + + git clone git@github.com:openmlsys/openmlsys.github.io.git python3 tools/assemble_docs_publish_tree.py \ --destination-root openmlsys.github.io \ diff --git a/tests/test_update_docs_workflow.py b/tests/test_update_docs_workflow.py index e57774a..d02e138 100644 --- a/tests/test_update_docs_workflow.py +++ b/tests/test_update_docs_workflow.py @@ -13,7 +13,9 @@ class UpdateDocsWorkflowTests(unittest.TestCase): def test_workflow_deploys_to_openmlsys_github_io(self) -> None: workflow = WORKFLOW_PATH.read_text(encoding="utf-8") - self.assertIn("DEPLOY_TOKEN", workflow) + self.assertIn("secrets.DEPLOY_KEY", workflow) + self.assertIn("git@github.com:openmlsys/openmlsys.github.io.git", workflow) + self.assertNotIn("DEPLOY_TOKEN", workflow) self.assertIn("openmlsys.github.io", workflow) self.assertIn("git push", workflow)