Skip to content

send workflow url from cli #2048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 24, 2025
Merged

send workflow url from cli #2048

merged 3 commits into from
Jul 24, 2025

Conversation

motatoes
Copy link
Contributor

No description provided.

Copy link
Contributor

bismuthdev bot commented Jul 24, 2025

Bug Summary Report

Total Bugs Found: 3

Bug Summaries

  1. Missing Environment Variable Validation in URL Construction

    • The getWorkflowUrl() function constructs GitHub workflow URLs without validating if required environment variables exist
    • Could result in malformed URLs like "//actions/runs/" when variables are missing
    • Affects user interface by potentially displaying broken links
  2. Lack of URL Format Validation

    • In projects.go, workflow URLs are stored in the database without validating their format
    • Invalid URLs could cause downstream issues in UI displays or when making requests
    • No validation check before storing the URL in the database
  3. Limited CI/CD Platform Support

    • The getWorkflowUrl() function only handles GitHub Actions environments
    • Returns a placeholder "#" for all other CI/CD environments (GitLab CI, Jenkins, CircleCI)
    • Users on non-GitHub platforms don't get proper links to their workflow runs

These bugs primarily affect URL handling and validation, which could impact user experience through broken links and missing workflow information.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR implements a workflow URL optimization feature to reduce GitHub API rate limiting by having the CLI provide workflow URLs directly rather than fetching them through API calls later. The changes span two key areas:

  1. CLI-side enhancement (libs/backendapi/diggerapi.go): Adds two helper functions isGitHubActions() and getWorkflowUrl() that detect when running in GitHub Actions and construct workflow URLs from environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID). The workflow URL is now included in the ReportProjectJobStatus payload sent to the backend.

  2. Backend-side enhancement (backend/controllers/projects.go): Adds a new optional WorkflowUrl field to the SetJobStatusRequest struct and updates the job's WorkflowRunUrl field when a workflow URL is provided during job startup (status = 'started').

This optimization fits into the existing codebase by leveraging the established job status reporting mechanism between CLI and backend. Previously, the system would make additional GitHub API calls after job completion to retrieve workflow URLs (as seen in the existing GetWorkflowIdAndUrlFromDiggerJobId function). Now, the CLI proactively provides this information, reducing API calls and improving rate limit management.

Confidence score: 4/5

  • This is a safe optimization that adds functionality without breaking existing behavior.
  • The implementation is straightforward and follows existing patterns, with proper fallback handling.
  • The backend/controllers/projects.go file needs attention due to potential edge cases around URL validation and existing workflow URL handling logic.

2 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Comment on lines 668 to 670
if request.WorkflowUrl != "" {
job.WorkflowRunUrl = &request.WorkflowUrl
}
Copy link
Contributor

Choose a reason for hiding this comment

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

style: Consider adding debug logging here to track when workflow URL is provided by CLI versus fetched later from GitHub API

Comment on lines +142 to +151
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function constructs a URL using environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID) without validating if they exist or have valid values. If any of these variables are missing or empty, the function will still attempt to construct a URL with empty values, resulting in an invalid URL like "//actions/runs/" or similar malformed URLs.

This could lead to broken links in the application UI or API responses. The fix adds validation to check if any of the required environment variables are missing or empty, and returns a fallback value ("#") in that case, which is consistent with the non-GitHub Actions case.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Validate that all required environment variables are present
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing required GitHub environment variables for workflow URL",
"GITHUB_SERVER_URL", githubServerURL,
"GITHUB_REPOSITORY", githubRepository,
"GITHUB_RUN_ID", githubRunID)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}

Comment on lines +142 to +152
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function constructs a GitHub workflow URL using environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, and GITHUB_RUN_ID) without validating if these variables are actually set. If any of these environment variables are missing, the function will still attempt to construct a URL with empty values, potentially resulting in an invalid URL. This could lead to broken links in the UI or other unexpected behavior.

The fix adds validation to check if the required environment variables are present before constructing the URL. If any of them are missing, it logs a warning with the specific missing variables and returns the fallback value "#" instead.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Validate environment variables are present
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing GitHub environment variables for workflow URL construction",
"GITHUB_SERVER_URL", githubServerURL,
"GITHUB_REPOSITORY", githubRepository,
"GITHUB_RUN_ID", githubRunID,
)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}

Comment on lines 668 to 670
if request.WorkflowUrl != "" {
job.WorkflowRunUrl = &request.WorkflowUrl
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The code doesn't validate the URL format before assigning request.WorkflowUrl to job.WorkflowRunUrl. This could lead to storing invalid URLs in the database, which might cause issues when these URLs are later used (e.g., in UI displays, API responses, or when attempting to make requests to these URLs).

The fix adds URL validation using Go's standard url.Parse() function, which checks if the URL format is valid. If the URL is invalid, it logs a warning and doesn't store the URL. This prevents invalid URLs from being stored in the database while maintaining the existing behavior for valid URLs.

Suggested change
if request.WorkflowUrl != "" {
job.WorkflowRunUrl = &request.WorkflowUrl
}
if request.WorkflowUrl != "" {
// Validate URL format before storing
_, err := url.Parse(request.WorkflowUrl)
if err != nil {
slog.Warn("Invalid workflow URL format",
"jobId", jobId,
"workflowUrl", request.WorkflowUrl,
"error", err,
)
} else {
job.WorkflowRunUrl = &request.WorkflowUrl
}
}

Comment on lines +142 to +151
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function only handles GitHub Actions environments and returns a placeholder "#" for all other CI/CD environments. This means that when the code runs in other CI/CD environments like GitLab CI, Jenkins, or CircleCI, users won't get proper links to their workflow runs.

Each CI/CD platform provides environment variables that can be used to construct workflow URLs:

  1. GitLab CI provides CI_PROJECT_URL and CI_PIPELINE_ID
  2. Jenkins provides JENKINS_URL, JOB_NAME, and BUILD_NUMBER
  3. CircleCI provides CIRCLE_BUILD_URL

The fix adds support for these common CI/CD platforms by checking for their specific environment variables and constructing appropriate workflow URLs for each platform.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else if os.Getenv("GITLAB_CI") == "true" {
// GitLab CI environment
projectURL := os.Getenv("CI_PROJECT_URL")
pipelineID := os.Getenv("CI_PIPELINE_ID")
return fmt.Sprintf("%s/-/pipelines/%s", projectURL, pipelineID)
} else if os.Getenv("JENKINS_URL") != "" {
// Jenkins environment
jenkinsURL := os.Getenv("JENKINS_URL")
jobName := os.Getenv("JOB_NAME")
buildNumber := os.Getenv("BUILD_NUMBER")
return fmt.Sprintf("%s/job/%s/%s", jenkinsURL, jobName, buildNumber)
} else if os.Getenv("CIRCLECI") == "true" {
// CircleCI environment
buildURL := os.Getenv("CIRCLE_BUILD_URL")
if buildURL != "" {
return buildURL
}
return "#"
} else {
return "#"
}

Copy link
Contributor

bismuthdev bot commented Jul 24, 2025

Bug Summary Report

Total Bugs Found: 4

Summary of Bugs

  1. Missing URL Validation in getWorkflowUrl() - The function constructs URLs from environment variables without validating their presence or content, potentially leading to security issues including URL injection attacks, XSS vulnerabilities, and server-side request forgery.

  2. Missing Environment Variable Checks - The getWorkflowUrl() function doesn't verify if required GitHub environment variables are present before using them, which could result in malformed URLs with empty segments.

  3. Incomplete Error Message Formatting - In the updateWorkflowUrlForJob function, an error message contains a formatting placeholder (%v) but no corresponding value is provided, resulting in incomplete error messages.

  4. Invalid URL Construction - The getWorkflowUrl() function doesn't validate that the constructed URL is valid before returning it, which could lead to malformed URLs being stored in the database and displayed to users.

The most critical bugs are the security vulnerabilities in the URL construction process, which could potentially allow for injection attacks if environment variables contain malicious values.

Comment on lines +143 to +148
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function uses environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, and GITHUB_RUN_ID) to construct a URL without any validation or sanitization. This could lead to security issues if these environment variables are manipulated or contain malicious values.

Potential security risks include:

  1. URL injection attacks if the environment variables contain characters that could change the URL structure
  2. XSS vulnerabilities if the constructed URL is later rendered in a web context
  3. Potential server-side request forgery if the URL is used for internal requests

The fix adds validation to:

  1. Check if the environment variables are present
  2. Validate the format of the components before constructing the URL
  3. Log warnings when invalid values are detected

Note: The implementation requires adding two helper functions isValidURLComponent and isValidRunID which should be added to the file to validate the URL components and run ID format.

Suggested change
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Validate environment variables before using them
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing GitHub environment variables for workflow URL construction",
"GITHUB_SERVER_URL", githubServerURL,
"GITHUB_REPOSITORY", githubRepository,
"GITHUB_RUN_ID", githubRunID)
return "#"
}
// Basic validation to prevent URL injection
if !isValidURLComponent(githubServerURL) || !isValidURLComponent(githubRepository) || !isValidRunID(githubRunID) {
slog.Warn("Invalid GitHub environment variables detected",
"GITHUB_SERVER_URL", githubServerURL,
"GITHUB_REPOSITORY", githubRepository,
"GITHUB_RUN_ID", githubRunID)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL

Comment on lines +142 to +151
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function doesn't check if the required GitHub environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, GITHUB_RUN_ID) are present before constructing the workflow URL. If any of these variables are missing, it will create a malformed URL with empty segments like https:///actions/runs/123 or https://github.com//actions/runs/123, which could lead to invalid links in the application.

The fix adds validation to check if all required environment variables are present before constructing the URL, and returns the fallback value (#) if any of them are missing, while also logging a warning message to help with debugging.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Check if all required environment variables are present
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing required GitHub environment variables for workflow URL",
"GITHUB_SERVER_URL", githubServerURL,
"GITHUB_REPOSITORY", githubRepository,
"GITHUB_RUN_ID", githubRunID)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}

} else {
slog.Debug("Workflow URL not found for job",
"jobId", jobId)
return fmt.Errorf("workflow URL not found for job (workflowUrl returned: %v)")
Copy link
Contributor

Choose a reason for hiding this comment

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

The error message in updateWorkflowUrlForJob has a formatting placeholder %v but no value is provided to fill it. This will result in incomplete error messages where the placeholder is not replaced with the actual workflow URL value. The fix adds the workflowUrl variable as a parameter to the fmt.Errorf call to properly format the error message.

Suggested change
return fmt.Errorf("workflow URL not found for job (workflowUrl returned: %v)")
return fmt.Errorf("workflow URL not found for job (workflowUrl returned: %v)", workflowUrl)

Comment on lines +142 to +152
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function constructs a URL from environment variables without validating that the required variables are present or that the resulting URL is valid. This could lead to malformed URLs being stored in the database and potentially displayed to users. The fix adds validation to ensure all required environment variables are present and that the constructed URL is valid before returning it. If any validation fails, it returns a safe fallback value ("#") and logs a warning.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Validate that we have all required components before constructing the URL
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing GitHub environment variables for workflow URL construction",
"serverURL", githubServerURL,
"repository", githubRepository,
"runID", githubRunID)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
// Validate the constructed URL
_, err := url.Parse(workflowURL)
if err != nil {
slog.Warn("Generated invalid workflow URL", "url", workflowURL, "error", err)
return "#"
}
return workflowURL
} else {
return "#"
}
}

Copy link
Contributor

bismuthdev bot commented Jul 24, 2025

Summary of Bugs Found in Codebase

Total bugs found: 3

Bug Summaries

  1. Hardcoded Workflow URL for Non-GitHub Actions Environments

    • The getWorkflowUrl() function returns a hardcoded "#" value for non-GitHub Actions environments
    • This overrides custom URLs from other CI systems like GitLab, Bitbucket, and Buildkite
    • Affects the flexibility of the system when used with non-GitHub CI platforms
  2. Unvalidated URL Construction in getWorkflowUrl()

    • Constructs URLs using environment variables without validation
    • No checks for missing environment variables
    • No validation of URL format
    • No escaping of path components that might contain special characters
    • Could result in malformed workflow URLs
  3. Insufficient GitHub Actions Environment Detection

    • Current implementation only checks a single environment variable (GITHUB_ACTIONS="true")
    • Lacks robustness for detecting GitHub Actions environments
    • Could fail to identify GitHub Actions environments if the primary variable is missing or incorrectly set

The most critical bug is the unvalidated URL construction, as it could lead to malformed URLs that break functionality or potentially create security issues with improperly escaped URL components.

@motatoes motatoes merged commit cc703a9 into develop Jul 24, 2025
12 checks passed
Comment on lines +142 to +152
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function in libs/backendapi/diggerapi.go returns a hardcoded "#" value for non-GitHub Actions environments. This can cause confusion or issues in other CI systems that might have their own workflow URLs.

