From 6d1c4254215bdc3b2f0c72053429529be6e7c810 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Mon, 22 Sep 2025 16:42:42 +0100 Subject: [PATCH] ci: fix AI triage (a.k.a. 'traiage') workflow (#19912) - Updates default template name - Set `GITHUB_TOKEN` env - Implement simple `traiage.sh resume` script to download output artifact --- .github/workflows/traiage.yaml | 35 ++++++++++++++-------------------- scripts/traiage.sh | 28 +++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/.github/workflows/traiage.yaml b/.github/workflows/traiage.yaml index 965eefb4be..e2b10ea0b1 100644 --- a/.github/workflows/traiage.yaml +++ b/.github/workflows/traiage.yaml @@ -10,21 +10,13 @@ on: template_name: description: 'Coder template to use for workspace' required: true - default: 'ai-workspace' + default: 'traiage' type: string prefix: description: 'Prefix for workspace name' required: false default: 'traiage' type: string - persistence_mode: - description: 'Persistence mode (push or archive)' - required: false - type: choice - options: - - push - - archive - default: 'archive' jobs: traiage: @@ -51,6 +43,7 @@ jobs: id: extract-context env: ISSUE_URL: ${{ inputs.issue_url }} + GITHUB_TOKEN: ${{ github.token }} run: | issue_number="$(gh issue view "${ISSUE_URL}" --json number --jq '.number')" context_key="gh-${issue_number}" @@ -94,6 +87,7 @@ jobs: env: WORKSPACE_NAME: ${{ steps.create-workspace.outputs.workspace_name }} ISSUE_URL: ${{ inputs.issue_url }} + GITHUB_TOKEN: ${{ github.token }} run: | PROMPT_FILE=/tmp/prompt.txt trap 'rm -f "${PROMPT_FILE}"' EXIT @@ -116,22 +110,14 @@ jobs: # and exit once the agent has completed the task. PROMPT=$(cat $PROMPT_FILE) ./scripts/traiage.sh prompt - - name: Commit and push changes - id: commit-push - if: ${{ inputs.persistence_mode == 'push' }} - run: | - echo "Committing and pushing changes in workspace: $WORKSPACE_NAME" - ./scripts/traiage.sh commit-push - - name: Create and upload archive id: create-archive - if: ${{ inputs.persistence_mode == 'archive' }} env: - DESTINATION_PREFIX: ${{ secrets.TRAIAGE_DESTINATION_PREFIX }} + BUCKET_PREFIX: "gs://coder-traiage-outputs/traiage" run: | echo "Creating archive for workspace: $WORKSPACE_NAME" ./scripts/traiage.sh archive - echo "archive_url=${DESTINATION_PREFIX%%/}/$WORKSPACE_NAME.tar.gz" >> "${GITHUB_OUTPUT}" + echo "archive_url=${BUCKET_PREFIX%%/}/$WORKSPACE_NAME.tar.gz" >> "${GITHUB_OUTPUT}" - name: Report results env: @@ -139,17 +125,24 @@ jobs: CONTEXT_KEY: ${{ steps.extract-context.outputs.context_key }} WORKSPACE_NAME: ${{ steps.create-workspace.outputs.workspace_name }} ARCHIVE_URL: ${{ steps.create-archive.outputs.archive_url }} + BUCKET_PREFIX: "gs://coder-traiage-outputs/traiage" run: | { echo "## TrAIage Results"; echo "- **Issue URL:** ${ISSUE_URL}"; echo "- **Context Key:** ${CONTEXT_KEY}"; echo "- **Workspace:** ${WORKSPACE_NAME}"; - echo "- **Archive URL:** ${ARCHIVE_URL}" + echo "- **Archive URL:** ${ARCHIVE_URL}"; + + echo "To fetch the output to your own workspace:"; + echo ''; + echo '```bash'; + echo "BUCKET_PREFIX=${BUCKET_PREFIX} WORKSPACE_NAME=${WORKSPACE_NAME} ./scripts/traiage.sh resume"; + echo '```' } >> "${GITHUB_STEP_SUMMARY}" - name: Cleanup workspace - if: steps.create-workspace.outputs.workspace_name != '' && (inputs.persistence_mode == 'archive' && steps.create-archive.outputs.archive_url != '') + if: steps.create-workspace.outputs.workspace_name != '' && steps.create-archive.outputs.archive_url != '' run: | echo "Cleaning up workspace: $WORKSPACE_NAME" ./scripts/traiage.sh delete || true diff --git a/scripts/traiage.sh b/scripts/traiage.sh index 633e743d9f..8d31a09869 100755 --- a/scripts/traiage.sh +++ b/scripts/traiage.sh @@ -140,7 +140,7 @@ wait_agentapi_stable() { } archive() { - requiredenvs CODER_URL CODER_SESSION_TOKEN WORKSPACE_NAME DESTINATION_PREFIX + requiredenvs CODER_URL CODER_SESSION_TOKEN WORKSPACE_NAME BUCKET_PREFIX ssh_config # We want the heredoc to be expanded locally and not remotely. @@ -153,7 +153,7 @@ archive() { set -euo pipefail ARCHIVE_PATH=\$(coder-archive-create) ARCHIVE_NAME=\$(basename "\${ARCHIVE_PATH}") - ARCHIVE_DEST="${DESTINATION_PREFIX%%/}/\${ARCHIVE_NAME}" + ARCHIVE_DEST="${BUCKET_PREFIX%%/}/\${ARCHIVE_NAME}" if [[ ! -f "\${ARCHIVE_PATH}" ]]; then echo "FATAL: Archive not found at expected path: \${ARCHIVE_PATH}" exit 1 @@ -215,6 +215,27 @@ delete() { exit 0 } +resume() { + requiredenvs CODER_URL CODER_SESSION_TOKEN WORKSPACE_NAME BUCKET_PREFIX + + # Note: WORKSPACE_NAME here is really the 'context key'. + # Files are uploaded to the GCS bucket under this key. + # This just happens to be the same as the workspace name. + + src="${BUCKET_PREFIX%%/}/${WORKSPACE_NAME}.tar.gz" + dest="${TEMPDIR}/${WORKSPACE_NAME}.tar.gz" + gcloud storage cp "${src}" "${dest}" + if [[ ! -f "${dest}" ]]; then + echo "FATAL: Failed to download archive from ${src}" + exit 1 + fi + + resume_dest="${HOME}/workspaces/${WORKSPACE_NAME}" + mkdir -p "${resume_dest}" + tar -xzvf "${dest}" -C "${resume_dest}" || exit 1 + echo "Workspace restored to ${resume_dest}" +} + main() { dependencies coder @@ -241,6 +262,9 @@ main() { wait-agentapi-stable) wait_agentapi_stable ;; + resume) + resume + ;; *) echo "Unknown option: $1" usage