Skip to content

feat: add workflow run logs page and retrieval API#911

Open
mertilginoglu wants to merge 11 commits intostagingfrom
feat/workflow-logs
Open

feat: add workflow run logs page and retrieval API#911
mertilginoglu wants to merge 11 commits intostagingfrom
feat/workflow-logs

Conversation

@mertilginoglu
Copy link
Contributor

@mertilginoglu mertilginoglu commented Mar 12, 2026

Motivation

Helios currently shows workflow run status, but it does not provide an in-app way to inspect the underlying logs. Reviewing failures still requires switching to GitHub.

Description

  • add backend support for workflow run log retrieval, caching, and manifest metadata via /api/workflows/runs/{workflowRunId}/logs
  • normalize and group workflow log files for UI consumption, including workflow conclusion metadata and fallback loading from per-job logs when needed
  • add a dedicated workflow run logs page in the client with grouped file navigation, status badges, log highlighting, refresh, and GitHub deep-linking
  • regenerate OpenAPI client artifacts and add server/client test coverage for the new workflow log flow

Testing Instructions

Prerequisites:

  • GitHub Account without having any additional access-rights (e.g. admin, owner)
  • A repository in Helios with completed workflow runs
  • Ideally one recently completed workflow run and one older completed workflow run to verify both log retrieval paths

Flow:

  1. Log in to Helios as a Developer.
  2. Open a repository that has completed workflow runs.
  3. Navigate to /repo/<repositoryId>/workflow-runs/<workflowRunId>/logs for a recently completed workflow run.
  4. Verify the page first shows a loading state and then renders grouped log files, workflow status/conclusion information, and the Open on GitHub / Refresh Logs actions.
  5. Open multiple log files and verify normalized GitHub markers such as [group], [command], [warning], and [error] are rendered in a readable way.
  6. Repeat the same check with an older completed workflow run and verify logs still load successfully.
  7. Run cd server && ./gradlew :application-server:test.
  8. Run cd server && ./gradlew :application-server:generateOpenApiDocs and cd client && yarn generate:openapi, then verify no additional generated changes remain.

Screenshots

Not attached in this draft.

Checklist

General

Server

  • Code is performant and follows best practices
  • I documented the Java code using JavaDoc style.

Client

  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

@codacy-production
Copy link

codacy-production bot commented Mar 12, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
+3.80% (target: -1.00%) 87.81%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (437fcaa) 8387 2715 32.37%
Head commit (1cd69bd) 8952 (+565) 3238 (+523) 36.17% (+3.80%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#911) 566 497 87.81%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

@mertilginoglu mertilginoglu changed the title Feat/workflow logs feat: add workflow run logs page and retrieval API Mar 13, 2026
@mertilginoglu mertilginoglu force-pushed the feat/workflow-logs branch 15 times, most recently from 4e22087 to 435d434 Compare March 16, 2026 23:53
@mertilginoglu mertilginoglu force-pushed the feat/workflow-logs branch 2 times, most recently from 52b3088 to 1cd69bd Compare March 18, 2026 13:57
@mertilginoglu mertilginoglu marked this pull request as ready for review March 18, 2026 14:01
@mertilginoglu mertilginoglu requested a review from a team as a code owner March 18, 2026 14:01
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1cd69bd1e0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +42 to +44
Optional<WorkflowRunLogManifest> existingManifest = readManifest(runDirectory);
if (existingManifest.isPresent()) {
return new WorkflowRunLogCacheResult(workflowRun, runDirectory, existingManifest.get(), true);

Choose a reason for hiding this comment

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

P1 Badge Refresh cached logs when a workflow run gets a new attempt

If a workflow run is rerun, GitHubWorkflowRunSyncService.process updates the existing WorkflowRun row in place and GitHubWorkflowRunConverter.update records the new runAttempt, but cacheLogs() returns any existing manifest without checking either field. In that scenario /api/workflows/runs/{workflowRunId}/logs — and the new “Refresh Logs” button — will keep serving the previous attempt's archive until the daily cleanup removes it, so users can inspect stale logs for up to a day after a rerun.

Useful? React with 👍 / 👎.

Comment on lines +173 to +177
private void deleteQuietly(Path path) {
try {
Files.deleteIfExists(path);
} catch (IOException e) {
log.warn("Failed to delete temporary workflow log path {}", path, e);

Choose a reason for hiding this comment

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

P2 Badge Propagate cache-delete failures to the cleanup task

This helper swallows every IOException from Files.deleteIfExists, but WorkflowRunLogCleanupTask.cleanRunDirectory increments summary.deleted unless deleteRecursively() throws. When an expired cache contains a file that cannot be removed (for example due to permissions or transient filesystem errors), the task will report the run as deleted and never increment deleteFailures, leaving partial cache data on disk while the cleanup summary says it succeeded.

Useful? React with 👍 / 👎.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant