diff --git a/action.yml b/action.yml index 00f0e7f..7c482d2 100644 --- a/action.yml +++ b/action.yml @@ -197,6 +197,7 @@ runs: INCLUDE_COMMENTS_BY_ACTOR: ${{ inputs.include_comments_by_actor }} EXCLUDE_COMMENTS_BY_ACTOR: ${{ inputs.exclude_comments_by_actor }} GITHUB_RUN_ID: ${{ github.run_id }} + GITEA_RUN_NUMBER: ${{ env.GITEA_RUN_NUMBER }} USE_STICKY_COMMENT: ${{ inputs.use_sticky_comment }} DEFAULT_WORKFLOW_TOKEN: ${{ github.token }} USE_COMMIT_SIGNING: ${{ inputs.use_commit_signing }} @@ -321,7 +322,8 @@ runs: REPOSITORY: ${{ github.repository }} PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} CLAUDE_COMMENT_ID: ${{ steps.prepare.outputs.claude_comment_id }} - GITHUB_RUN_ID: ${{ github.run_id }} + GITHUB_RUN_ID: ${{ steps.prepare.outputs.run_id || github.run_id }} + GITEA_RUN_NUMBER: ${{ env.GITEA_RUN_NUMBER }} GITHUB_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }} GH_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }} GITHUB_EVENT_NAME: ${{ github.event_name }} diff --git a/src/entrypoints/prepare.ts b/src/entrypoints/prepare.ts index af0ce9d..ee5259a 100644 --- a/src/entrypoints/prepare.ts +++ b/src/entrypoints/prepare.ts @@ -6,6 +6,7 @@ */ import * as core from "@actions/core"; +import * as github from "@actions/github"; import { setupGitHubToken } from "../github/token"; import { checkWritePermissions } from "../github/validation/permissions"; import { createOctokit } from "../github/api/client"; @@ -13,11 +14,26 @@ import { parseGitHubContext, isEntityContext } from "../github/context"; import { getMode } from "../modes/registry"; import { prepare } from "../prepare"; import { collectActionInputsPresence } from "./collect-inputs"; +import { setupGiteaRunId } from "../github/api/gitea-run-id"; async function run() { try { collectActionInputsPresence(); + // Resolve Gitea run ID before parsing context (uses GITEA_RUN_NUMBER if available) + // We need a token for this - use either the override token or the default workflow token + const earlyToken = + process.env.OVERRIDE_GITHUB_TOKEN || process.env.DEFAULT_WORKFLOW_TOKEN; + if (earlyToken) { + const { owner, repo } = github.context.repo; + await setupGiteaRunId(earlyToken, owner, repo); + } + + // Output the resolved run ID for subsequent steps + if (process.env.GITHUB_RUN_ID) { + core.setOutput("run_id", process.env.GITHUB_RUN_ID); + } + // Parse GitHub context first to enable mode detection const context = parseGitHubContext(); diff --git a/src/entrypoints/update-comment-link.ts b/src/entrypoints/update-comment-link.ts index 849f954..f76ca6a 100644 --- a/src/entrypoints/update-comment-link.ts +++ b/src/entrypoints/update-comment-link.ts @@ -1,5 +1,6 @@ #!/usr/bin/env bun +import * as github from "@actions/github"; import { createOctokit } from "../github/api/client"; import * as fs from "fs/promises"; import { @@ -14,6 +15,7 @@ import { import { GITHUB_SERVER_URL } from "../github/api/config"; import { checkAndCommitOrDeleteBranch } from "../github/operations/branch-cleanup"; import { updateClaudeComment } from "../github/operations/comments/update-claude-comment"; +import { setupGiteaRunId } from "../github/api/gitea-run-id"; async function run() { try { @@ -23,6 +25,10 @@ async function run() { const baseBranch = process.env.BASE_BRANCH || "main"; const triggerUsername = process.env.TRIGGER_USERNAME; + // Resolve Gitea run ID before parsing context (uses GITEA_RUN_NUMBER if available) + const { owner, repo } = github.context.repo; + await setupGiteaRunId(githubToken, owner, repo); + const context = parseGitHubContext(); // This script is only called for entity-based events @@ -30,8 +36,6 @@ async function run() { throw new Error("update-comment-link requires an entity context"); } - const { owner, repo } = context.repository; - const octokit = createOctokit(githubToken); const serverUrl = GITHUB_SERVER_URL; diff --git a/src/github/api/gitea-run-id.ts b/src/github/api/gitea-run-id.ts new file mode 100644 index 0000000..8adb080 --- /dev/null +++ b/src/github/api/gitea-run-id.ts @@ -0,0 +1,91 @@ +import { GITHUB_API_URL, USE_GITEA_API } from "./config"; + +/** + * Resolves the Gitea run ID from the run number. + * In Gitea, the environment variable GITHUB_RUN_ID is not available, + * so we need to fetch it via the API using GITEA_RUN_NUMBER. + * + * @param token - GitHub/Gitea token for authentication + * @param owner - Repository owner + * @param repo - Repository name + * @returns The resolved run ID, or undefined if not found + */ +export async function resolveGiteaRunId( + token: string, + owner: string, + repo: string, +): Promise { + if (!USE_GITEA_API) { + return undefined; + } + + const runNumber = process.env.GITEA_RUN_NUMBER; + if (!runNumber) { + console.log("GITEA_RUN_NUMBER not set, cannot resolve Gitea run ID"); + return undefined; + } + + try { + // Call Gitea API to get action runs + // GET /api/v1/repos/{owner}/{repo}/actions/runs + const url = `${GITHUB_API_URL}/repos/${owner}/${repo}/actions/runs`; + const response = await fetch(url, { + headers: { + Authorization: `token ${token}`, + Accept: "application/json", + }, + }); + + if (!response.ok) { + console.error( + `Failed to fetch Gitea action runs: ${response.status} ${response.statusText}`, + ); + return undefined; + } + + const data = (await response.json()) as { + workflow_runs?: Array<{ id: number; run_number: number }>; + }; + + // Find the run with matching run_number + const runs = data.workflow_runs || []; + const targetRunNumber = parseInt(runNumber, 10); + const matchingRun = runs.find((run) => run.run_number === targetRunNumber); + + if (matchingRun) { + console.log( + `Resolved Gitea run ID: ${matchingRun.id} from run number: ${runNumber}`, + ); + return String(matchingRun.id); + } + + console.log( + `Could not find Gitea run with run_number: ${runNumber} in ${runs.length} runs`, + ); + return undefined; + } catch (error) { + console.error("Error resolving Gitea run ID:", error); + return undefined; + } +} + +/** + * Sets up the GITHUB_RUN_ID environment variable for Gitea. + * This should be called early in the action execution. + */ +export async function setupGiteaRunId( + token: string, + owner: string, + repo: string, +): Promise { + // Only proceed if we're in Gitea and don't already have a run ID + if (!USE_GITEA_API || process.env.GITHUB_RUN_ID) { + return; + } + + const runId = await resolveGiteaRunId(token, owner, repo); + if (runId) { + process.env.GITHUB_RUN_ID = runId; + console.log(`Set GITHUB_RUN_ID to ${runId} from Gitea API`); + } +}