Replace index with id in actions routes (#36842)

This PR migrates the web Actions run/job routes from index-based
`runIndex` or `jobIndex` to database IDs.

**⚠️ BREAKING ⚠️**: Existing saved links/bookmarks that use the old
index-based URLs will no longer resolve after this change.

Improvements of this change:
- Previously, `jobIndex` depended on list order, making it hard to
locate a specific job. Using `jobID` provides stable addressing.
- Web routes now align with API, which already use IDs.
- Behavior is closer to GitHub, which exposes run/job IDs in URLs.
- Provides a cleaner base for future features without relying on list
order.
- #36388 this PR improves the support for reusable workflows. If a job
uses a reusable workflow, it may contain multiple child jobs, which
makes relying on job index to locate a job much more complicated

---------

Signed-off-by: Zettat123 <zettat123@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Zettat123
2026-03-10 15:14:48 -06:00
committed by GitHub
parent 6e8f78ae27
commit 385994295d
33 changed files with 713 additions and 228 deletions

View File

@@ -40,7 +40,7 @@ interface StoredState {
const props = defineProps<{
jobs: ActionsJob[];
currentJobIndex: number;
currentJobId: number;
runLink: string;
workflowId: string;
}>()
@@ -588,9 +588,9 @@ function computeJobLevels(jobs: ActionsJob[]): Map<string, number> {
}
function onNodeClick(job: JobNode, event: MouseEvent) {
if (job.index === props.currentJobIndex) return;
if (job.id === props.currentJobId) return;
const link = `${props.runLink}/jobs/${job.index}`;
const link = `${props.runLink}/jobs/${job.id}`;
if (event.ctrlKey || event.metaKey) {
window.open(link, '_blank');
return;
@@ -652,7 +652,7 @@ function onNodeClick(job: JobNode, event: MouseEvent) {
<g
v-for="job in jobsWithLayout"
:key="job.id"
:class="{'current-job': job.index === currentJobIndex}"
:class="{'current-job': job.id === currentJobId}"
class="job-node-group"
@click="onNodeClick(job, $event)"
@mouseenter="handleNodeMouseEnter(job)"
@@ -665,8 +665,8 @@ function onNodeClick(job: JobNode, event: MouseEvent) {
:height="nodeHeight"
rx="8"
:fill="getNodeColor(job.status)"
:stroke="job.index === currentJobIndex ? 'var(--color-primary)' : 'var(--color-card-border)'"
:stroke-width="job.index === currentJobIndex ? '3' : '2'"
:stroke="job.id === currentJobId ? 'var(--color-primary)' : 'var(--color-card-border)'"
:stroke-width="job.id === currentJobId ? '3' : '2'"
class="job-rect"
/>