Skip to content

actions: expose previous job attempts and allow downloading attempt logs#37052

Draft
bircni wants to merge 12 commits intogo-gitea:mainfrom
bircni:feature/access-previous-logs
Draft

actions: expose previous job attempts and allow downloading attempt logs#37052
bircni wants to merge 12 commits intogo-gitea:mainfrom
bircni:feature/access-previous-logs

Conversation

@bircni
Copy link
Copy Markdown
Member

@bircni bircni commented Mar 31, 2026

Added a UI to download previous logs of job runs

  • Adds an attempt list for a job (when it has been rerun) and a “Previous logs” section with download links per attempt.
  • Extends job logs download to support ?attempt= so users can fetch logs from earlier attempts (web + API).
  • Adds a subtle attempt badge (×N) next to jobs that have been rerun.
Bildschirmfoto 2026-03-31 um 18 45 10

bircni and others added 5 commits March 31, 2026 00:18
- Filter previous attempts on the backend (attempt < current) instead of
  relying on frontend slice(0,-1), making the contract explicit
- Rename store field currentJobAttempts -> previousJobAttempts to match semantics
- Remove computed wrapper and unused `computed` import in RepoActionView.vue
- Fix container div class job-artifacts -> job-previous-logs for semantic correctness
- Remove redundant comment that restated the condition

Co-Authored-By: Claude  <[email protected]>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Mar 31, 2026
@github-actions github-actions bot added modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/templates This PR modifies the template files modifies/frontend labels Mar 31, 2026
@bircni bircni marked this pull request as ready for review March 31, 2026 13:02
@bircni bircni requested review from ChristopherHX and Zettat123 and removed request for Zettat123 March 31, 2026 14:38
@silverwind silverwind requested a review from Copilot March 31, 2026 15:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “attempt” awareness to Actions workflow job runs so users can see rerun counts and download logs for specific job attempts (web UI + API).

Changes:

  • Extend job/log download endpoints to accept ?attempt=<n> (web + API) and document it in Swagger.
  • Add frontend UI elements: per-job attempt badge and a “Previous logs” attempt list with download links.
  • Add backend plumbing to expose available attempts for a job and to fetch logs for a specific attempt.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
web_src/js/modules/gitea-actions.ts Adds attempt to the ActionsJob type for UI rendering.
web_src/js/features/repo-actions.ts Passes new locale strings (attempt, previousLogs) into the view.
web_src/js/components/RepoActionView.vue Renders attempt badge and new “Previous logs” attempt list + styles.
web_src/js/components/ActionRunView.ts Introduces ActionsAttempt type and stores previousJobAttempts in view data.
web_src/js/components/ActionRunJobView.vue Plumbs availableAttempts from job payload into shared store state.
routers/web/repo/actions/view.go Exposes availableAttempts, adds cursor bounds check, and supports attempt query param for logs.
routers/common/actions.go Extends log download helpers to load logs for a specified attempt.
routers/api/v1/repo/actions_run.go Adds attempt query support and validation for API log download endpoint.
models/actions/task.go Adds indexed JobID and introduces task lookup helpers by job/attempt.
templates/repo/actions/view_component.tmpl Adds locale attributes for new UI labels.
options/locale/locale_en-US.json Adds English strings for “Attempt” and “Previous logs”.
templates/swagger/v1_json.tmpl Documents the new attempt query parameter for job log download.
routers/web/web.go Adds devtest route for mock job logs endpoint.
routers/web/devtest/mock_actions.go Implements mock job logs endpoint and mock attempt metadata.
tests/integration/actions_route_test.go Adds integration test coverage for downloading logs by attempt.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@wxiaoguang

This comment was marked as resolved.

@wxiaoguang wxiaoguang marked this pull request as draft March 31, 2026 15:41
@bircni

This comment was marked as resolved.

@wxiaoguang

This comment was marked as resolved.

@wxiaoguang

This comment was marked as resolved.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 31, 2026

I think adding a dropdown here can be better, there is enough space for more elements.

I like your idea - will try

@wxiaoguang

This comment was marked as resolved.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 31, 2026

I think adding a dropdown here can be better, there is enough space for more elements.

I like your idea - will try

Dropdown is tricky.

I think you can use the fomantic "ui dropdown" in Vue directly (without writing new JS code). If anything wrong happens, I will take a look.

what do you think?

image

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Mar 31, 2026

Bildschirmfoto 2026-03-31 um 18 45 10

@bircni bircni marked this pull request as ready for review April 1, 2026 06:39
@bircni bircni requested a review from wxiaoguang April 1, 2026 06:39
Copy link
Copy Markdown
Contributor

@wxiaoguang wxiaoguang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will wait for real Actions users to review (I don't use Actions). I can do final round (code-level) review.

@silverwind
Copy link
Copy Markdown
Member

How does this feature compare to GitHub UI?

type ActionTask struct {
ID int64
JobID int64
JobID int64 `xorm:"index"`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use runner_id=? and job_id=? , then this index is not needed.

@lunny
Copy link
Copy Markdown
Member

lunny commented Apr 1, 2026

This is useful when running a failed job multiple times.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 1, 2026

How does this feature compare to GitHub UI?

GitHub's Solution is another way where you can switch between attempts but i don't think that's necessary

@silverwind
Copy link
Copy Markdown
Member

silverwind commented Apr 1, 2026

But the root cause is that gitea does not show previous runs of restarted runs, correct? I have a feeling that this root cause should be tackled, then we don't need this button which seems like a workaround.

return tasks, db.GetEngine(ctx).
Cols("id", "job_id", "attempt", "status", "started", "stopped", "log_expired").
Where("job_id=?", jobID).
OrderBy("attempt ASC").
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since attempt is not indexed, we might could sort it in memory?

@Zettat123
Copy link
Copy Markdown
Contributor

But the root cause is that gitea does not show previous runs of restarted runs, correct? I have a feeling that this root cause should be tackled, then we don't need this button which seems like a workaround.

In GitHub, even if the user only rerun a single job, the system recreates all jobs within that run (meaning all job IDs change in the new attempt). For example:

I actually support this solution. It would simplify the rerun logic since we wouldn't need to modify existing job states - we'd just create new jobs as if it were the first time the run was triggered. Furthermore, this approach would resolve several rerun-related bugs I've encountered while developing #36388.

However, this would be a big task, as it requires refactoring both the rerun logic and the core run-job relationship. We should be cautious before deciding on such a refactor.

@silverwind
Copy link
Copy Markdown
Member

silverwind commented Apr 1, 2026

It would simplify the rerun logic since we wouldn't need to modify existing job states

Yes, runs should be seen as a append-only, that's how it worked in Drone CI and I'm surprised Gitea implements it through mutation. Mutation is the source of many bugs.

Would changing to this way require changes in the runner or just Gitea code?

@Zettat123
Copy link
Copy Markdown
Contributor

Would changing to this way require changes in the runner or just Gitea code?

I'm thinking we could introduce a RunAttempt model. A new RunAttempt record would be created whenever a run is first executed or rerun. We would also create the full set of jobs for every attempt, and a RunAttemptID field would be added to ActionRunJob to link it to the corresponding RunAttempt.

@silverwind
Copy link
Copy Markdown
Member

Would changing to this way require changes in the runner or just Gitea code?

I'm thinking we could introduce a RunAttempt model. A new RunAttempt record would be created whenever a run is first executed or rerun. We would also create the full set of jobs for every attempt, and a RunAttemptID field would be added to ActionRunJob to link it to the corresponding RunAttempt.

Sound reasonable, that would create a clean way of identifiying re-runs, I like it.

@Zettat123
Copy link
Copy Markdown
Contributor

Would changing to this way require changes in the runner or just Gitea code?

I'm thinking we could introduce a RunAttempt model. A new RunAttempt record would be created whenever a run is first executed or rerun. We would also create the full set of jobs for every attempt, and a RunAttemptID field would be added to ActionRunJob to link it to the corresponding RunAttempt.

Sound reasonable, that would create a clean way of identifiying re-runs, I like it.

I will create a PR to implement this in a few days.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 1, 2026

I will create a PR to implement this in a few days.

so how can we continue with this PR?

@Zettat123
Copy link
Copy Markdown
Contributor

I will create a PR to implement this in a few days.

so how can we continue with this PR?

Maybe we can keep parts of this PR so users can still access legacy job attempt logs, but I'm worried about potential conflicts with RunAttempt. Could we mark this PR as a Draft for now and resume work after RunAttempt is introduced?

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 1, 2026

I will create a PR to implement this in a few days.

so how can we continue with this PR?

Maybe we can keep parts of this PR so users can still access legacy job attempt logs, but I'm worried about potential conflicts with RunAttempt. Could we mark this PR as a Draft for now and resume work after RunAttempt is introduced?

yes 100% - I would really really like to see this in 1.26

@bircni bircni marked this pull request as draft April 1, 2026 18:27
@lunny
Copy link
Copy Markdown
Member

lunny commented Apr 1, 2026

I will create a PR to implement this in a few days.

so how can we continue with this PR?

If that PR could be merged, I think this PR could be closed.

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 3, 2026

@Zettat123 any updates on RunAttempt? I'd really like to have this feature in 1.26

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 5, 2026

Any update on this? @Zettat123
Couldn't we start like this and do the RunAttempt Migration after?
I really wanted that in 1.26

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 5, 2026

@silverwind @lunny how can we continue here?

@Zettat123
Copy link
Copy Markdown
Contributor

Any update on this? @Zettat123 Couldn't we start like this and do the RunAttempt Migration after? I really wanted that in 1.26

Thanks for following this feature! It currently has a few bugs that I am working on fixing, but I'll create the PR later today.

@Zettat123
Copy link
Copy Markdown
Contributor

Would changing to this way require changes in the runner or just Gitea code?

I'm thinking we could introduce a RunAttempt model. A new RunAttempt record would be created whenever a run is first executed or rerun. We would also create the full set of jobs for every attempt, and a RunAttemptID field would be added to ActionRunJob to link it to the corresponding RunAttempt.

Sound reasonable, that would create a clean way of identifiying re-runs, I like it.

I will create a PR to implement this in a few days.

PR is created: #37119. It's large and I'm still in the process of testing it. Any testing or reviews are welcome!

@bircni
Copy link
Copy Markdown
Member Author

bircni commented Apr 6, 2026

PR is created: #37119. It's large and I'm still in the process of testing it. Any testing or reviews are welcome!

Will have look at it but I think we have to delay it to 1.27 🫤

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/api This PR adds API routes or modifies them modifies/frontend modifies/go Pull requests that update Go code modifies/templates This PR modifies the template files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants