mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-05 14:48:07 +00:00
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:
@@ -110,8 +110,8 @@ export default defineComponent({
|
||||
WorkflowGraph,
|
||||
},
|
||||
props: {
|
||||
runIndex: {type: Number, required: true},
|
||||
jobIndex: {type: Number, required: true},
|
||||
runId: {type: Number, required: true},
|
||||
jobId: {type: Number, required: true},
|
||||
actionsURL: {type: String, required: true},
|
||||
locale: {
|
||||
type: Object as PropType<Record<string, any>>,
|
||||
@@ -366,7 +366,7 @@ export default defineComponent({
|
||||
// for example: make cursor=null means the first time to fetch logs, cursor=eof means no more logs, etc
|
||||
return {step: idx, cursor: it.cursor, expanded: it.expanded};
|
||||
});
|
||||
const resp = await POST(`${this.actionsURL}/runs/${this.runIndex}/jobs/${this.jobIndex}`, {
|
||||
const resp = await POST(`${this.actionsURL}/runs/${this.runId}/jobs/${this.jobId}`, {
|
||||
signal: abortController.signal,
|
||||
data: {logCursors},
|
||||
});
|
||||
@@ -538,13 +538,13 @@ export default defineComponent({
|
||||
<div class="action-view-left">
|
||||
<div class="job-group-section">
|
||||
<div class="job-brief-list">
|
||||
<a class="job-brief-item" :href="run.link+'/jobs/'+index" :class="jobIndex === index ? 'selected' : ''" v-for="(job, index) in run.jobs" :key="job.id">
|
||||
<a class="job-brief-item" :href="run.link+'/jobs/'+job.id" :class="jobId === job.id ? 'selected' : ''" v-for="job in run.jobs" :key="job.id">
|
||||
<div class="job-brief-item-left">
|
||||
<ActionRunStatus :locale-status="locale.status[job.status]" :status="job.status"/>
|
||||
<span class="job-brief-name tw-mx-2 gt-ellipsis">{{ job.name }}</span>
|
||||
</div>
|
||||
<span class="job-brief-item-right">
|
||||
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-brief-rerun tw-mx-2 link-action interact-fg" :data-url="`${run.link}/jobs/${index}/rerun`" v-if="job.canRerun"/>
|
||||
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-brief-rerun tw-mx-2 link-action interact-fg" :data-url="`${run.link}/jobs/${job.id}/rerun`" v-if="job.canRerun"/>
|
||||
<span class="step-summary-duration">{{ job.duration }}</span>
|
||||
</span>
|
||||
</a>
|
||||
@@ -581,7 +581,7 @@ export default defineComponent({
|
||||
<WorkflowGraph
|
||||
v-if="showWorkflowGraph && run.jobs.length > 1"
|
||||
:jobs="run.jobs"
|
||||
:current-job-index="jobIndex"
|
||||
:current-job-id="jobId"
|
||||
:run-link="run.link"
|
||||
:workflow-id="run.workflowID"
|
||||
class="workflow-graph-container"
|
||||
@@ -626,7 +626,7 @@ export default defineComponent({
|
||||
</a>
|
||||
|
||||
<div class="divider"/>
|
||||
<a :class="['item', !currentJob.steps.length ? 'disabled' : '']" :href="run.link+'/jobs/'+jobIndex+'/logs'" download>
|
||||
<a :class="['item', !currentJob.steps.length ? 'disabled' : '']" :href="run.link+'/jobs/'+jobId+'/logs'" download>
|
||||
<i class="icon"><SvgIcon name="octicon-download"/></i>
|
||||
{{ locale.downloadLogs }}
|
||||
</a>
|
||||
|
||||
@@ -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"
|
||||
/>
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ export function initRepositoryActionView() {
|
||||
if (parentFullHeight) parentFullHeight.classList.add('tw-pb-0');
|
||||
|
||||
const view = createApp(RepoActionView, {
|
||||
runIndex: parseInt(el.getAttribute('data-run-index')!),
|
||||
jobIndex: parseInt(el.getAttribute('data-job-index')!),
|
||||
runId: parseInt(el.getAttribute('data-run-id')!),
|
||||
jobId: parseInt(el.getAttribute('data-job-id')!),
|
||||
actionsURL: el.getAttribute('data-actions-url'),
|
||||
locale: {
|
||||
approve: el.getAttribute('data-locale-approve'),
|
||||
|
||||
Reference in New Issue
Block a user