Looking at the codebase, I found that:

  1. The CiBackend interface in backend/ci_backends/ci_backends.go defines a GetWorkflowUrl method that each CI backend implementation should provide.
  2. Other CI backends like GitLab, Bitbucket, and Buildkite have their own implementations of this method.
  3. When the workflow URL is sent to the backend API in ReportProjectJobStatus, it uses the hardcoded "#" for non-GitHub Actions environments, which overrides any custom URL that might be provided by other CI systems.

By returning an empty string instead of "#", we allow other CI systems to provide their own workflow URLs without being overridden by this hardcoded value. This makes the system more flexible and avoids potential confusion in the UI where a "#" link might not make sense for non-GitHub Actions environments.

Suggested change
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
return "#"
}
}
func getWorkflowUrl() string {
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
} else {
// Return empty string for non-GitHub Actions environments
// This allows other CI systems to provide their own workflow URLs
return ""
}
}

Comment on lines +143 to +148
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
Copy link
Contributor

Choose a reason for hiding this comment

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

The getWorkflowUrl() function constructs a URL using environment variables without any validation. This can lead to malformed URLs if any of the environment variables (GITHUB_SERVER_URL, GITHUB_REPOSITORY, or GITHUB_RUN_ID) contain unexpected characters or are missing.

The bug has several issues:

  1. No validation that the required environment variables exist
  2. No validation that GITHUB_SERVER_URL is a valid URL
  3. No escaping of path components which could contain special characters

The fix:

  • Checks if any required environment variables are missing
  • Validates that the server URL is properly formatted
  • Uses url.PathEscape() to properly escape path components
  • Adds appropriate error logging
  • Returns a fallback URL ("#") when validation fails

This ensures the constructed workflow URL will always be valid, even if environment variables contain unexpected characters or are missing.

Suggested change
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", githubServerURL, githubRepository, githubRunID)
return workflowURL
if isGitHubActions() {
githubServerURL := os.Getenv("GITHUB_SERVER_URL") // e.g., https://github.com
githubRepository := os.Getenv("GITHUB_REPOSITORY") // e.g., diggerhq/demo-opentofu
githubRunID := os.Getenv("GITHUB_RUN_ID") // numeric run ID
// Validate environment variables to prevent malformed URLs
if githubServerURL == "" || githubRepository == "" || githubRunID == "" {
slog.Warn("Missing GitHub environment variables for workflow URL construction",
"serverURL", githubServerURL,
"repository", githubRepository,
"runID", githubRunID)
return "#"
}
// Ensure the URL is properly constructed
serverURL, err := url.Parse(githubServerURL)
if err != nil {
slog.Error("Invalid GitHub server URL", "url", githubServerURL, "error", err)
return "#"
}
workflowURL := fmt.Sprintf("%s/%s/actions/runs/%s", serverURL.String(), url.PathEscape(githubRepository), url.PathEscape(githubRunID))
return workflowURL

Comment on lines +138 to +140
func isGitHubActions() bool {
return os.Getenv("GITHUB_ACTIONS") == "true"
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The current implementation of isGitHubActions() only checks if the environment variable GITHUB_ACTIONS is set to "true". This is potentially problematic because:

  1. There could be cases where the GITHUB_ACTIONS environment variable is not set correctly or is missing, but the code is still running in a GitHub Actions environment.

  2. GitHub's documentation indicates that multiple environment variables are set in GitHub Actions environments, and relying on just one could lead to false negatives.

  3. In some GitHub Actions configurations or custom runners, the environment variables might be set differently.

The fix adds additional checks for other GitHub Actions-specific environment variables (GITHUB_WORKFLOW, GITHUB_RUN_ID, and GITHUB_REPOSITORY) that are typically present in GitHub Actions environments. This creates a more robust detection mechanism that will correctly identify GitHub Actions environments even if the primary environment variable is missing or incorrectly set.

Suggested change
func isGitHubActions() bool {
return os.Getenv("GITHUB_ACTIONS") == "true"
}
func isGitHubActions() bool {
// Check for GITHUB_ACTIONS environment variable
if os.Getenv("GITHUB_ACTIONS") == "true" {
return true
}
// Additional checks for GitHub Actions environment
// Check for other GitHub Actions specific environment variables
if os.Getenv("GITHUB_WORKFLOW") != "" &&
os.Getenv("GITHUB_RUN_ID") != "" &&
os.Getenv("GITHUB_REPOSITORY") != "" {
return true
}
return false
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant