-
Notifications
You must be signed in to change notification settings - Fork 9
refactor jenkins client #57
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
Conversation
WalkthroughA comprehensive, modular Jenkins client implementation in TypeScript was introduced, featuring a service-oriented architecture with strong typing, centralized configuration, custom error handling, extensible credential strategies, and utility classes. Supporting documentation and type definitions were added. Minor changes to GitLab CI code and related imports were also made for consistency and improved clarity. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant JenkinsClient
participant JenkinsJobService
participant JenkinsBuildService
participant JenkinsCredentialService
participant JenkinsHttpClient
participant Jenkins
User->>JenkinsClient: createJob(options)
JenkinsClient->>JenkinsJobService: createJob(options)
JenkinsJobService->>JenkinsHttpClient: POST /createItem
JenkinsHttpClient->>Jenkins: HTTP Request
Jenkins-->>JenkinsHttpClient: HTTP Response
JenkinsHttpClient-->>JenkinsJobService: JenkinsApiResponse
JenkinsJobService-->>JenkinsClient: JenkinsApiResponse
JenkinsClient-->>User: JenkinsApiResponse
User->>JenkinsClient: build(options)
JenkinsClient->>JenkinsBuildService: triggerBuild(options)
JenkinsBuildService->>JenkinsHttpClient: POST /build
JenkinsHttpClient->>Jenkins: HTTP Request
Jenkins-->>JenkinsHttpClient: HTTP Response
JenkinsHttpClient-->>JenkinsBuildService: JenkinsApiResponse
JenkinsBuildService-->>JenkinsClient: JenkinsApiResponse
JenkinsClient-->>User: JenkinsApiResponse
User->>JenkinsClient: createCredential(...)
JenkinsClient->>JenkinsCredentialService: createCredential(...)
JenkinsCredentialService->>JenkinsHttpClient: POST /credentials
JenkinsHttpClient->>Jenkins: HTTP Request
Jenkins-->>JenkinsHttpClient: HTTP Response
JenkinsHttpClient-->>JenkinsCredentialService: JenkinsApiResponse
JenkinsCredentialService-->>JenkinsClient: JenkinsApiResponse
JenkinsClient-->>User: JenkinsApiResponse
Estimated code review effort4 (~90 minutes) Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
src/api/ci/jenkins/config/jenkins.config.tsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@eslint/js' imported from /eslint.config.js src/api/ci/gitlabciClient.tsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@eslint/js' imported from /eslint.config.js src/api/ci/jenkins/enums/jenkins.enums.tsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@eslint/js' imported from /eslint.config.js
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 13
🔭 Outside diff range comments (1)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts (1)
303-319
: Good integration of the helper method, but there's duplicated conversion logic.While the use of
convertBuildToPipeline
is correct, there's still manual status conversion logic above (lines 241-265) that should also use this helper method for consistency.Consider refactoring the manual status conversion to also use the helper:
- // Map Jenkins build status to our standardized PipelineStatus format - let status = PipelineStatus.UNKNOWN; - - if (buildInfo.building) { - status = PipelineStatus.RUNNING; - } else if (buildInfo.result) { - switch (buildInfo.result.toUpperCase()) { - case 'SUCCESS': - status = PipelineStatus.SUCCESS; - break; - case 'FAILURE': - status = PipelineStatus.FAILURE; - break; - case 'UNSTABLE': - status = PipelineStatus.FAILURE; // Map unstable to failure - break; - case 'ABORTED': - status = PipelineStatus.FAILURE; // Map aborted to failure - break; - case 'NOT_BUILT': - status = PipelineStatus.PENDING; - break; - default: - status = PipelineStatus.UNKNOWN; - } - } - - // If we're filtering by status and this pipeline doesn't match, return null - if (pipelineStatus !== PipelineStatus.UNKNOWN && status !== pipelineStatus) { - return null; - } + // Create a temporary pipeline to get the standardized status + const tempPipeline = this.convertBuildToPipeline(buildInfo, jobName, pullRequest.repository, '', commitSha); + + // If we're filtering by status and this pipeline doesn't match, return null + if (pipelineStatus !== PipelineStatus.UNKNOWN && tempPipeline.status !== pipelineStatus) { + return null; + }
🧹 Nitpick comments (9)
tests/api/ci/jenkinsClient.test.ts (1)
13-13
: Consider using a more descriptive default URL.Setting the default Jenkins URL to an empty string may cause unclear error messages if the environment variable is not set. Consider using a placeholder URL or adding validation.
-const JENKINS_URL = process.env.JENKINS_URL || ''; +const JENKINS_URL = process.env.JENKINS_URL || 'http://localhost:8080';Or add validation:
const JENKINS_URL = process.env.JENKINS_URL; if (!JENKINS_URL) { throw new Error('JENKINS_URL environment variable is required for tests'); }src/api/ci/jenkins/config/jenkins.config.ts (1)
24-30
: Consider making plugin versions configurable.Hardcoded plugin versions may become outdated over time. Consider making these configurable or adding a mechanism to validate/update them.
// Example: Allow override via environment or config PLUGINS: { WORKFLOW_JOB: process.env.JENKINS_WORKFLOW_JOB_PLUGIN || 'workflow-job@2.40', GITHUB: process.env.JENKINS_GITHUB_PLUGIN || 'github@1.37.1', // ... other plugins } as const,src/api/ci/jenkins/types/jenkins.types.ts (3)
1-1
: Fix import ordering and remove unused import.The static analysis correctly identifies import ordering and unused import issues.
-import { JenkinsBuildResult, JenkinsBuildTrigger, CredentialType } from '../enums/jenkins.enums'; +import { JenkinsBuildResult, JenkinsBuildTrigger } from '../enums/jenkins.enums';Note: CredentialType appears to be unused in this file and should be removed unless it's actually needed somewhere not visible in the diff.
6-11
: Consider more specific typing for the generic response wrapper.While the generic
T = any
provides flexibility, it reduces type safety. Consider if specific response types could be defined for common use cases.-export interface JenkinsApiResponse<T = any> { +export interface JenkinsApiResponse<T = unknown> { success: boolean; status: number; data: T; location?: string; }Using
unknown
instead ofany
encourages proper type checking at usage sites.
91-96
: Consider more specific typing for actions and causes.The
any[]
types for actions and causes could be more specific if the Jenkins API structure is known.If the structure of these fields is consistent, consider defining specific interfaces:
// Example if actions have a known structure actions: JenkinsBuildAction[]; causes?: JenkinsBuildCause[];This would improve type safety and IDE support.
src/api/ci/jenkins/README.md (1)
20-43
: Fix missing language specification for the directory structure.The static analysis correctly identifies a missing language specification for the directory structure code block.
-``` +```text jenkins/ ├── enums/ # Enums for Jenkins constants │ └── jenkins.enums.tssrc/api/ci/jenkins/utils/jenkins.utils.ts (1)
123-130
: Consider using an XML library for escapingManual XML escaping can miss edge cases and control characters. Consider using a dedicated XML library for more robust escaping.
private static escapeXml(text: string): string { - return text - .replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); + // Use a library like 'xmlbuilder2' or 'xml-escape' + // Example: return xmlEscape(text); + // For now, keeping the manual implementation + return text + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); }src/api/ci/jenkins/services/jenkins-build.service.ts (1)
299-369
: Refactor complex commit matching logicThis method is quite long and handles multiple matching strategies. Consider breaking it down into smaller, focused methods for better maintainability.
Also, use optional chaining for consistency:
- if (build.displayName && build.displayName.includes(normalizedCommitSha)) { + if (build.displayName?.includes(normalizedCommitSha)) { - } else if (build.description && build.description.includes(normalizedCommitSha)) { + } else if (build.description?.includes(normalizedCommitSha)) {Consider extracting each matching strategy into separate methods:
checkScmRevision(action, normalizedCommitSha)
checkBuildParameters(action, normalizedCommitSha)
checkPullRequestInfo(action, normalizedCommitSha)
- etc.
src/api/ci/jenkins/jenkins.client.ts (1)
353-379
: Well-documented service accessors for advanced use cases.The getter methods provide appropriate access to underlying services for advanced scenarios. The JSDoc comments clearly indicate their purpose.
Consider whether exposing the raw HTTP client (line 377-379) is necessary. It might break encapsulation and allow bypassing of the service layer's logic. If it's truly needed, consider documenting specific use cases or providing a more restricted interface.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
-
src/api/ci/jenkins/README.md
(1 hunks) -
src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks) -
src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks) -
src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks) -
src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks) -
src/api/ci/jenkins/index.ts
(1 hunks) -
src/api/ci/jenkins/jenkins.client.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks) -
src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks) -
src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks) -
src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks) -
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(4 hunks) -
src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks) -
tests/api/ci/jenkinsClient.test.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts (4)
src/api/ci/jenkinsClient.ts (2)
build
(323-360)JenkinsBuild
(29-63)src/api/ci/jenkins/types/jenkins.types.ts (1)
JenkinsBuild
(75-109)src/rhtap/core/integration/ci/ciInterface.ts (2)
Pipeline
(50-50)PipelineStatus
(50-50)src/rhtap/core/integration/ci/pipeline.ts (1)
Pipeline
(17-174)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 ESLint
src/api/ci/jenkins/index.ts
[error] 28-28: Replace ·
with ⏎
(prettier/prettier)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
[error] 5-5: Replace Client
with BuildTrigger
(prettier/prettier)
[error] 6-6: Replace Build
with Client
(prettier/prettier)
[error] 303-307: Replace ⏎············jobName,⏎············buildNumber,⏎············folderName⏎··········
with jobName,·buildNumber,·folderName
(prettier/prettier)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/enums/jenkins.enums.ts
[error] 30-30: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/errors/jenkins.errors.ts
[error] 12-12: Delete ····
(prettier/prettier)
[error] 87-87: Delete ·
(prettier/prettier)
[error] 93-93: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 1-1: Replace axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
with {⏎··JenkinsAuthenticationError,⏎··JenkinsError,⏎··JenkinsRateLimitError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 2-2: Replace ClientConfig,·JenkinsApiResponse
with ApiResponse,·JenkinsClientConfig
(prettier/prettier)
[error] 3-7: Replace {·⏎··JenkinsError,·⏎··JenkinsAuthenticationError,·⏎··JenkinsRateLimitError·⏎}·from·'../errors/jenkins.error
with axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
(prettier/prettier)
[error] 64-68: Replace ⏎················
Jenkins·API·request·failed:·${message},⏎················status,⏎················error⏎··············
with ``Jenkins·API·request·failed:·${message},·status,·error
(prettier/prettier)
[error] 82-82: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 83-83: Delete ·
(prettier/prettier)
[error] 85-85: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 99-99: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 101-101: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 103-103: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 111-111: Delete ····
(prettier/prettier)
[error] 130-130: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 132-132: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 148-148: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 153-153: Delete ····
(prettier/prettier)
[error] 184-184: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/types/jenkins.types.ts
[error] 1-1: Replace JenkinsBuildResult,·JenkinsBuildTrigger,·CredentialType
with CredentialType,·JenkinsBuildResult,·JenkinsBuildTrigger
(prettier/prettier)
[error] 1-1: 'CredentialType' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 6-6: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 91-91: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 95-95: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 141-141: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 142-142: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 150-150: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 155-155: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 156-156: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 158-158: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 1-1: Replace CredentialType·}·from·'../enums/jenkins.enums
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CredentialType·}·from·'../enums/jenkins.enums
(prettier/prettier)
[error] 45-45: Delete ····
(prettier/prettier)
[error] 64-64: Delete ····
(prettier/prettier)
[error] 67-67: Delete ····
(prettier/prettier)
[error] 95-95: Delete ····
(prettier/prettier)
[error] 99-99: Delete ····
(prettier/prettier)
[error] 116-116: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-9: Replace ⏎··JenkinsApiResponse,·⏎··BuildOptions,·⏎··BuildSearchOptions,⏎··WaitForBuildOptions,⏎··JenkinsBuild,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
(prettier/prettier)
[error] 10-10: Replace ·JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
with ⏎··JenkinsBuildNotFoundError,⏎··JenkinsBuildTimeoutError,⏎··JenkinsJobNotFoundError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 10-10: 'JenkinsBuildResult' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 11-11: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 13-13: Replace JenkinsPathBuilder,·
with BuildOptions,⏎··BuildSearchOptions,
(prettier/prettier)
[error] 14-14: Replace TriggerAnalyzer,·
with ApiResponse,⏎··JenkinsBuild,
(prettier/prettier)
[error] 15-15: Replace PollingUtils·
with Job,⏎··WaitForBuildOptions,
(prettier/prettier)
[error] 16-16: Replace utils/jenkins.util
with types/jenkins.type
(prettier/prettier)
[error] 17-17: Delete ·
(prettier/prettier)
[error] 18-18: Replace BuildNotFoundError,·
with PathBuilder,
(prettier/prettier)
[error] 19-19: Replace BuildTimeoutError
with PollingUtils
(prettier/prettier)
[error] 20-20: Replace JobNotFoundError·
with TriggerAnalyzer,
(prettier/prettier)
[error] 21-21: Replace errors/jenkins.error
with utils/jenkins.util
(prettier/prettier)
[error] 35-35: Delete ·
(prettier/prettier)
[error] 36-36: Delete ·
(prettier/prettier)
[error] 38-38: Delete ······
(prettier/prettier)
[error] 40-40: Delete ·
(prettier/prettier)
[error] 41-41: Delete ·
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 48-48: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 57-57: Delete ·
(prettier/prettier)
[error] 58-58: Delete ·
(prettier/prettier)
[error] 64-64: Delete ·
(prettier/prettier)
[error] 65-65: Delete ·
(prettier/prettier)
[error] 66-66: Delete ·
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 70-73: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.JSON⏎······
with path,·JenkinsConfig.HEADERS.JSON
(prettier/prettier)
[error] 77-77: Replace buildInfo
with ⏎··········buildInfo⏎········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 151-151: Delete ·
(prettier/prettier)
[error] 152-152: Delete ·
(prettier/prettier)
[error] 153-153: Delete ·
(prettier/prettier)
[error] 157-159: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.PLAIN,
with path,·JenkinsConfig.HEADERS.PLAIN,·{
(prettier/prettier)
[error] 160-160: Replace {·start:·0·}
with start:·0,
(prettier/prettier)
[error] 161-161: Insert }
(prettier/prettier)
[error] 178-178: Insert ,
(prettier/prettier)
[error] 204-204: Insert ,
(prettier/prettier)
[error] 234-234: Delete ········
(prettier/prettier)
[error] 264-264: Delete ·
(prettier/prettier)
[error] 265-265: Delete ·
(prettier/prettier)
[error] 276-276: Delete ·
(prettier/prettier)
[error] 277-277: Delete ·
(prettier/prettier)
[error] 288-288: Delete ·
(prettier/prettier)
[error] 289-289: Delete ·
(prettier/prettier)
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
[error] 377-377: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-credential.service.ts
[error] 1-2: Replace HttpClient·}·from·'../http/jenkins-http.client';⏎import·{·JenkinsApiResponse·}·from·'../types/jenkins.types
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 4-4: Replace onfig·}·from·'../config/jenkins.config
with redentialError·}·from·'../errors/jenkins.errors
(prettier/prettier)
[error] 5-5: Replace PathBuilder·}·from·'../utils/jenkins.utils
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 7-7: Replace CredentialError·}·from·'../errors/jenkins.error
with ApiResponse·}·from·'../types/jenkins.types';⏎import·{·JenkinsPathBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 30-30: Delete ······
(prettier/prettier)
[error] 33-33: Delete ······
(prettier/prettier)
[error] 35-35: Delete ······
(prettier/prettier)
[error] 57-57: Delete ······
(prettier/prettier)
[error] 60-60: Delete ······
(prettier/prettier)
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 90-90: Delete ······
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 126-126: Delete ······
(prettier/prettier)
[error] 128-128: Delete ······
(prettier/prettier)
[error] 130-130: Delete ······
(prettier/prettier)
[error] 133-136: Replace ⏎········credentialId,⏎········'Credential·not·found·or·not·accessible'⏎······
with credentialId,·'Credential·not·found·or·not·accessible'
(prettier/prettier)
[error] 143-143: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 149-149: Delete ······
(prettier/prettier)
[error] 151-151: Delete ······
(prettier/prettier)
[error] 152-152: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Delete ······
(prettier/prettier)
[error] 188-188: Replace folderName,·credentialId,·secretValue,·CredentialType.USERNAME_PASSWORD
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.USERNAME_PASSWORD⏎····
(prettier/prettier)
[error] 204-204: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 1-1: Replace CreateJobOptions·}·from·'../types/jenkins.types
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CreateJobOptions·}·from·'../types/jenkins.types
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
[error] 242-242: Delete ····
(prettier/prettier)
[error] 245-245: Delete ······
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 253-253: Delete ······
(prettier/prettier)
[error] 264-264: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-job.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-7: Replace ·⏎··JenkinsApiResponse,·⏎··FolderConfig,·⏎··CreateJobOptions,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with ·JenkinsFolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 8-8: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 9-9: Replace ·JenkinsPathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
with ⏎··CreateJobOptions,⏎··FolderConfig,⏎··JenkinsApiResponse,⏎··JenkinsJob,⏎}·from·'../types/jenkins.type
(prettier/prettier)
[error] 10-10: Replace FolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
with PathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 25-25: Delete ······
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 51-51: Delete ······
(prettier/prettier)
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 90-90: Replace ``${path}/doDelete,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/doDelete`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 91-91: Insert );⏎
(prettier/prettier)
[error] 119-119: Delete ·
(prettier/prettier)
[error] 122-122: Delete ······
(prettier/prettier)
[error] 144-144: Replace ``${path}/disable,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/disable`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 145-145: Insert );⏎
(prettier/prettier)
[error] 160-160: Delete ······
(prettier/prettier)
[error] 171-171: Replace jobName:·string,·configXml:·string,·folderName?:·string
with ⏎····jobName:·string,⏎····configXml:·string,⏎····folderName?:·string⏎··
(prettier/prettier)
[error] 174-174: Replace ``${path}/config.xml,·configXml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········configXml,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 175-175: Insert );⏎
(prettier/prettier)
[error] 189-189: Replace ``${path}/config.xml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 190-190: Insert );⏎
(prettier/prettier)
[error] 197-197: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/jenkins.client.ts
[error] 1-1: Replace JenkinsHttpClient·}·from·'./http/jenkins-http.client
with CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enums
(prettier/prettier)
[error] 2-2: Replace JobService·}·from·'./services/jenkins-job.service
with HttpClient·}·from·'./http/jenkins-http.client
(prettier/prettier)
[error] 5-9: Replace ⏎··JenkinsClientConfig,⏎··JenkinsApiResponse,⏎··FolderConfig,⏎··CreateJobOptions,
with JenkinsJobService·}·from·'./services/jenkins-job.service';⏎import·{
(prettier/prettier)
[error] 12-12: Replace WaitForBuild
with CreateJob
(prettier/prettier)
[error] 13-13: Replace JenkinsBuild
with FolderConfig,⏎··JenkinsApiResponse
(prettier/prettier)
[error] 14-14: Replace Job
with Build,
(prettier/prettier)
[error] 15-16: Replace }·from·'./types/jenkins.types';⏎import·{·CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enum
with ··JenkinsClientConfig,⏎··JenkinsJob,⏎··WaitForBuildOptions,⏎}·from·'./types/jenkins.type
(prettier/prettier)
[error] 142-142: Replace folderName,·credentialId,·secretValue,·credentialType
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······credentialType⏎····
(prettier/prettier)
[error] 165-165: Replace folderName,·credentialId,·username,·password
with ⏎······folderName,⏎······credentialId,⏎······username,⏎······password⏎····
(prettier/prettier)
[error] 380-380: Replace ·
with ⏎
(prettier/prettier)
🪛 Biome (1.9.4)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 84-116: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 94-94: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 107-107: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 114-114: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
🔇 Additional comments (23)
src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts (1)
1-1
: LGTM! Import path correctly updated for modular architecture.The import path update aligns with the Jenkins client refactoring to use the centralized module structure. This change supports better organization and maintainability.
tests/api/ci/jenkinsClient.test.ts (1)
5-5
: LGTM! Import path correctly updated for modular architecture.The import path update aligns with the Jenkins client refactoring to use the centralized module structure.
src/api/ci/jenkins/enums/jenkins.enums.ts (1)
1-30
: LGTM! Well-defined enums for type safety.The enums provide excellent type safety and use appropriate string values that align with Jenkins API terminology. The coverage appears comprehensive for the current use cases.
Fix the trailing whitespace issue:
-export enum CredentialType { - SECRET_TEXT = 'Secret text', - USERNAME_PASSWORD = 'Username with password', -} +export enum CredentialType { + SECRET_TEXT = 'Secret text', + USERNAME_PASSWORD = 'Username with password', +}src/api/ci/jenkins/index.ts (1)
1-28
: Excellent barrel export organization!The index file provides a clean, well-organized API surface that supports both backward compatibility and the new modular architecture. The categorized exports make it easy for consumers to understand what's available.
Fix the trailing whitespace issue:
-// Export a facade for backwards compatibility and convenience -export { JenkinsClient } from './jenkins.client'; +// Export a facade for backwards compatibility and convenience +export { JenkinsClient } from './jenkins.client';src/rhtap/core/integration/ci/providers/jenkinsCI.ts (3)
4-7
: Import consolidation looks good but verify enum usage consistency.The updated imports properly use the new typed enums and interfaces from the refactored Jenkins client. This improves type safety and consistency across the codebase.
30-82
: Excellent refactoring with the convertBuildToPipeline helper method.This helper method successfully centralizes the build-to-pipeline conversion logic, eliminating code duplication and improving maintainability. The implementation properly:
- Maps Jenkins build statuses to standardized PipelineStatus enums
- Handles the building state correctly
- Maps various Jenkins result states appropriately (UNSTABLE and ABORTED to FAILURE)
- Serializes build actions for the results field
- Uses the Pipeline.createJenkinsPipeline factory method
394-398
: Perfect usage of the helper method in checkPipelineStatus.The integration of
convertBuildToPipeline
in thecheckPipelineStatus
method is clean and consistent with the refactoring goals.src/api/ci/jenkins/types/jenkins.types.ts (2)
75-109
: Well-designed JenkinsBuild interface with comprehensive coverage.The interface properly captures all essential Jenkins build properties with clear documentation. The use of typed enums for
result
andtriggerType
provides good type safety.
114-158
: Comprehensive JenkinsJob interface covers Jenkins job metadata well.The interface thoroughly covers Jenkins job properties including health reports, build references, and parameter definitions. The structure aligns well with Jenkins API responses.
src/api/ci/jenkins/README.md (2)
1-231
: Excellent comprehensive documentation for the Jenkins client refactor.This README provides outstanding documentation covering:
- Clear architecture overview with benefits
- Detailed directory structure
- Multiple usage examples (legacy, new options-based, direct service access)
- Design patterns explanation
- Extension guidelines
- Testing, performance, and security considerations
The documentation effectively communicates the refactoring goals and how to use the new client architecture.
45-145
: Usage examples are clear and demonstrate both backward compatibility and new features.The code examples effectively show:
- Backward compatibility with existing method signatures
- New options-based approach for better maintainability
- Direct service access for advanced use cases
- Proper error handling with specific error types
These examples will help developers understand the migration path and new capabilities.
src/api/ci/jenkins/strategies/credential.strategy.ts (3)
7-10
: Clean strategy interface design.The
CredentialStrategy
interface provides a clear contract for credential XML generation with proper typing.
15-37
: Secure XML generation with proper escaping.The
SecretTextCredentialStrategy
properly implements XML escaping to prevent injection attacks. The XML structure follows Jenkins credential plugin conventions.
59-69
: Robust password parsing with colon support.The credential parsing logic correctly handles passwords containing colons by rejoining array elements after the first split. This is important for complex passwords.
src/api/ci/jenkins/errors/jenkins.errors.ts (6)
4-18
: Excellent base error class with proper error chaining.The
JenkinsError
base class properly:
- Extends native Error with additional context (statusCode, cause)
- Handles stack trace capture for better debugging
- Provides a foundation for the error hierarchy
23-29
: Well-designed job not found error with path context.The error constructor intelligently builds the job path including folder context, providing clear error messages for debugging.
34-39
: Informative build timeout error with timing context.The timeout error includes all relevant context (job name, build number, timeout duration) for effective debugging.
55-60
: Flexible credential error with contextual information.The credential error design allows for various failure scenarios while maintaining clear error identification.
75-80
: Authentication error with sensible defaults.The authentication error provides a default message while allowing customization, and correctly sets the 401 status code.
85-93
: Rate limit error with retry guidance.The rate limit error intelligently includes retry timing information when available, helping clients implement proper backoff strategies.
src/api/ci/jenkins/jenkins.client.ts (3)
39-44
: Clean delegation pattern for folder operations.The folder creation method correctly delegates to the job service, maintaining proper separation of concerns.
133-167
: Well-designed credential operations with sensible defaults.The credential methods provide a good balance between flexibility and convenience. The default
CredentialType.SECRET_TEXT
is a sensible choice, and the convenience methods enhance usability.
335-347
: Useful utility methods for server health checks.The ping and getVersion methods provide essential functionality for monitoring Jenkins server status and compatibility checks.
export class JenkinsConfig { | ||
public static readonly DEFAULT_BRANCH = 'main'; | ||
public static readonly DEFAULT_JENKINSFILE_PATH = 'Jenkinsfile'; | ||
public static readonly DEFAULT_CREDENTIAL_ID = 'GITOPS_AUTH_PASSWORD'; | ||
public static readonly DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes | ||
public static readonly DEFAULT_POLL_INTERVAL_MS = 5000; // 5 seconds | ||
public static readonly DEFAULT_MAX_BUILDS_TO_CHECK = 50; | ||
|
||
/** | ||
* HTTP headers for different content types | ||
*/ | ||
public static readonly HEADERS = { | ||
XML: { 'Content-Type': 'application/xml' }, | ||
JSON: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, | ||
PLAIN: { 'Accept': 'text/plain' }, | ||
} as const; | ||
|
||
/** | ||
* Jenkins plugin information | ||
*/ | ||
public static readonly PLUGINS = { | ||
WORKFLOW_JOB: 'workflow-job@2.40', | ||
GITHUB: 'github@1.37.1', | ||
WORKFLOW_CPS: 'workflow-cps@2.89', | ||
GIT: 'git@4.4.5', | ||
PLAIN_CREDENTIALS: 'plain-credentials', | ||
} as const; | ||
|
||
/** | ||
* Jenkins API endpoints | ||
*/ | ||
public static readonly ENDPOINTS = { | ||
CREATE_ITEM: 'createItem', | ||
API_JSON: 'api/json', | ||
BUILD: 'build', | ||
BUILD_WITH_PARAMETERS: 'buildWithParameters', | ||
LOG_TEXT: 'logText/progressiveText', | ||
CREDENTIALS_STORE_SYSTEM: 'credentials/store/system/domain/_/createCredentials', | ||
CREDENTIALS_STORE_FOLDER: 'credentials/store/folder/domain/_/createCredentials', | ||
} as const; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor to avoid static-only class anti-pattern.
Using a class with only static members is an anti-pattern. Consider using a namespace, const object, or individual exports instead.
-export class JenkinsConfig {
- public static readonly DEFAULT_BRANCH = 'main';
- public static readonly DEFAULT_JENKINSFILE_PATH = 'Jenkinsfile';
- // ... other static members
-}
+export const JenkinsConfig = {
+ DEFAULT_BRANCH: 'main',
+ DEFAULT_JENKINSFILE_PATH: 'Jenkinsfile',
+ DEFAULT_CREDENTIAL_ID: 'GITOPS_AUTH_PASSWORD',
+ DEFAULT_TIMEOUT_MS: 10 * 60 * 1000, // 10 minutes
+ DEFAULT_POLL_INTERVAL_MS: 5000, // 5 seconds
+ DEFAULT_MAX_BUILDS_TO_CHECK: 50,
+
+ HEADERS: {
+ XML: { 'Content-Type': 'application/xml' },
+ JSON: { 'Content-Type': 'application/json', Accept: 'application/json' },
+ PLAIN: { Accept: 'text/plain' },
+ } as const,
+
+ PLUGINS: {
+ WORKFLOW_JOB: 'workflow-job@2.40',
+ GITHUB: 'github@1.37.1',
+ WORKFLOW_CPS: 'workflow-cps@2.89',
+ GIT: 'git@4.4.5',
+ PLAIN_CREDENTIALS: 'plain-credentials',
+ } as const,
+
+ ENDPOINTS: {
+ CREATE_ITEM: 'createItem',
+ API_JSON: 'api/json',
+ BUILD: 'build',
+ BUILD_WITH_PARAMETERS: 'buildWithParameters',
+ LOG_TEXT: 'logText/progressiveText',
+ CREDENTIALS_STORE_SYSTEM: 'credentials/store/system/domain/_/createCredentials',
+ CREDENTIALS_STORE_FOLDER: 'credentials/store/folder/domain/_/createCredentials',
+ } as const,
+} as const;
This also fixes the prettier formatting issues with quotes and spacing.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export class JenkinsConfig { | |
public static readonly DEFAULT_BRANCH = 'main'; | |
public static readonly DEFAULT_JENKINSFILE_PATH = 'Jenkinsfile'; | |
public static readonly DEFAULT_CREDENTIAL_ID = 'GITOPS_AUTH_PASSWORD'; | |
public static readonly DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes | |
public static readonly DEFAULT_POLL_INTERVAL_MS = 5000; // 5 seconds | |
public static readonly DEFAULT_MAX_BUILDS_TO_CHECK = 50; | |
/** | |
* HTTP headers for different content types | |
*/ | |
public static readonly HEADERS = { | |
XML: { 'Content-Type': 'application/xml' }, | |
JSON: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, | |
PLAIN: { 'Accept': 'text/plain' }, | |
} as const; | |
/** | |
* Jenkins plugin information | |
*/ | |
public static readonly PLUGINS = { | |
WORKFLOW_JOB: 'workflow-job@2.40', | |
GITHUB: 'github@1.37.1', | |
WORKFLOW_CPS: 'workflow-cps@2.89', | |
GIT: 'git@4.4.5', | |
PLAIN_CREDENTIALS: 'plain-credentials', | |
} as const; | |
/** | |
* Jenkins API endpoints | |
*/ | |
public static readonly ENDPOINTS = { | |
CREATE_ITEM: 'createItem', | |
API_JSON: 'api/json', | |
BUILD: 'build', | |
BUILD_WITH_PARAMETERS: 'buildWithParameters', | |
LOG_TEXT: 'logText/progressiveText', | |
CREDENTIALS_STORE_SYSTEM: 'credentials/store/system/domain/_/createCredentials', | |
CREDENTIALS_STORE_FOLDER: 'credentials/store/folder/domain/_/createCredentials', | |
} as const; | |
} | |
export const JenkinsConfig = { | |
DEFAULT_BRANCH: 'main', | |
DEFAULT_JENKINSFILE_PATH: 'Jenkinsfile', | |
DEFAULT_CREDENTIAL_ID: 'GITOPS_AUTH_PASSWORD', | |
DEFAULT_TIMEOUT_MS: 10 * 60 * 1000, // 10 minutes | |
DEFAULT_POLL_INTERVAL_MS: 5000, // 5 seconds | |
DEFAULT_MAX_BUILDS_TO_CHECK: 50, | |
/** | |
* HTTP headers for different content types | |
*/ | |
HEADERS: { | |
XML: { 'Content-Type': 'application/xml' }, | |
JSON: { 'Content-Type': 'application/json', Accept: 'application/json' }, | |
PLAIN: { Accept: 'text/plain' }, | |
} as const, | |
/** | |
* Jenkins plugin information | |
*/ | |
PLUGINS: { | |
WORKFLOW_JOB: 'workflow-job@2.40', | |
GITHUB: 'github@1.37.1', | |
WORKFLOW_CPS: 'workflow-cps@2.89', | |
GIT: 'git@4.4.5', | |
PLAIN_CREDENTIALS: 'plain-credentials', | |
} as const, | |
/** | |
* Jenkins API endpoints | |
*/ | |
ENDPOINTS: { | |
CREATE_ITEM: 'createItem', | |
API_JSON: 'api/json', | |
BUILD: 'build', | |
BUILD_WITH_PARAMETERS: 'buildWithParameters', | |
LOG_TEXT: 'logText/progressiveText', | |
CREDENTIALS_STORE_SYSTEM: 'credentials/store/system/domain/_/createCredentials', | |
CREDENTIALS_STORE_FOLDER: 'credentials/store/folder/domain/_/createCredentials', | |
} as const, | |
} as const; |
🧰 Tools
🪛 Biome (1.9.4)
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
🪛 ESLint
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/config/jenkins.config.ts from lines 4 to 44, the
JenkinsConfig class contains only static members, which is an anti-pattern.
Refactor this by replacing the class with either a namespace or a set of
individual exported constants or objects that hold the same data. This will also
help fix any prettier formatting issues related to quotes and spacing by
allowing more straightforward formatting of the exported constants.
case 429: | ||
const retryAfter = error.response.headers['retry-after']; | ||
throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined); | ||
case 404: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix variable scoping in switch statement
The retryAfter
variable declaration can be accessed by other switch cases, which could lead to unexpected behavior.
case 429:
- const retryAfter = error.response.headers['retry-after'];
- throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined);
+ {
+ const retryAfter = error.response.headers['retry-after'];
+ throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined);
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
case 429: | |
const retryAfter = error.response.headers['retry-after']; | |
throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined); | |
case 404: | |
case 429: | |
{ | |
const retryAfter = error.response.headers['retry-after']; | |
throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined); | |
} | |
case 404: |
🧰 Tools
🪛 Biome (1.9.4)
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/http/jenkins-http.client.ts around lines 58 to 61, the
variable retryAfter is declared directly inside the switch case, making it
accessible to other cases and potentially causing scope-related bugs. To fix
this, wrap the case 429 block in braces {} to create a new block scope, ensuring
retryAfter is scoped only within that case and does not leak to other cases.
if (response.status !== 200 && response.status !== 201) { | ||
throw new JenkinsError( | ||
`Request failed with status ${response.status}: ${response.statusText}`, | ||
response.status | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove redundant status check
This status check is unnecessary because the response interceptor already handles non-2xx status codes by throwing appropriate errors.
const response: AxiosResponse<T> = await this.client.post(path, data, config);
-
- if (response.status !== 200 && response.status !== 201) {
- throw new JenkinsError(
- `Request failed with status ${response.status}: ${response.statusText}`,
- response.status
- );
- }
return {
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (response.status !== 200 && response.status !== 201) { | |
throw new JenkinsError( | |
`Request failed with status ${response.status}: ${response.statusText}`, | |
response.status | |
); | |
} | |
const response: AxiosResponse<T> = await this.client.post(path, data, config); | |
return { |
🤖 Prompt for AI Agents
In src/api/ci/jenkins/http/jenkins-http.client.ts between lines 112 and 117,
remove the redundant if statement that checks if the response status is not 200
or 201 and throws a JenkinsError. This check is unnecessary because the response
interceptor already handles non-2xx status codes by throwing errors, so simply
delete this entire conditional block to avoid duplication.
if (typeof optionsOrJobName === 'string') { | ||
// Legacy method signature | ||
const options: CreateJobOptions = { | ||
jobName: optionsOrJobName, | ||
repoUrl: repoUrl!, | ||
folderName, | ||
branch, | ||
jenkinsfilePath, | ||
credentialId, | ||
}; | ||
return this.jobService.createJob(options); | ||
} else { | ||
// New options object signature | ||
return this.jobService.createJob(optionsOrJobName); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add runtime validation for legacy method parameters.
The non-null assertion on line 74 (repoUrl!
) could cause runtime errors if the method is called with undefined parameters. Consider adding validation:
if (typeof optionsOrJobName === 'string') {
// Legacy method signature
+ if (!repoUrl) {
+ throw new Error('repoUrl is required when using legacy method signature');
+ }
const options: CreateJobOptions = {
jobName: optionsOrJobName,
- repoUrl: repoUrl!,
+ repoUrl: repoUrl,
folderName,
branch,
jenkinsfilePath,
credentialId,
};
return this.jobService.createJob(options);
}
🤖 Prompt for AI Agents
In src/api/ci/jenkins/jenkins.client.ts around lines 70 to 85, the legacy method
uses a non-null assertion on repoUrl which may cause runtime errors if repoUrl
is undefined. Add runtime validation to check if repoUrl is defined before using
it. If repoUrl is missing, throw a clear error or handle the case gracefully to
prevent unexpected failures.
async build( | ||
optionsOrJobName: BuildOptions | string, | ||
folderName?: string, | ||
parameters?: Record<string, string> | ||
): Promise<JenkinsApiResponse> { | ||
if (typeof optionsOrJobName === 'string') { | ||
// Legacy method signature | ||
const options: BuildOptions = { | ||
jobName: optionsOrJobName, | ||
folderName, | ||
parameters, | ||
}; | ||
return this.buildService.triggerBuild(options); | ||
} else { | ||
// New options object signature | ||
return this.buildService.triggerBuild(optionsOrJobName); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add validation for legacy build method parameters.
Similar to the createJob method, the build method should validate parameters when using the legacy signature.
if (typeof optionsOrJobName === 'string') {
// Legacy method signature
const options: BuildOptions = {
jobName: optionsOrJobName,
folderName,
parameters,
};
return this.buildService.triggerBuild(options);
}
Note: This particular method doesn't have non-null assertions, so it's safer than the others.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/api/ci/jenkins/jenkins.client.ts around lines 181 to 198, the build
method uses a legacy signature accepting separate parameters but lacks
validation for these inputs. Add validation checks for the legacy parameters
(optionsOrJobName, folderName, parameters) similar to the createJob method to
ensure they meet expected criteria before proceeding. This will prevent invalid
or missing inputs from causing runtime errors.
console.log(`Found matching commit in lastBuiltRevision: ${buildSha}`); | ||
return true; | ||
} | ||
} | ||
|
||
// Method 2: Check buildsByBranchName | ||
if (action.buildsByBranchName) { | ||
for (const branch in action.buildsByBranchName) { | ||
if (action.buildsByBranchName[branch].revision?.SHA1) { | ||
const branchSha = action.buildsByBranchName[branch].revision.SHA1.toLowerCase(); | ||
if (this.commitShasMatch(branchSha, normalizedCommitSha)) { | ||
console.log(`Found matching commit in buildsByBranchName for branch ${branch}: ${branchSha}`); | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Method 3: Check GIT_COMMIT environment variable in build parameters | ||
if (action.parameters) { | ||
for (const param of action.parameters) { | ||
if ((param.name === 'GIT_COMMIT' || param.name === 'ghprbActualCommit') && param.value) { | ||
const paramSha = param.value.toLowerCase(); | ||
if (this.commitShasMatch(paramSha, normalizedCommitSha)) { | ||
console.log(`Found matching commit in build parameter ${param.name}: ${paramSha}`); | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Method 4: Check pull request related information | ||
if (action._class?.includes('pull-request') && action.pullRequest?.source?.commit) { | ||
const prSha = action.pullRequest.source.commit.toLowerCase(); | ||
if (this.commitShasMatch(prSha, normalizedCommitSha)) { | ||
console.log(`Found matching commit in pull request info: ${prSha}`); | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Method 5: Check in build causes | ||
if (build.causes) { | ||
for (const cause of build.causes) { | ||
if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) { | ||
console.log(`Found matching commit in build causes: ${cause.shortDescription}`); | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
// Method 6: Check in build display name or description | ||
if (build.displayName && build.displayName.includes(normalizedCommitSha)) { | ||
console.log(`Found matching commit in build display name: ${build.displayName}`); | ||
return true; | ||
} else if (build.description && build.description.includes(normalizedCommitSha)) { | ||
console.log(`Found matching commit in build description: ${build.description}`); | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove additional debug console.log statements
This method also contains multiple console.log statements that should be removed or replaced with proper logging.
Remove console.log statements at:
- Line 307
- Line 318
- Line 331
- Line 342
- Line 353
- Line 361
- Line 364
🧰 Tools
🪛 Biome (1.9.4)
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 ESLint
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-build.service.ts between lines 307 and
365, there are multiple console.log statements used for debugging purposes.
Remove all these console.log statements at lines 307, 318, 331, 342, 353, 361,
and 364 to clean up the code. If logging is necessary, replace them with
appropriate logger calls consistent with the project's logging strategy.
const basePath = folderName | ||
? `job/${encodeURIComponent(folderName)}/credentials/store/folder/domain/_/credential/${encodeURIComponent(credentialId)}` | ||
: `credentials/store/system/domain/_/credential/${encodeURIComponent(credentialId)}`; | ||
|
||
const path = `${basePath}/config.xml`; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Extract credential path building to utility method
The path building logic is duplicated across updateCredential
, deleteCredential
, and other methods. Consider adding a helper method to JenkinsPathBuilder
for credential-specific paths.
This would improve maintainability and ensure consistent path construction. Would you like me to generate a utility method for credential path building?
🧰 Tools
🪛 ESLint
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-credential.service.ts around lines 62 to
67, the logic for building the credential path is duplicated in multiple methods
like updateCredential and deleteCredential. To fix this, create a utility method
in JenkinsPathBuilder that accepts folderName and credentialId as parameters and
returns the constructed credential path string. Replace all instances of the
duplicated path construction with calls to this new helper method to improve
maintainability and consistency.
} catch (error) { | ||
const jobPath = options.folderName ? `${options.folderName}/${options.jobName}` : options.jobName; | ||
throw new JenkinsJobNotFoundError(jobPath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use appropriate error type for job creation failure
Throwing JenkinsJobNotFoundError
when job creation fails is semantically incorrect. Consider creating a JenkinsJobCreationError
or using a more generic JenkinsError
with appropriate context.
} catch (error) {
const jobPath = options.folderName ? `${options.folderName}/${options.jobName}` : options.jobName;
- throw new JenkinsJobNotFoundError(jobPath);
+ throw new JenkinsError(
+ `Failed to create job: ${jobPath}`,
+ undefined,
+ error instanceof Error ? error : undefined
+ );
}
🧰 Tools
🪛 ESLint
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-job.service.ts around lines 53 to 56, the
catch block throws a JenkinsJobNotFoundError on job creation failure, which is
semantically incorrect. Replace this with a new error type
JenkinsJobCreationError or a generic JenkinsError that better reflects a job
creation failure, and update the thrown error to include relevant context about
the failure.
private escapeXml(text: string): string { | ||
return text | ||
.replace(/&/g, '&') | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, '''); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
DRY violation: Duplicated XML escaping logic.
Both credential strategies implement identical XML escaping methods. This violates the DRY principle and makes maintenance harder.
Extract the XML escaping to a shared utility function:
+/**
+ * Escape XML special characters to prevent injection
+ */
+function escapeXml(text: string): string {
+ return text
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+}
export class SecretTextCredentialStrategy implements CredentialStrategy {
buildXml(credentialId: string, secretValue: string): string {
return `<org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl plugin="${JenkinsConfig.PLUGINS.PLAIN_CREDENTIALS}">
<scope>GLOBAL</scope>
- <id>${this.escapeXml(credentialId)}</id>
- <description>Secret variable for ${this.escapeXml(credentialId)}</description>
- <secret>${this.escapeXml(secretValue)}</secret>
+ <id>${escapeXml(credentialId)}</id>
+ <description>Secret variable for ${escapeXml(credentialId)}</description>
+ <secret>${escapeXml(secretValue)}</secret>
</org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl>`;
}
- private escapeXml(text: string): string {
- return text
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''');
- }
Apply similar changes to UsernamePasswordCredentialStrategy
.
Also applies to: 71-78
🤖 Prompt for AI Agents
In src/api/ci/jenkins/strategies/credential.strategy.ts around lines 29 to 36
and 71 to 78, the XML escaping logic is duplicated in both credential
strategies. To fix this, extract the escapeXml method into a shared utility
function in a common helper file. Then, replace the duplicated methods in both
strategies by importing and using this shared utility function, ensuring the
code adheres to the DRY principle and is easier to maintain.
export class CredentialStrategyFactory { | ||
private static strategies = new Map<CredentialType, CredentialStrategy>([ | ||
[CredentialType.SECRET_TEXT, new SecretTextCredentialStrategy()], | ||
[CredentialType.USERNAME_PASSWORD, new UsernamePasswordCredentialStrategy()], | ||
]); | ||
|
||
/** | ||
* Create a credential strategy for the given type | ||
*/ | ||
static create(type: CredentialType): CredentialStrategy { | ||
const strategy = this.strategies.get(type); | ||
|
||
if (!strategy) { | ||
throw new Error(`Unsupported credential type: ${type}`); | ||
} | ||
|
||
return strategy; | ||
} | ||
|
||
/** | ||
* Get all supported credential types | ||
*/ | ||
static getSupportedTypes(): CredentialType[] { | ||
return Array.from(this.strategies.keys()); | ||
} | ||
|
||
/** | ||
* Check if a credential type is supported | ||
*/ | ||
static isSupported(type: CredentialType): boolean { | ||
return this.strategies.has(type); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor static-only factory class to use functions or namespace.
The static analysis correctly identifies that this class contains only static members, which can be confusing and is generally not recommended in TypeScript.
Consider refactoring to use module-level functions or a namespace:
-export class CredentialStrategyFactory {
- private static strategies = new Map<CredentialType, CredentialStrategy>([
+const strategies = new Map<CredentialType, CredentialStrategy>([
[CredentialType.SECRET_TEXT, new SecretTextCredentialStrategy()],
[CredentialType.USERNAME_PASSWORD, new UsernamePasswordCredentialStrategy()],
]);
- /**
- * Create a credential strategy for the given type
- */
- static create(type: CredentialType): CredentialStrategy {
- const strategy = this.strategies.get(type);
+/**
+ * Create a credential strategy for the given type
+ */
+export function createCredentialStrategy(type: CredentialType): CredentialStrategy {
+ const strategy = strategies.get(type);
if (!strategy) {
throw new Error(`Unsupported credential type: ${type}`);
}
return strategy;
- }
+}
- /**
- * Get all supported credential types
- */
- static getSupportedTypes(): CredentialType[] {
- return Array.from(this.strategies.keys());
- }
+/**
+ * Get all supported credential types
+ */
+export function getSupportedCredentialTypes(): CredentialType[] {
+ return Array.from(strategies.keys());
+}
- /**
- * Check if a credential type is supported
- */
- static isSupported(type: CredentialType): boolean {
- return this.strategies.has(type);
- }
-}
+/**
+ * Check if a credential type is supported
+ */
+export function isCredentialTypeSupported(type: CredentialType): boolean {
+ return strategies.has(type);
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export class CredentialStrategyFactory { | |
private static strategies = new Map<CredentialType, CredentialStrategy>([ | |
[CredentialType.SECRET_TEXT, new SecretTextCredentialStrategy()], | |
[CredentialType.USERNAME_PASSWORD, new UsernamePasswordCredentialStrategy()], | |
]); | |
/** | |
* Create a credential strategy for the given type | |
*/ | |
static create(type: CredentialType): CredentialStrategy { | |
const strategy = this.strategies.get(type); | |
if (!strategy) { | |
throw new Error(`Unsupported credential type: ${type}`); | |
} | |
return strategy; | |
} | |
/** | |
* Get all supported credential types | |
*/ | |
static getSupportedTypes(): CredentialType[] { | |
return Array.from(this.strategies.keys()); | |
} | |
/** | |
* Check if a credential type is supported | |
*/ | |
static isSupported(type: CredentialType): boolean { | |
return this.strategies.has(type); | |
} | |
} | |
const strategies = new Map<CredentialType, CredentialStrategy>([ | |
[CredentialType.SECRET_TEXT, new SecretTextCredentialStrategy()], | |
[CredentialType.USERNAME_PASSWORD, new UsernamePasswordCredentialStrategy()], | |
]); | |
/** | |
* Create a credential strategy for the given type | |
*/ | |
export function createCredentialStrategy(type: CredentialType): CredentialStrategy { | |
const strategy = strategies.get(type); | |
if (!strategy) { | |
throw new Error(`Unsupported credential type: ${type}`); | |
} | |
return strategy; | |
} | |
/** | |
* Get all supported credential types | |
*/ | |
export function getSupportedCredentialTypes(): CredentialType[] { | |
return Array.from(strategies.keys()); | |
} | |
/** | |
* Check if a credential type is supported | |
*/ | |
export function isCredentialTypeSupported(type: CredentialType): boolean { | |
return strategies.has(type); | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 84-116: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 94-94: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 107-107: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 114-114: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 ESLint
[error] 95-95: Delete ····
(prettier/prettier)
[error] 99-99: Delete ····
(prettier/prettier)
[error] 116-116: Replace ·
with ⏎
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/strategies/credential.strategy.ts between lines 84 and
116, the CredentialStrategyFactory class only contains static members, which is
not recommended in TypeScript. Refactor this class by removing the class
structure and instead implement the functionality as module-level functions or
group them inside a namespace. This involves converting the static methods into
standalone functions and replacing the static strategies map with a module-level
constant, ensuring the same functionality is preserved without using a
static-only class.
bcae555
to
93132aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🔭 Outside diff range comments (2)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts (2)
1-9
: Fix duplicate imports causing compilation errors.The import statement contains duplicate declarations that will prevent compilation:
JenkinsBuildResult
is imported twice (lines 4 and 6)JenkinsBuild
is imported twice (lines 3 and 8)Apply this diff to fix the duplicate imports:
import { CredentialType, JenkinsBuild, JenkinsBuildResult, JenkinsBuildTrigger, - JenkinsBuildResult, JenkinsClient, - JenkinsBuild, } from '../../../../../../src/api/ci/jenkins';
552-600
: Remove duplicate method definition.The
convertBuildToPipeline
method is defined twice in this class (first at lines 32-84). This duplicate definition will cause a compilation error.Remove this duplicate method definition entirely, keeping only the first implementation.
♻️ Duplicate comments (12)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: The static-only class anti-pattern still needs to be addressed.This issue was previously identified and the recommendation to refactor to a const object or namespace remains valid. The current implementation violates the
noStaticOnlyClass
lint rule and has formatting issues.src/api/ci/jenkins/strategies/credential.strategy.ts (2)
29-36
: DRY violation: Duplicated XML escaping logic.Both credential strategies implement identical XML escaping methods. This violates the DRY principle and makes maintenance harder.
Extract the XML escaping to a shared utility function as suggested in the previous review.
Also applies to: 71-78
84-116
: Refactor static-only factory class to use functions or namespace.The static analysis correctly identifies that this class contains only static members, which can be confusing and is generally not recommended in TypeScript.
Consider refactoring to use module-level functions or a namespace as suggested in the previous review.
src/api/ci/jenkins/services/jenkins-credential.service.ts (1)
62-67
: Extract duplicated credential path building logic.The path building logic is duplicated across multiple methods (
updateCredential
,deleteCredential
,getCredential
). This violates the DRY principle and could lead to maintenance issues.Consider extracting this logic to a utility method in
JenkinsPathBuilder
for credential-specific paths as suggested in the previous review.Also applies to: 85-90, 123-128
src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-61
: Fix variable scoping in switch statement.The
retryAfter
variable declaration can be accessed by other switch cases, which could lead to unexpected behavior.Wrap the case 429 block in braces {} to create proper block scope as suggested in the previous review.
112-117
: Remove redundant status check.This status check is unnecessary because the response interceptor already handles non-2xx status codes by throwing appropriate errors.
Remove the redundant if statement as suggested in the previous review.
src/api/ci/jenkins/services/jenkins-job.service.ts (1)
53-56
: Use appropriate error type for job creation failure.Throwing
JenkinsJobNotFoundError
when job creation fails is semantically incorrect. Consider creating aJenkinsJobCreationError
or using a more genericJenkinsError
with appropriate context.} catch (error) { const jobPath = options.folderName ? `${options.folderName}/${options.jobName}` : options.jobName; - throw new JenkinsJobNotFoundError(jobPath); + throw new JenkinsError( + `Failed to create job: ${jobPath}`, + undefined, + error instanceof Error ? error : undefined + ); }src/api/ci/jenkins/services/jenkins-build.service.ts (2)
210-253
: Remove debug console.log statements.Multiple console.log statements appear to be debug code that should not be in production. Consider using a proper logging framework with configurable log levels or removing these statements entirely.
Remove all console.log statements in this method:
- Line 210
- Line 221
- Line 224
- Line 232
- Lines 242-244
- Lines 251-253
307-365
: Remove debug console.log statements and improve optional chaining.This method contains multiple console.log debug statements that should be removed. Additionally, some conditional checks could be simplified with optional chaining.
Remove console.log statements at lines: 307, 318, 331, 342, 353, 361, 364
Apply optional chaining improvements:
- if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) { + if (cause.shortDescription?.includes(normalizedCommitSha)) { console.log(`Found matching commit in build causes: ${cause.shortDescription}`); return true; } - if (build.displayName && build.displayName.includes(normalizedCommitSha)) { + if (build.displayName?.includes(normalizedCommitSha)) { console.log(`Found matching commit in build display name: ${build.displayName}`); return true; - } else if (build.description && build.description.includes(normalizedCommitSha)) { + } else if (build.description?.includes(normalizedCommitSha)) { console.log(`Found matching commit in build description: ${build.description}`); return true; }src/api/ci/jenkins/jenkins.client.ts (3)
70-85
: Add runtime validation for legacy method parameters.The non-null assertion on line 74 (
repoUrl!
) could cause runtime errors if the method is called with undefined parameters. Consider adding validation.if (typeof optionsOrJobName === 'string') { // Legacy method signature + if (!repoUrl) { + throw new Error('repoUrl is required when using legacy method signature'); + } const options: CreateJobOptions = { jobName: optionsOrJobName, - repoUrl: repoUrl!, + repoUrl: repoUrl, folderName, branch, jenkinsfilePath, credentialId, }; return this.jobService.createJob(options); }
244-265
: Validate required parameters in waitForBuildCompletion.The non-null assertion on line 255 should be replaced with proper validation.
if (typeof optionsOrJobName === 'string') { // Legacy method signature + if (buildNumber === undefined) { + throw new Error('buildNumber is required when using legacy method signature'); + } const options: WaitForBuildOptions = { jobName: optionsOrJobName, - buildNumber: buildNumber!, + buildNumber: buildNumber, folderName, timeoutMs, pollIntervalMs, }; return this.buildService.waitForBuildCompletion(options); }
277-296
: Validate required parameters in getBuildByCommitSha.The non-null assertion on line 287 should be replaced with validation.
if (typeof optionsOrJobName === 'string') { // Legacy method signature + if (!commitSha) { + throw new Error('commitSha is required when using legacy method signature'); + } const options: BuildSearchOptions = { jobName: optionsOrJobName, - commitSha: commitSha!, + commitSha: commitSha, folderName, maxBuildsToCheck, }; return this.buildService.getBuildByCommitSha(options); }
🧹 Nitpick comments (7)
src/api/ci/jenkins/enums/jenkins.enums.ts (1)
4-30
: LGTM! Fix minor formatting issue.The enum definitions are well-structured and comprehensive. Just needs a minor formatting fix:
export enum CredentialType { SECRET_TEXT = 'Secret text', USERNAME_PASSWORD = 'Username with password', -} +}src/api/ci/jenkins/index.ts (1)
1-28
: LGTM! Well-organized barrel exports with minor formatting fix needed.The module organization is excellent, providing a clean API surface with logical grouping. Just needs a formatting fix:
// Export a facade for backwards compatibility and convenience -export { JenkinsClient } from './jenkins.client'; +export { JenkinsClient } from './jenkins.client';src/api/ci/jenkins/types/jenkins.types.ts (2)
6-6
: Consider improving type safety for Jenkins API responses.While some
any
types are understandable for dynamic Jenkins API responses, consider creating more specific interfaces where possible to improve type safety:For example, common action types could be defined:
interface ScmAction { _class: string; lastBuiltRevision?: { SHA1: string; branch: Array<{ SHA1: string; name: string }>; }; } interface CauseAction { _class: string; causes: Array<{ shortDescription: string; userId?: string; [key: string]: any; }>; }Also applies to: 91-91, 95-95, 140-142, 150-150, 155-157
158-158
: Fix formatting.downstreamProjects?: any[]; -} +}src/api/ci/jenkins/README.md (1)
20-43
: Add language specification to fenced code block.The directory structure code block is missing a language specification, which affects readability and syntax highlighting.
Apply this diff to add the language specification:
-``` +```text jenkins/ ├── enums/ # Enums for Jenkins constants │ └── jenkins.enums.tssrc/api/ci/jenkins/utils/jenkins.utils.ts (1)
231-264
: Well-implemented polling utility - consider function refactor.The polling logic is excellent with proper timeout handling and generic type support. Consider refactoring to standalone functions:
-export class JenkinsPollingUtils { - static async pollUntil<T>( +export async function pollUntil<T>( pollFn: () => Promise<T>, conditionFn: (result: T) => boolean, timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS, intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS ): Promise<T> { const startTime = Date.now(); while (true) { const result = await pollFn(); if (conditionFn(result)) { return result; } if (Date.now() - startTime > timeoutMs) { throw new Error(`Polling timed out after ${timeoutMs}ms`); } - await this.sleep(intervalMs); + await sleep(intervalMs); } - } +} - static sleep(ms: number): Promise<void> { +export function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); - } -} +}src/api/ci/jenkins/services/jenkins-build.service.ts (1)
75-78
: Avoid type assertion for trigger type.The type assertion
as JenkinsBuildTrigger
could hide type mismatches. Consider ensuringdetermineBuildTrigger
returns the proper enum type.// Determine trigger type if requested if (includeTriggerInfo) { - buildInfo.triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo) as JenkinsBuildTrigger; + buildInfo.triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo); }Ensure
determineBuildTrigger
returnsJenkinsBuildTrigger
enum values instead of strings.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
-
src/api/ci/jenkins/README.md
(1 hunks) -
src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks) -
src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks) -
src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks) -
src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks) -
src/api/ci/jenkins/index.ts
(1 hunks) -
src/api/ci/jenkins/jenkins.client.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks) -
src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks) -
src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks) -
src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks) -
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(2 hunks) -
src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks) -
tests/api/ci/jenkinsClient.test.ts
(1 hunks)
🧬 Code Graph Analysis (2)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 ESLint
src/api/ci/jenkins/types/jenkins.types.ts
[error] 1-1: Replace JenkinsBuildResult,·JenkinsBuildTrigger,·CredentialType
with CredentialType,·JenkinsBuildResult,·JenkinsBuildTrigger
(prettier/prettier)
[error] 1-1: 'CredentialType' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 6-6: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 91-91: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 95-95: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 141-141: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 142-142: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 150-150: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 155-155: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 156-156: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 158-158: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 1-1: Replace CreateJobOptions·}·from·'../types/jenkins.types
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CreateJobOptions·}·from·'../types/jenkins.types
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
[error] 242-242: Delete ····
(prettier/prettier)
[error] 245-245: Delete ······
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 253-253: Delete ······
(prettier/prettier)
[error] 264-264: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-job.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-7: Replace ·⏎··JenkinsApiResponse,·⏎··FolderConfig,·⏎··CreateJobOptions,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with ·JenkinsFolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 8-8: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 9-9: Replace ·JenkinsPathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
with ⏎··CreateJobOptions,⏎··FolderConfig,⏎··JenkinsApiResponse,⏎··JenkinsJob,⏎}·from·'../types/jenkins.type
(prettier/prettier)
[error] 10-10: Replace FolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
with PathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 25-25: Delete ······
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 51-51: Delete ······
(prettier/prettier)
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 90-90: Replace ``${path}/doDelete,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/doDelete`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 91-91: Insert );⏎
(prettier/prettier)
[error] 119-119: Delete ·
(prettier/prettier)
[error] 122-122: Delete ······
(prettier/prettier)
[error] 144-144: Replace ``${path}/disable,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/disable`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 145-145: Insert );⏎
(prettier/prettier)
[error] 160-160: Delete ······
(prettier/prettier)
[error] 171-171: Replace jobName:·string,·configXml:·string,·folderName?:·string
with ⏎····jobName:·string,⏎····configXml:·string,⏎····folderName?:·string⏎··
(prettier/prettier)
[error] 174-174: Replace ``${path}/config.xml,·configXml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········configXml,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 175-175: Insert );⏎
(prettier/prettier)
[error] 189-189: Replace ``${path}/config.xml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 190-190: Insert );⏎
(prettier/prettier)
[error] 197-197: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-credential.service.ts
[error] 1-2: Replace HttpClient·}·from·'../http/jenkins-http.client';⏎import·{·JenkinsApiResponse·}·from·'../types/jenkins.types
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 4-4: Replace onfig·}·from·'../config/jenkins.config
with redentialError·}·from·'../errors/jenkins.errors
(prettier/prettier)
[error] 5-5: Replace PathBuilder·}·from·'../utils/jenkins.utils
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 7-7: Replace CredentialError·}·from·'../errors/jenkins.error
with ApiResponse·}·from·'../types/jenkins.types';⏎import·{·JenkinsPathBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 30-30: Delete ······
(prettier/prettier)
[error] 33-33: Delete ······
(prettier/prettier)
[error] 35-35: Delete ······
(prettier/prettier)
[error] 57-57: Delete ······
(prettier/prettier)
[error] 60-60: Delete ······
(prettier/prettier)
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 90-90: Delete ······
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 126-126: Delete ······
(prettier/prettier)
[error] 128-128: Delete ······
(prettier/prettier)
[error] 130-130: Delete ······
(prettier/prettier)
[error] 133-136: Replace ⏎········credentialId,⏎········'Credential·not·found·or·not·accessible'⏎······
with credentialId,·'Credential·not·found·or·not·accessible'
(prettier/prettier)
[error] 143-143: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 149-149: Delete ······
(prettier/prettier)
[error] 151-151: Delete ······
(prettier/prettier)
[error] 152-152: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Delete ······
(prettier/prettier)
[error] 188-188: Replace folderName,·credentialId,·secretValue,·CredentialType.USERNAME_PASSWORD
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.USERNAME_PASSWORD⏎····
(prettier/prettier)
[error] 204-204: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-9: Replace ⏎··JenkinsApiResponse,·⏎··BuildOptions,·⏎··BuildSearchOptions,⏎··WaitForBuildOptions,⏎··JenkinsBuild,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
(prettier/prettier)
[error] 10-10: Replace ·JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
with ⏎··JenkinsBuildNotFoundError,⏎··JenkinsBuildTimeoutError,⏎··JenkinsJobNotFoundError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 10-10: 'JenkinsBuildResult' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 11-11: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 13-13: Replace JenkinsPathBuilder,·
with BuildOptions,⏎··BuildSearchOptions,
(prettier/prettier)
[error] 14-14: Replace TriggerAnalyzer,·
with ApiResponse,⏎··JenkinsBuild,
(prettier/prettier)
[error] 15-15: Replace PollingUtils·
with Job,⏎··WaitForBuildOptions,
(prettier/prettier)
[error] 16-16: Replace utils/jenkins.util
with types/jenkins.type
(prettier/prettier)
[error] 17-17: Delete ·
(prettier/prettier)
[error] 18-18: Replace BuildNotFoundError,·
with PathBuilder,
(prettier/prettier)
[error] 19-19: Replace BuildTimeoutError
with PollingUtils
(prettier/prettier)
[error] 20-20: Replace JobNotFoundError·
with TriggerAnalyzer,
(prettier/prettier)
[error] 21-21: Replace errors/jenkins.error
with utils/jenkins.util
(prettier/prettier)
[error] 35-35: Delete ·
(prettier/prettier)
[error] 36-36: Delete ·
(prettier/prettier)
[error] 38-38: Delete ······
(prettier/prettier)
[error] 40-40: Delete ·
(prettier/prettier)
[error] 41-41: Delete ·
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 48-48: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 57-57: Delete ·
(prettier/prettier)
[error] 58-58: Delete ·
(prettier/prettier)
[error] 64-64: Delete ·
(prettier/prettier)
[error] 65-65: Delete ·
(prettier/prettier)
[error] 66-66: Delete ·
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 70-73: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.JSON⏎······
with path,·JenkinsConfig.HEADERS.JSON
(prettier/prettier)
[error] 77-77: Replace buildInfo
with ⏎··········buildInfo⏎········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 151-151: Delete ·
(prettier/prettier)
[error] 152-152: Delete ·
(prettier/prettier)
[error] 153-153: Delete ·
(prettier/prettier)
[error] 157-159: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.PLAIN,
with path,·JenkinsConfig.HEADERS.PLAIN,·{
(prettier/prettier)
[error] 160-160: Replace {·start:·0·}
with start:·0,
(prettier/prettier)
[error] 161-161: Insert }
(prettier/prettier)
[error] 178-178: Insert ,
(prettier/prettier)
[error] 204-204: Insert ,
(prettier/prettier)
[error] 234-234: Delete ········
(prettier/prettier)
[error] 264-264: Delete ·
(prettier/prettier)
[error] 265-265: Delete ·
(prettier/prettier)
[error] 276-276: Delete ·
(prettier/prettier)
[error] 277-277: Delete ·
(prettier/prettier)
[error] 288-288: Delete ·
(prettier/prettier)
[error] 289-289: Delete ·
(prettier/prettier)
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
[error] 377-377: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/enums/jenkins.enums.ts
[error] 30-30: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/errors/jenkins.errors.ts
[error] 12-12: Delete ····
(prettier/prettier)
[error] 87-87: Delete ·
(prettier/prettier)
[error] 93-93: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 1-1: Replace axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
with {⏎··JenkinsAuthenticationError,⏎··JenkinsError,⏎··JenkinsRateLimitError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 2-2: Replace ClientConfig,·JenkinsApiResponse
with ApiResponse,·JenkinsClientConfig
(prettier/prettier)
[error] 3-7: Replace {·⏎··JenkinsError,·⏎··JenkinsAuthenticationError,·⏎··JenkinsRateLimitError·⏎}·from·'../errors/jenkins.error
with axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
(prettier/prettier)
[error] 64-68: Replace ⏎················
Jenkins·API·request·failed:·${message},⏎················status,⏎················error⏎··············
with ``Jenkins·API·request·failed:·${message},·status,·error
(prettier/prettier)
[error] 82-82: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 83-83: Delete ·
(prettier/prettier)
[error] 85-85: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 99-99: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 101-101: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 103-103: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 111-111: Delete ····
(prettier/prettier)
[error] 130-130: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 132-132: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 148-148: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 153-153: Delete ····
(prettier/prettier)
[error] 184-184: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/index.ts
[error] 28-28: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/jenkins.client.ts
[error] 1-1: Replace JenkinsHttpClient·}·from·'./http/jenkins-http.client
with CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enums
(prettier/prettier)
[error] 2-2: Replace JobService·}·from·'./services/jenkins-job.service
with HttpClient·}·from·'./http/jenkins-http.client
(prettier/prettier)
[error] 5-9: Replace ⏎··JenkinsClientConfig,⏎··JenkinsApiResponse,⏎··FolderConfig,⏎··CreateJobOptions,
with JenkinsJobService·}·from·'./services/jenkins-job.service';⏎import·{
(prettier/prettier)
[error] 12-12: Replace WaitForBuild
with CreateJob
(prettier/prettier)
[error] 13-13: Replace JenkinsBuild
with FolderConfig,⏎··JenkinsApiResponse
(prettier/prettier)
[error] 14-14: Replace Job
with Build,
(prettier/prettier)
[error] 15-16: Replace }·from·'./types/jenkins.types';⏎import·{·CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enum
with ··JenkinsClientConfig,⏎··JenkinsJob,⏎··WaitForBuildOptions,⏎}·from·'./types/jenkins.type
(prettier/prettier)
[error] 142-142: Replace folderName,·credentialId,·secretValue,·credentialType
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······credentialType⏎····
(prettier/prettier)
[error] 165-165: Replace folderName,·credentialId,·username,·password
with ⏎······folderName,⏎······credentialId,⏎······username,⏎······password⏎····
(prettier/prettier)
[error] 380-380: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 1-1: Replace CredentialType·}·from·'../enums/jenkins.enums
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CredentialType·}·from·'../enums/jenkins.enums
(prettier/prettier)
[error] 45-45: Delete ····
(prettier/prettier)
[error] 64-64: Delete ····
(prettier/prettier)
[error] 67-67: Delete ····
(prettier/prettier)
[error] 95-95: Delete ····
(prettier/prettier)
[error] 99-99: Delete ····
(prettier/prettier)
[error] 116-116: Replace ·
with ⏎
(prettier/prettier)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
[error] 6-6: Parsing error:
(prettier/prettier)
🪛 Biome (1.9.4)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 84-116: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 94-94: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 107-107: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 114-114: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
[error] 6-6: Declarations inside of a import
declaration may not have duplicates
a second declaration of JenkinsBuildResult
is not allowed
JenkinsBuildResult
is first declared here
(parse)
[error] 8-8: Declarations inside of a import
declaration may not have duplicates
a second declaration of JenkinsBuild
is not allowed
JenkinsBuild
is first declared here
(parse)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
✅ Files skipped from review due to trivial changes (1)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/api/ci/jenkinsClient.test.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 ESLint
src/api/ci/jenkins/types/jenkins.types.ts
[error] 1-1: Replace JenkinsBuildResult,·JenkinsBuildTrigger,·CredentialType
with CredentialType,·JenkinsBuildResult,·JenkinsBuildTrigger
(prettier/prettier)
[error] 1-1: 'CredentialType' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 6-6: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 91-91: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 95-95: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 141-141: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 142-142: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 150-150: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 155-155: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 156-156: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 158-158: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 1-1: Replace CreateJobOptions·}·from·'../types/jenkins.types
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CreateJobOptions·}·from·'../types/jenkins.types
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
[error] 242-242: Delete ····
(prettier/prettier)
[error] 245-245: Delete ······
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 253-253: Delete ······
(prettier/prettier)
[error] 264-264: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-job.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-7: Replace ·⏎··JenkinsApiResponse,·⏎··FolderConfig,·⏎··CreateJobOptions,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with ·JenkinsFolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 8-8: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 9-9: Replace ·JenkinsPathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
with ⏎··CreateJobOptions,⏎··FolderConfig,⏎··JenkinsApiResponse,⏎··JenkinsJob,⏎}·from·'../types/jenkins.type
(prettier/prettier)
[error] 10-10: Replace FolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
with PathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 25-25: Delete ······
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 51-51: Delete ······
(prettier/prettier)
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 90-90: Replace ``${path}/doDelete,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/doDelete`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 91-91: Insert );⏎
(prettier/prettier)
[error] 119-119: Delete ·
(prettier/prettier)
[error] 122-122: Delete ······
(prettier/prettier)
[error] 144-144: Replace ``${path}/disable,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/disable`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 145-145: Insert );⏎
(prettier/prettier)
[error] 160-160: Delete ······
(prettier/prettier)
[error] 171-171: Replace jobName:·string,·configXml:·string,·folderName?:·string
with ⏎····jobName:·string,⏎····configXml:·string,⏎····folderName?:·string⏎··
(prettier/prettier)
[error] 174-174: Replace ``${path}/config.xml,·configXml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········configXml,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 175-175: Insert );⏎
(prettier/prettier)
[error] 189-189: Replace ``${path}/config.xml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 190-190: Insert );⏎
(prettier/prettier)
[error] 197-197: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-credential.service.ts
[error] 1-2: Replace HttpClient·}·from·'../http/jenkins-http.client';⏎import·{·JenkinsApiResponse·}·from·'../types/jenkins.types
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 4-4: Replace onfig·}·from·'../config/jenkins.config
with redentialError·}·from·'../errors/jenkins.errors
(prettier/prettier)
[error] 5-5: Replace PathBuilder·}·from·'../utils/jenkins.utils
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 7-7: Replace CredentialError·}·from·'../errors/jenkins.error
with ApiResponse·}·from·'../types/jenkins.types';⏎import·{·JenkinsPathBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 30-30: Delete ······
(prettier/prettier)
[error] 33-33: Delete ······
(prettier/prettier)
[error] 35-35: Delete ······
(prettier/prettier)
[error] 57-57: Delete ······
(prettier/prettier)
[error] 60-60: Delete ······
(prettier/prettier)
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 90-90: Delete ······
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 126-126: Delete ······
(prettier/prettier)
[error] 128-128: Delete ······
(prettier/prettier)
[error] 130-130: Delete ······
(prettier/prettier)
[error] 133-136: Replace ⏎········credentialId,⏎········'Credential·not·found·or·not·accessible'⏎······
with credentialId,·'Credential·not·found·or·not·accessible'
(prettier/prettier)
[error] 143-143: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 149-149: Delete ······
(prettier/prettier)
[error] 151-151: Delete ······
(prettier/prettier)
[error] 152-152: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Delete ······
(prettier/prettier)
[error] 188-188: Replace folderName,·credentialId,·secretValue,·CredentialType.USERNAME_PASSWORD
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.USERNAME_PASSWORD⏎····
(prettier/prettier)
[error] 204-204: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-9: Replace ⏎··JenkinsApiResponse,·⏎··BuildOptions,·⏎··BuildSearchOptions,⏎··WaitForBuildOptions,⏎··JenkinsBuild,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
(prettier/prettier)
[error] 10-10: Replace ·JenkinsBuildResult,·JenkinsBuildTrigger·}·from·'../enums/jenkins.enum
with ⏎··JenkinsBuildNotFoundError,⏎··JenkinsBuildTimeoutError,⏎··JenkinsJobNotFoundError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 10-10: 'JenkinsBuildResult' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 11-11: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 13-13: Replace JenkinsPathBuilder,·
with BuildOptions,⏎··BuildSearchOptions,
(prettier/prettier)
[error] 14-14: Replace TriggerAnalyzer,·
with ApiResponse,⏎··JenkinsBuild,
(prettier/prettier)
[error] 15-15: Replace PollingUtils·
with Job,⏎··WaitForBuildOptions,
(prettier/prettier)
[error] 16-16: Replace utils/jenkins.util
with types/jenkins.type
(prettier/prettier)
[error] 17-17: Delete ·
(prettier/prettier)
[error] 18-18: Replace BuildNotFoundError,·
with PathBuilder,
(prettier/prettier)
[error] 19-19: Replace BuildTimeoutError
with PollingUtils
(prettier/prettier)
[error] 20-20: Replace JobNotFoundError·
with TriggerAnalyzer,
(prettier/prettier)
[error] 21-21: Replace errors/jenkins.error
with utils/jenkins.util
(prettier/prettier)
[error] 35-35: Delete ·
(prettier/prettier)
[error] 36-36: Delete ·
(prettier/prettier)
[error] 38-38: Delete ······
(prettier/prettier)
[error] 40-40: Delete ·
(prettier/prettier)
[error] 41-41: Delete ·
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 48-48: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 57-57: Delete ·
(prettier/prettier)
[error] 58-58: Delete ·
(prettier/prettier)
[error] 64-64: Delete ·
(prettier/prettier)
[error] 65-65: Delete ·
(prettier/prettier)
[error] 66-66: Delete ·
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 70-73: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.JSON⏎······
with path,·JenkinsConfig.HEADERS.JSON
(prettier/prettier)
[error] 77-77: Replace buildInfo
with ⏎··········buildInfo⏎········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 151-151: Delete ·
(prettier/prettier)
[error] 152-152: Delete ·
(prettier/prettier)
[error] 153-153: Delete ·
(prettier/prettier)
[error] 157-159: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.PLAIN,
with path,·JenkinsConfig.HEADERS.PLAIN,·{
(prettier/prettier)
[error] 160-160: Replace {·start:·0·}
with start:·0,
(prettier/prettier)
[error] 161-161: Insert }
(prettier/prettier)
[error] 178-178: Insert ,
(prettier/prettier)
[error] 204-204: Insert ,
(prettier/prettier)
[error] 234-234: Delete ········
(prettier/prettier)
[error] 264-264: Delete ·
(prettier/prettier)
[error] 265-265: Delete ·
(prettier/prettier)
[error] 276-276: Delete ·
(prettier/prettier)
[error] 277-277: Delete ·
(prettier/prettier)
[error] 288-288: Delete ·
(prettier/prettier)
[error] 289-289: Delete ·
(prettier/prettier)
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
[error] 377-377: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/enums/jenkins.enums.ts
[error] 30-30: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/errors/jenkins.errors.ts
[error] 12-12: Delete ····
(prettier/prettier)
[error] 87-87: Delete ·
(prettier/prettier)
[error] 93-93: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 1-1: Replace axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
with {⏎··JenkinsAuthenticationError,⏎··JenkinsError,⏎··JenkinsRateLimitError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 2-2: Replace ClientConfig,·JenkinsApiResponse
with ApiResponse,·JenkinsClientConfig
(prettier/prettier)
[error] 3-7: Replace {·⏎··JenkinsError,·⏎··JenkinsAuthenticationError,·⏎··JenkinsRateLimitError·⏎}·from·'../errors/jenkins.error
with axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
(prettier/prettier)
[error] 64-68: Replace ⏎················
Jenkins·API·request·failed:·${message},⏎················status,⏎················error⏎··············
with ``Jenkins·API·request·failed:·${message},·status,·error
(prettier/prettier)
[error] 82-82: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 83-83: Delete ·
(prettier/prettier)
[error] 85-85: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 99-99: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 101-101: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 103-103: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 111-111: Delete ····
(prettier/prettier)
[error] 130-130: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 132-132: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 148-148: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 153-153: Delete ····
(prettier/prettier)
[error] 184-184: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/index.ts
[error] 28-28: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/jenkins.client.ts
[error] 1-1: Replace JenkinsHttpClient·}·from·'./http/jenkins-http.client
with CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enums
(prettier/prettier)
[error] 2-2: Replace JobService·}·from·'./services/jenkins-job.service
with HttpClient·}·from·'./http/jenkins-http.client
(prettier/prettier)
[error] 5-9: Replace ⏎··JenkinsClientConfig,⏎··JenkinsApiResponse,⏎··FolderConfig,⏎··CreateJobOptions,
with JenkinsJobService·}·from·'./services/jenkins-job.service';⏎import·{
(prettier/prettier)
[error] 12-12: Replace WaitForBuild
with CreateJob
(prettier/prettier)
[error] 13-13: Replace JenkinsBuild
with FolderConfig,⏎··JenkinsApiResponse
(prettier/prettier)
[error] 14-14: Replace Job
with Build,
(prettier/prettier)
[error] 15-16: Replace }·from·'./types/jenkins.types';⏎import·{·CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enum
with ··JenkinsClientConfig,⏎··JenkinsJob,⏎··WaitForBuildOptions,⏎}·from·'./types/jenkins.type
(prettier/prettier)
[error] 142-142: Replace folderName,·credentialId,·secretValue,·credentialType
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······credentialType⏎····
(prettier/prettier)
[error] 165-165: Replace folderName,·credentialId,·username,·password
with ⏎······folderName,⏎······credentialId,⏎······username,⏎······password⏎····
(prettier/prettier)
[error] 380-380: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 1-1: Replace CredentialType·}·from·'../enums/jenkins.enums
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CredentialType·}·from·'../enums/jenkins.enums
(prettier/prettier)
[error] 45-45: Delete ····
(prettier/prettier)
[error] 64-64: Delete ····
(prettier/prettier)
[error] 67-67: Delete ····
(prettier/prettier)
[error] 95-95: Delete ····
(prettier/prettier)
[error] 99-99: Delete ····
(prettier/prettier)
[error] 116-116: Replace ·
with ⏎
(prettier/prettier)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
[error] 6-6: Parsing error:
(prettier/prettier)
🪛 Biome (1.9.4)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 84-116: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 94-94: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 107-107: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 114-114: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
[error] 6-6: Declarations inside of a import
declaration may not have duplicates
a second declaration of JenkinsBuildResult
is not allowed
JenkinsBuildResult
is first declared here
(parse)
[error] 8-8: Declarations inside of a import
declaration may not have duplicates
a second declaration of JenkinsBuild
is not allowed
JenkinsBuild
is first declared here
(parse)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
🔇 Additional comments (13)
src/api/ci/jenkins/errors/jenkins.errors.ts (1)
1-93
: Well-designed error hierarchy with proper inheritance.The error class hierarchy follows TypeScript best practices with:
- Proper inheritance from the base Error class
- Stack trace capture for debugging
- Meaningful error types for different failure scenarios
- Consistent naming and structure
Note: There are minor formatting issues flagged by ESLint (extra spaces and missing newlines) that should be addressed by running the code formatter.
src/api/ci/jenkins/services/jenkins-credential.service.ts (1)
1-204
: Well-structured service with comprehensive credential management.The credential service effectively uses the strategy pattern and provides a complete set of CRUD operations for Jenkins credentials. The error handling is consistent and the convenience methods improve usability.
The service integrates well with the overall architecture and follows TypeScript best practices for dependency injection and error handling.
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
9-184
: Solid HTTP client abstraction with comprehensive error handling.The HTTP client provides a well-structured abstraction layer with:
- Proper Axios configuration and authentication
- Request/response interceptors for logging and error handling
- Structured response formats
- Utility methods for server health checks
The client serves as an effective foundation for the service layer architecture.
src/api/ci/jenkins/services/jenkins-job.service.ts (6)
12-17
: Clean service architecture with dependency injection.The service class follows good design patterns with proper dependency injection and encapsulation.
18-36
: Well-implemented folder creation with proper error handling.The method correctly builds folder XML, encodes parameters, and provides meaningful error context.
59-83
: Well-designed job retrieval methods.The methods provide both direct path access and convenient name-based access with appropriate error handling.
99-112
: Clean implementation of existence check.Good use of exception handling to determine existence without exposing error details to callers.
138-166
: Consistent implementation of job state management.Both enable and disable methods follow the same pattern with appropriate endpoints and error handling.
168-196
: Well-implemented configuration management methods.Both methods correctly handle XML configuration with appropriate headers and error handling.
src/api/ci/jenkins/services/jenkins-build.service.ts (2)
86-167
: Well-implemented build query methods.These methods efficiently query build information with proper null handling and consistent error patterns.
371-376
: Smart SHA comparison implementation.Good implementation that handles both full and shortened SHA comparisons correctly.
src/api/ci/jenkins/jenkins.client.ts (2)
18-33
: Excellent facade pattern implementation.The client provides a clean facade over the service-oriented architecture with proper dependency injection and encapsulation.
349-380
: Excellent service exposure for advanced usage.The getter methods provide clean access to underlying services while maintaining encapsulation. This allows advanced users to access full functionality while keeping the main API simple.
export class JenkinsPathBuilder { | ||
/** | ||
* Build a job path for API calls | ||
*/ | ||
static buildJobPath(jobName: string, folderName?: string): string { | ||
return folderName | ||
? `job/${encodeURIComponent(folderName)}/job/${encodeURIComponent(jobName)}` | ||
: `job/${encodeURIComponent(jobName)}`; | ||
} | ||
|
||
/** | ||
* Build a path for creating items (jobs, folders) | ||
*/ | ||
static buildCreateItemPath(folderName?: string): string { | ||
return folderName | ||
? `job/${encodeURIComponent(folderName)}/${JenkinsConfig.ENDPOINTS.CREATE_ITEM}` | ||
: JenkinsConfig.ENDPOINTS.CREATE_ITEM; | ||
} | ||
|
||
/** | ||
* Build a path for credential operations | ||
*/ | ||
static buildCredentialPath(folderName?: string): string { | ||
return folderName | ||
? `job/${encodeURIComponent(folderName)}/${JenkinsConfig.ENDPOINTS.CREDENTIALS_STORE_FOLDER}` | ||
: JenkinsConfig.ENDPOINTS.CREDENTIALS_STORE_SYSTEM; | ||
} | ||
|
||
/** | ||
* Build a formatted job path for API calls (handles nested folders) | ||
*/ | ||
static buildFormattedJobPath(jobPath: string): string { | ||
return jobPath | ||
.split('/') | ||
.map(segment => `job/${encodeURIComponent(segment)}`) | ||
.join('/'); | ||
} | ||
|
||
/** | ||
* Build build-specific API path | ||
*/ | ||
static buildBuildPath(jobName: string, buildNumber: number, folderName?: string, endpoint: string = ''): string { | ||
const jobPath = this.buildJobPath(jobName, folderName); | ||
return endpoint ? `${jobPath}/${buildNumber}/${endpoint}` : `${jobPath}/${buildNumber}`; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider refactoring static utility class to functions.
The JenkinsPathBuilder
class contains only static methods. Consider refactoring to standalone functions for better tree-shaking and cleaner code. Also, replace this
with the class name in static contexts.
-export class JenkinsPathBuilder {
- /**
- * Build a job path for API calls
- */
- static buildJobPath(jobName: string, folderName?: string): string {
+/**
+ * Build a job path for API calls
+ */
+export function buildJobPath(jobName: string, folderName?: string): string {
return folderName
? `job/${encodeURIComponent(folderName)}/job/${encodeURIComponent(jobName)}`
: `job/${encodeURIComponent(jobName)}`;
- }
+}
- static buildBuildPath(jobName: string, buildNumber: number, folderName?: string, endpoint: string = ''): string {
- const jobPath = this.buildJobPath(jobName, folderName);
+export function buildBuildPath(jobName: string, buildNumber: number, folderName?: string, endpoint: string = ''): string {
+ const jobPath = buildJobPath(jobName, folderName);
return endpoint ? `${jobPath}/${buildNumber}/${endpoint}` : `${jobPath}/${buildNumber}`;
- }
-}
+}
Continue this pattern for all methods in the class.
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Biome (1.9.4)
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 ESLint
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/utils/jenkins.utils.ts between lines 7 and 52, the
JenkinsPathBuilder class only contains static methods and uses 'this' to call
other static methods. Refactor by converting each static method into standalone
exported functions. Replace all 'this' references with direct function calls by
name. Remove the class declaration entirely to improve tree-shaking and simplify
the code structure.
/** | ||
* Utility class for generating Jenkins XML configurations | ||
*/ | ||
export class JenkinsXmlBuilder { | ||
/** | ||
* Build XML configuration for Jenkins folder | ||
*/ | ||
static buildFolderXml(description: string = ''): string { | ||
return `<?xml version='1.1' encoding='UTF-8'?> | ||
<com.cloudbees.hudson.plugins.folder.Folder> | ||
<description>${this.escapeXml(description)}</description> | ||
<properties/> | ||
<folderViews/> | ||
<healthMetrics/> | ||
</com.cloudbees.hudson.plugins.folder.Folder>`; | ||
} | ||
|
||
/** | ||
* Build XML configuration for Jenkins pipeline job | ||
*/ | ||
static buildJobXml(options: CreateJobOptions): string { | ||
const { | ||
repoUrl, | ||
branch = JenkinsConfig.DEFAULT_BRANCH, | ||
jenkinsfilePath = JenkinsConfig.DEFAULT_JENKINSFILE_PATH, | ||
credentialId = JenkinsConfig.DEFAULT_CREDENTIAL_ID | ||
} = options; | ||
|
||
return `<flow-definition plugin="${JenkinsConfig.PLUGINS.WORKFLOW_JOB}"> | ||
<actions/> | ||
<description></description> | ||
<keepDependencies>false</keepDependencies> | ||
<properties> | ||
<org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty> | ||
<triggers> | ||
<com.cloudbees.jenkins.GitHubPushTrigger plugin="${JenkinsConfig.PLUGINS.GITHUB}"> | ||
<spec/> | ||
</com.cloudbees.jenkins.GitHubPushTrigger> | ||
</triggers> | ||
</org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty> | ||
</properties> | ||
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="${JenkinsConfig.PLUGINS.WORKFLOW_CPS}"> | ||
<scm class="hudson.plugins.git.GitSCM" plugin="${JenkinsConfig.PLUGINS.GIT}"> | ||
<configVersion>2</configVersion> | ||
<userRemoteConfigs> | ||
<hudson.plugins.git.UserRemoteConfig> | ||
<url>${this.escapeXml(repoUrl)}</url> | ||
<credentialsId>${this.escapeXml(credentialId)}</credentialsId> | ||
</hudson.plugins.git.UserRemoteConfig> | ||
</userRemoteConfigs> | ||
<branches> | ||
<hudson.plugins.git.BranchSpec> | ||
<name>*/${this.escapeXml(branch)}</name> | ||
</hudson.plugins.git.BranchSpec> | ||
</branches> | ||
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations> | ||
<submoduleCfg class="list"/> | ||
<extensions/> | ||
</scm> | ||
<scriptPath>${this.escapeXml(jenkinsfilePath)}</scriptPath> | ||
<lightweight>true</lightweight> | ||
</definition> | ||
<disabled>false</disabled> | ||
</flow-definition>`; | ||
} | ||
|
||
/** | ||
* Escape XML special characters | ||
*/ | ||
private static escapeXml(text: string): string { | ||
return text | ||
.replace(/&/g, '&') | ||
.replace(/</g, '<') | ||
.replace(/>/g, '>') | ||
.replace(/"/g, '"') | ||
.replace(/'/g, '''); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor XML builder to functions and fix static method references.
Like JenkinsPathBuilder
, this static-only class should be refactored to functions. The XML escaping implementation is excellent and properly handles all special characters.
-export class JenkinsXmlBuilder {
- static buildFolderXml(description: string = ''): string {
+export function buildFolderXml(description: string = ''): string {
return `<?xml version='1.1' encoding='UTF-8'?>
<com.cloudbees.hudson.plugins.folder.Folder>
- <description>${this.escapeXml(description)}</description>
+ <description>${escapeXml(description)}</description>
<properties/>
<folderViews/>
<healthMetrics/>
</com.cloudbees.hudson.plugins.folder.Folder>`;
- }
+}
- private static escapeXml(text: string): string {
+function escapeXml(text: string): string {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
- }
-}
+}
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Biome (1.9.4)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 ESLint
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/utils/jenkins.utils.ts from lines 54 to 131, refactor the
JenkinsXmlBuilder static class into standalone functions to match the style of
JenkinsPathBuilder. Convert each static method (buildFolderXml, buildJobXml,
escapeXml) into separate exported functions. Replace all references to
'this.escapeXml' with direct calls to the escapeXml function. Ensure the
escapeXml function remains private or internal to the module if needed, or
export it if used externally.
export class JenkinsTriggerAnalyzer { | ||
/** | ||
* Determines the trigger type of a Jenkins build | ||
*/ | ||
static determineBuildTrigger(build: any): string { | ||
// Check if build has actions array | ||
if (build.actions && Array.isArray(build.actions)) { | ||
// Look for pull request related information in actions | ||
for (const action of build.actions) { | ||
if (this.isPullRequestTrigger(action)) { | ||
return 'PULL_REQUEST'; | ||
} | ||
} | ||
} | ||
|
||
// Check causes for trigger information | ||
if (build.causes && Array.isArray(build.causes)) { | ||
for (const cause of build.causes) { | ||
const triggerType = this.analyzeCause(cause); | ||
if (triggerType !== 'UNKNOWN') { | ||
return triggerType; | ||
} | ||
} | ||
} | ||
|
||
// Default to PUSH if we have git information but couldn't identify as PR | ||
if (this.hasGitInformation(build)) { | ||
return 'PUSH'; | ||
} | ||
|
||
return 'UNKNOWN'; | ||
} | ||
|
||
/** | ||
* Check if action indicates pull request trigger | ||
*/ | ||
private static isPullRequestTrigger(action: any): boolean { | ||
return action._class?.includes('pull-request') || | ||
action._class?.includes('PullRequestAction') || | ||
action.pullRequest || | ||
(action.parameters && action.parameters.some((p: any) => | ||
p.name?.includes('ghpr') || p.name?.includes('pull') || p.name?.includes('PR'))); | ||
} | ||
|
||
/** | ||
* Analyze build cause to determine trigger type | ||
*/ | ||
private static analyzeCause(cause: any): string { | ||
if (!cause.shortDescription) { | ||
return 'UNKNOWN'; | ||
} | ||
|
||
const description = cause.shortDescription.toLowerCase(); | ||
|
||
if (description.includes('pull request') || description.includes('pr ') || | ||
cause._class?.toLowerCase().includes('pullrequest')) { | ||
return 'PULL_REQUEST'; | ||
} | ||
|
||
if (description.includes('push') || | ||
cause._class?.includes('GitHubPushCause') || | ||
cause._class?.includes('GitLabWebHookCause')) { | ||
return 'PUSH'; | ||
} | ||
|
||
if (description.includes('started by user') || | ||
cause._class?.includes('UserIdCause')) { | ||
return 'MANUAL'; | ||
} | ||
|
||
if (description.includes('timer') || | ||
cause._class?.includes('TimerTrigger')) { | ||
return 'SCHEDULED'; | ||
} | ||
|
||
if (description.includes('remote') || | ||
cause._class?.includes('RemoteCause')) { | ||
return 'API'; | ||
} | ||
|
||
return 'UNKNOWN'; | ||
} | ||
|
||
/** | ||
* Check if build has git information | ||
*/ | ||
private static hasGitInformation(build: any): boolean { | ||
return build.actions && build.actions.some((action: any) => | ||
action._class?.includes('git') || action.lastBuiltRevision || action.buildsByBranchName); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve type safety and code consistency in trigger analyzer.
The JenkinsTriggerAnalyzer
has comprehensive logic but uses any
types and inconsistent optional chaining. Consider:
- Define proper types for build objects instead of using
any
- Use optional chaining consistently
- Consider refactoring to functions
+interface BuildAction {
+ _class?: string;
+ pullRequest?: { source?: { commit?: string } };
+ parameters?: Array<{ name?: string; value?: string }>;
+ lastBuiltRevision?: { SHA1?: string };
+ buildsByBranchName?: Record<string, { revision?: { SHA1?: string } }>;
+}
+
+interface Build {
+ actions?: BuildAction[];
+ causes?: Array<{ shortDescription?: string; _class?: string }>;
+ displayName?: string;
+ description?: string;
+}
-export class JenkinsTriggerAnalyzer {
- static determineBuildTrigger(build: any): string {
+export function determineBuildTrigger(build: Build): string {
// Check if build has actions array
- if (build.actions && Array.isArray(build.actions)) {
+ if (build.actions?.length) {
// Look for pull request related information in actions
for (const action of build.actions) {
- if (this.isPullRequestTrigger(action)) {
+ if (isPullRequestTrigger(action)) {
return 'PULL_REQUEST';
}
}
}
- if (action.parameters && action.parameters.some((p: any) =>
- p.name?.includes('ghpr') || p.name?.includes('pull') || p.name?.includes('PR'))) {
+ if (action.parameters?.some((p) =>
+ p.name?.includes('ghpr') || p.name?.includes('pull') || p.name?.includes('PR'))) {
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Biome (1.9.4)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 ESLint
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/utils/jenkins.utils.ts from lines 136 to 226, the
JenkinsTriggerAnalyzer class uses the any type for build and related objects,
which reduces type safety and code clarity. To fix this, define appropriate
TypeScript interfaces or types for the build, action, and cause objects
reflecting their expected structure. Replace all any types with these defined
types. Also, ensure optional chaining is applied consistently throughout the
code to safely access nested properties. Optionally, refactor some static
methods into standalone functions if it improves readability and modularity.
93132aa
to
139b04a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (19)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: The static-only class anti-pattern issue remains unaddressed.This code segment still has the same structural issue that was previously identified - using a class with only static members.
src/api/ci/jenkins/types/jenkins.types.ts (1)
1-1
: Import issue resolved.The previous review comment about removing unused
CredentialType
import has been addressed - the import now only includes the actually used enums.src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-61
: Fix variable scoping in switch statement.The
retryAfter
variable declaration can be accessed by other switch cases, which could lead to unexpected behavior.case 429: - const retryAfter = error.response.headers['retry-after']; - throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined); + { + const retryAfter = error.response.headers['retry-after']; + throw new JenkinsRateLimitError(retryAfter ? parseInt(retryAfter) : undefined); + }
112-117
: Remove redundant status check.This status check is unnecessary because the response interceptor already handles non-2xx status codes by throwing appropriate errors.
const response: AxiosResponse<T> = await this.client.post(path, data, config); - - if (response.status !== 200 && response.status !== 201) { - throw new JenkinsError( - `Request failed with status ${response.status}: ${response.statusText}`, - response.status - ); - } return {src/api/ci/jenkins/strategies/credential.strategy.ts (6)
29-36
: DRY violation: Extract duplicated XML escaping logic to a shared utility.The XML escaping logic is duplicated across all three credential strategy implementations.
Also applies to: 71-78, 117-124
130-163
: Refactor static-only factory class to module-level functions.The static analysis correctly identifies that this class contains only static members.
15-37
: XML escaping duplication needs addressing.The implementation correctly generates XML for secret text credentials and properly escapes XML characters for security. However, as noted in previous reviews, the XML escaping logic is duplicated across multiple strategy classes.
42-79
: Good credential parsing logic with continued duplication issue.The
parseCredentials
method intelligently handles passwords containing colons by rejoining all parts after the first colon. The XML template structure is appropriate for Jenkins username/password credentials. However, the XML escaping duplication issue from previous reviews remains unaddressed.
84-125
: SSH credential implementation with appropriate parsing strategy.The use of
::
as delimiter for SSH credentials is a good design choice to avoid conflicts with colons in usernames or private keys. The optional passphrase support and XML structure for Jenkins SSH credentials plugin are correctly implemented. The XML escaping duplication issue persists here as well.
130-163
: Static-only class structure needs refactoring.As identified in previous reviews and confirmed by static analysis, this class contains only static members which is not recommended in TypeScript. The functionality is sound, but the structure should be refactored to use module-level functions instead of a static-only class.
src/api/ci/jenkins/services/jenkins-credential.service.ts (1)
62-67
: Extract duplicated credential path building logic to utility method.The path building logic is duplicated across multiple methods.
Also applies to: 85-90, 123-128, 146-151
src/api/ci/jenkins/services/jenkins-job.service.ts (1)
53-56
: Use appropriate error type for job creation failure.Throwing
JenkinsJobNotFoundError
when job creation fails is semantically incorrect.src/api/ci/jenkins/utils/jenkins.utils.ts (3)
7-52
: Refactor static utility class to standalone functions.The
JenkinsPathBuilder
class contains only static methods and should be refactored to functions.
57-131
: Refactor XML builder static class to functions and fix static method references.Like
JenkinsPathBuilder
, this static-only class should be refactored to functions.
136-226
: Improve type safety by defining proper interfaces instead of using 'any'.The
JenkinsTriggerAnalyzer
usesany
types which reduces type safety. Define proper interfaces for build objects.src/api/ci/jenkins/services/jenkins-build.service.ts (1)
210-210
: Remove debug console.log statements from production code.Multiple console.log statements appear to be debug code that should not be in production.
Also applies to: 221-221, 224-224, 232-232, 242-244, 251-253, 307-307, 318-318, 331-331, 342-342, 353-353, 361-361, 364-364
src/api/ci/jenkins/jenkins.client.ts (3)
70-85
: Add runtime validation for legacy method parameters.The non-null assertion on line 74 (
repoUrl!
) could cause runtime errors if the method is called with undefined parameters.
244-265
: Validate required parameters in waitForBuildCompletion.The non-null assertion on line 255 should be replaced with proper validation to prevent runtime errors.
277-296
: Validate required parameters in getBuildByCommitSha.The non-null assertion on line 287 should be replaced with validation to prevent runtime errors.
🧹 Nitpick comments (12)
src/api/ci/jenkins/enums/jenkins.enums.ts (1)
30-30
: Address the TODO and fix formatting.The TODO comment indicates uncertainty about the SSH credential type. Please verify this is correct for Jenkins credential management.
Also fix the formatting issue:
- SSH_USERNAME_PRIVATE_KEY = 'SSH Username with private key',//TODO: need to confirm if this is correct + SSH_USERNAME_PRIVATE_KEY = 'SSH Username with private key', // TODO: need to confirm if this is correctWould you like me to help verify the correct Jenkins credential types?
src/api/ci/jenkins/index.ts (1)
28-28
: Fix trailing whitespace.Remove the trailing whitespace at the end of the line.
-export { JenkinsClient } from './jenkins.client'; +export { JenkinsClient } from './jenkins.client';src/api/ci/jenkins/types/jenkins.types.ts (2)
6-6
: Consider more specific types for Jenkins API responses.While
any
types are sometimes necessary for dynamic API responses, consider creating more specific interfaces for well-known Jenkins API structures to improve type safety.For example, you could define specific interfaces for:
// For actions array export interface JenkinsAction { _class: string; [key: string]: any; } // For health reports export interface JenkinsHealthReport { description: string; iconClassName?: string; iconUrl?: string; score: number; } // For parameter definitions export interface JenkinsParameterDefinition { name: string; type: string; description?: string; defaultParameterValue?: { name: string; value: string | number | boolean; }; }Also applies to: 91-91, 95-95, 140-142, 150-150, 155-157
158-158
: Fix trailing whitespace.Remove the trailing whitespace at the end of the file.
-} +}src/api/ci/jenkins/README.md (1)
20-43
: Specify language for fenced code block.Add a language specification to improve syntax highlighting and markdown compliance.
-``` +```text jenkins/ ├── enums/ # Enums for Jenkins constantssrc/api/ci/jenkins/errors/jenkins.errors.ts (1)
12-12
: Fix formatting issues.Remove extra whitespace and add proper line ending.
this.name = 'JenkinsError'; - + // Capture stack trace if available- const message = retryAfter + const message = retryAfter ? `Rate limit exceeded. Retry after ${retryAfter} seconds.` : 'Rate limit exceeded.';-} +}Also applies to: 87-87, 93-93
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
1-7
: Address formatting and import organization issues.The static analysis tools have identified several formatting inconsistencies that should be addressed for code consistency.
Key formatting issues to fix:
- Import statement ordering and spacing
- Extra spaces and indentation
- Missing newline at end of file
Run your formatter (Prettier) to automatically fix these issues:
npx prettier --write src/api/ci/jenkins/http/jenkins-http.client.tsAlso applies to: 83-85, 99-103, 111-111, 130-132, 136-136, 148-148, 153-153, 184-184
src/api/ci/jenkins/utils/jenkins.utils.ts (1)
231-264
: Consider refactoring polling utility to functions for consistency.For consistency with other utilities, consider refactoring this static-only class to module-level functions.
-export class JenkinsPollingUtils { - static async pollUntil<T>( +export async function pollUntil<T>( pollFn: () => Promise<T>, conditionFn: (result: T) => boolean, timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS, intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS ): Promise<T> { // ... implementation ... - await this.sleep(intervalMs); + await sleep(intervalMs); } -} - static sleep(ms: number): Promise<void> { +export function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); - } +}src/api/ci/jenkins/services/jenkins-build.service.ts (1)
352-352
: Use optional chaining for cleaner null checks.These conditions can be simplified using optional chaining.
- if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) { + if (cause.shortDescription?.includes(normalizedCommitSha)) { - if (build.displayName && build.displayName.includes(normalizedCommitSha)) { + if (build.displayName?.includes(normalizedCommitSha)) { - } else if (build.description && build.description.includes(normalizedCommitSha)) { + } else if (build.description?.includes(normalizedCommitSha)) {Also applies to: 360-360, 363-363
src/api/ci/jenkins/jenkins.client.ts (3)
1-16
: Fix import formatting and organization.The ESLint prettier errors indicate formatting inconsistencies in the import statements. These should be resolved to maintain code consistency.
Apply this diff to fix the import formatting:
-import { JenkinsHttpClient } from './http/jenkins-http.client'; -import { JenkinsJobService } from './services/jenkins-job.service'; -import { JenkinsBuildService } from './services/jenkins-build.service'; -import { JenkinsCredentialService } from './services/jenkins-credential.service'; -import { - JenkinsClientConfig, - JenkinsApiResponse, - FolderConfig, - CreateJobOptions, - BuildOptions, - BuildSearchOptions, - WaitForBuildOptions, - JenkinsBuild, - JenkinsJob -} from './types/jenkins.types'; -import { CredentialType, JenkinsBuildTrigger } from './enums/jenkins.enums'; +import { CredentialType, JenkinsBuildTrigger } from './enums/jenkins.enums'; +import { JenkinsHttpClient } from './http/jenkins-http.client'; +import { JenkinsJobService } from './services/jenkins-job.service'; +import { JenkinsBuildService } from './services/jenkins-build.service'; +import { JenkinsCredentialService } from './services/jenkins-credential.service'; +import { + BuildOptions, + BuildSearchOptions, + CreateJobOptions, + FolderConfig, + JenkinsApiResponse, + JenkinsBuild, + JenkinsClientConfig, + JenkinsJob, + WaitForBuildOptions, +} from './types/jenkins.types';
18-380
: Excellent architectural design with proper separation of concerns.The implementation follows a well-structured facade pattern that:
- Provides a unified interface over multiple specialized services
- Maintains backward compatibility through method overloading
- Enables advanced usage through direct service access
- Organizes operations logically (folder, job, credential, build, utility)
- Demonstrates clear separation of concerns and modularity
The service delegation pattern ensures each service handles its specific domain while the client provides a convenient unified interface.
380-380
: Fix trailing whitespace.Remove the trailing space at the end of the file as indicated by ESLint.
-} +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
-
src/api/ci/gitlabciClient.ts
(1 hunks) -
src/api/ci/jenkins/README.md
(1 hunks) -
src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks) -
src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks) -
src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks) -
src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks) -
src/api/ci/jenkins/index.ts
(1 hunks) -
src/api/ci/jenkins/jenkins.client.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks) -
src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks) -
src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks) -
src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks) -
src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks) -
src/rhtap/core/integration/ci/providers/gitlabCI.ts
(1 hunks) -
src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(2 hunks) -
src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks) -
tests/api/ci/jenkinsClient.test.ts
(1 hunks) -
tsconfig.json
(1 hunks)
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/utils/jenkins.utils.ts (3)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/index.ts (1)
JenkinsConfig
(8-8)src/api/ci/jenkins/types/jenkins.types.ts (1)
CreateJobOptions
(33-40)
🪛 ESLint
src/rhtap/core/integration/ci/providers/gitlabCI.ts
[error] 281-281: 'pipeline' is defined but never used. Allowed unused args must match /^_/u.
(@typescript-eslint/no-unused-vars)
src/api/ci/jenkins/services/jenkins-credential.service.ts
[error] 1-2: Replace HttpClient·}·from·'../http/jenkins-http.client';⏎import·{·JenkinsApiResponse·}·from·'../types/jenkins.types
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 4-4: Replace onfig·}·from·'../config/jenkins.config
with redentialError·}·from·'../errors/jenkins.errors
(prettier/prettier)
[error] 5-5: Replace PathBuilder·}·from·'../utils/jenkins.utils
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 7-7: Replace CredentialError·}·from·'../errors/jenkins.error
with ApiResponse·}·from·'../types/jenkins.types';⏎import·{·JenkinsPathBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 30-30: Delete ······
(prettier/prettier)
[error] 33-33: Delete ······
(prettier/prettier)
[error] 35-35: Delete ······
(prettier/prettier)
[error] 57-57: Delete ······
(prettier/prettier)
[error] 60-60: Delete ······
(prettier/prettier)
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 90-90: Delete ······
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 126-126: Delete ······
(prettier/prettier)
[error] 128-128: Delete ······
(prettier/prettier)
[error] 130-130: Delete ······
(prettier/prettier)
[error] 133-136: Replace ⏎········credentialId,⏎········'Credential·not·found·or·not·accessible'⏎······
with credentialId,·'Credential·not·found·or·not·accessible'
(prettier/prettier)
[error] 143-143: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 149-149: Delete ······
(prettier/prettier)
[error] 151-151: Delete ······
(prettier/prettier)
[error] 152-152: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Delete ······
(prettier/prettier)
[error] 188-188: Replace folderName,·credentialId,·secretValue,·CredentialType.USERNAME_PASSWORD
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.USERNAME_PASSWORD⏎····
(prettier/prettier)
[error] 201-201: Delete ·
(prettier/prettier)
[error] 204-204: Replace folderName,·credentialId,·secretValue,·CredentialType.SSH_USERNAME_PRIVATE_KEY
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.SSH_USERNAME_PRIVATE_KEY⏎····
(prettier/prettier)
[error] 220-220: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-job.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-7: Replace ·⏎··JenkinsApiResponse,·⏎··FolderConfig,·⏎··CreateJobOptions,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with ·JenkinsFolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 8-8: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 9-9: Replace ·JenkinsPathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
with ⏎··CreateJobOptions,⏎··FolderConfig,⏎··JenkinsApiResponse,⏎··JenkinsJob,⏎}·from·'../types/jenkins.type
(prettier/prettier)
[error] 10-10: Replace FolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
with PathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 25-25: Delete ······
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 51-51: Delete ······
(prettier/prettier)
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 90-90: Replace ``${path}/doDelete,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/doDelete`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 91-91: Insert );⏎
(prettier/prettier)
[error] 119-119: Delete ·
(prettier/prettier)
[error] 122-122: Delete ······
(prettier/prettier)
[error] 144-144: Replace ``${path}/disable,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/disable`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 145-145: Insert );⏎
(prettier/prettier)
[error] 160-160: Delete ······
(prettier/prettier)
[error] 171-171: Replace jobName:·string,·configXml:·string,·folderName?:·string
with ⏎····jobName:·string,⏎····configXml:·string,⏎····folderName?:·string⏎··
(prettier/prettier)
[error] 174-174: Replace ``${path}/config.xml,·configXml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········configXml,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 175-175: Insert );⏎
(prettier/prettier)
[error] 189-189: Replace ``${path}/config.xml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 190-190: Insert );⏎
(prettier/prettier)
[error] 197-197: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 1-1: Replace CredentialType·}·from·'../enums/jenkins.enums
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CredentialType·}·from·'../enums/jenkins.enums
(prettier/prettier)
[error] 45-45: Delete ····
(prettier/prettier)
[error] 64-64: Delete ····
(prettier/prettier)
[error] 67-67: Delete ····
(prettier/prettier)
[error] 87-87: Delete ····
(prettier/prettier)
[error] 107-107: Replace 'SSH·credentials·must·be·in·format·"username::privateKey"·or·"username::privateKey::passphrase"');
with ⏎········'SSH·credentials·must·be·in·format·"username::privateKey"·or·"username::privateKey::passphrase"'
(prettier/prettier)
[error] 108-108: Replace ····}
with ······);
(prettier/prettier)
[error] 109-109: Insert }⏎
(prettier/prettier)
[error] 113-113: Delete ····
(prettier/prettier)
[error] 142-142: Delete ····
(prettier/prettier)
[error] 146-146: Delete ····
(prettier/prettier)
[error] 163-163: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-5: Replace ⏎··JenkinsApiResponse,·⏎··BuildOptions,·⏎··BuildSearchOptions,
with JenkinsBuildTrigger·}·from·'../enums/jenkins.enums';⏎import·{
(prettier/prettier)
[error] 6-6: Replace WaitForBuildOptions
with JenkinsBuildNotFoundError
(prettier/prettier)
[error] 7-7: Insert TimeoutError
(prettier/prettier)
[error] 8-8: Insert NotFoundError,
(prettier/prettier)
[error] 9-9: Replace types/jenkins.type
with errors/jenkins.error
(prettier/prettier)
[error] 10-10: Replace BuildTrigger·}·from·'../enums/jenkins.enums
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 11-12: Replace ·JenkinsConfig·}·from·'../config/jenkins.config';⏎import·{·
with ⏎··BuildOptions,⏎··BuildSearchOptions,⏎··JenkinsApiResponse,
(prettier/prettier)
[error] 13-13: Replace PathBuilder,·
with Build,
(prettier/prettier)
[error] 14-14: Replace TriggerAnalyzer,·
with Job,
(prettier/prettier)
[error] 15-15: Replace JenkinsPollingUtils·
with WaitForBuildOptions,
(prettier/prettier)
[error] 16-16: Replace utils/jenkins.util
with types/jenkins.type
(prettier/prettier)
[error] 17-17: Delete ·
(prettier/prettier)
[error] 18-18: Replace BuildNotFoundError,·
with PathBuilder,
(prettier/prettier)
[error] 19-19: Replace BuildTimeoutError
with PollingUtils
(prettier/prettier)
[error] 20-20: Replace JobNotFoundError·
with TriggerAnalyzer,
(prettier/prettier)
[error] 21-21: Replace errors/jenkins.error
with utils/jenkins.util
(prettier/prettier)
[error] 35-35: Delete ·
(prettier/prettier)
[error] 36-36: Delete ·
(prettier/prettier)
[error] 38-38: Delete ······
(prettier/prettier)
[error] 40-40: Delete ·
(prettier/prettier)
[error] 41-41: Delete ·
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 48-48: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 57-57: Delete ·
(prettier/prettier)
[error] 58-58: Delete ·
(prettier/prettier)
[error] 64-64: Delete ·
(prettier/prettier)
[error] 65-65: Delete ·
(prettier/prettier)
[error] 66-66: Delete ·
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 70-73: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.JSON⏎······
with path,·JenkinsConfig.HEADERS.JSON
(prettier/prettier)
[error] 77-77: Replace buildInfo
with ⏎··········buildInfo⏎········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 151-151: Delete ·
(prettier/prettier)
[error] 152-152: Delete ·
(prettier/prettier)
[error] 153-153: Delete ·
(prettier/prettier)
[error] 157-159: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.PLAIN,
with path,·JenkinsConfig.HEADERS.PLAIN,·{
(prettier/prettier)
[error] 160-160: Replace {·start:·0·}
with start:·0,
(prettier/prettier)
[error] 161-161: Insert }
(prettier/prettier)
[error] 178-178: Insert ,
(prettier/prettier)
[error] 204-204: Insert ,
(prettier/prettier)
[error] 234-234: Delete ········
(prettier/prettier)
[error] 264-264: Delete ·
(prettier/prettier)
[error] 265-265: Delete ·
(prettier/prettier)
[error] 276-276: Delete ·
(prettier/prettier)
[error] 277-277: Delete ·
(prettier/prettier)
[error] 288-288: Delete ·
(prettier/prettier)
[error] 289-289: Delete ·
(prettier/prettier)
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
[error] 377-377: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/enums/jenkins.enums.ts
[error] 30-30: Insert ·
(prettier/prettier)
[error] 31-31: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/errors/jenkins.errors.ts
[error] 12-12: Delete ····
(prettier/prettier)
[error] 87-87: Delete ·
(prettier/prettier)
[error] 93-93: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 1-1: Replace axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
with {⏎··JenkinsAuthenticationError,⏎··JenkinsError,⏎··JenkinsRateLimitError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 2-2: Replace ClientConfig,·JenkinsApiResponse
with ApiResponse,·JenkinsClientConfig
(prettier/prettier)
[error] 3-7: Replace {·⏎··JenkinsError,·⏎··JenkinsAuthenticationError,·⏎··JenkinsRateLimitError·⏎}·from·'../errors/jenkins.error
with axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
(prettier/prettier)
[error] 64-68: Replace ⏎················
Jenkins·API·request·failed:·${message},⏎················status,⏎················error⏎··············
with ``Jenkins·API·request·failed:·${message},·status,·error
(prettier/prettier)
[error] 82-82: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 83-83: Delete ·
(prettier/prettier)
[error] 85-85: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 99-99: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 101-101: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 103-103: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 111-111: Delete ····
(prettier/prettier)
[error] 130-130: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 132-132: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 148-148: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 153-153: Delete ····
(prettier/prettier)
[error] 184-184: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/index.ts
[error] 28-28: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/jenkins.client.ts
[error] 1-1: Replace JenkinsHttpClient·}·from·'./http/jenkins-http.client
with CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enums
(prettier/prettier)
[error] 2-2: Replace JobService·}·from·'./services/jenkins-job.service
with HttpClient·}·from·'./http/jenkins-http.client
(prettier/prettier)
[error] 5-9: Replace ⏎··JenkinsClientConfig,⏎··JenkinsApiResponse,⏎··FolderConfig,⏎··CreateJobOptions,
with JenkinsJobService·}·from·'./services/jenkins-job.service';⏎import·{
(prettier/prettier)
[error] 12-12: Replace WaitForBuild
with CreateJob
(prettier/prettier)
[error] 13-13: Replace JenkinsBuild
with FolderConfig,⏎··JenkinsApiResponse
(prettier/prettier)
[error] 14-14: Replace Job
with Build,
(prettier/prettier)
[error] 15-16: Replace }·from·'./types/jenkins.types';⏎import·{·CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enum
with ··JenkinsClientConfig,⏎··JenkinsJob,⏎··WaitForBuildOptions,⏎}·from·'./types/jenkins.type
(prettier/prettier)
[error] 142-142: Replace folderName,·credentialId,·secretValue,·credentialType
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······credentialType⏎····
(prettier/prettier)
[error] 165-165: Replace folderName,·credentialId,·username,·password
with ⏎······folderName,⏎······credentialId,⏎······username,⏎······password⏎····
(prettier/prettier)
[error] 380-380: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/types/jenkins.types.ts
[error] 6-6: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 91-91: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 95-95: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 141-141: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 142-142: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 150-150: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 155-155: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 156-156: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 158-158: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 1-1: Replace CreateJobOptions·}·from·'../types/jenkins.types
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CreateJobOptions·}·from·'../types/jenkins.types
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
[error] 242-242: Delete ····
(prettier/prettier)
[error] 245-245: Delete ······
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 253-253: Delete ······
(prettier/prettier)
[error] 264-264: Replace ·
with ⏎
(prettier/prettier)
🪛 Biome (1.9.4)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
✅ Files skipped from review due to trivial changes (2)
- tests/api/ci/jenkinsClient.test.ts
- src/rhtap/core/integration/ci/providers/jenkinsCI.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/utils/jenkins.utils.ts (3)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/index.ts (1)
JenkinsConfig
(8-8)src/api/ci/jenkins/types/jenkins.types.ts (1)
CreateJobOptions
(33-40)
🪛 ESLint
src/rhtap/core/integration/ci/providers/gitlabCI.ts
[error] 281-281: 'pipeline' is defined but never used. Allowed unused args must match /^_/u.
(@typescript-eslint/no-unused-vars)
src/api/ci/jenkins/services/jenkins-credential.service.ts
[error] 1-2: Replace HttpClient·}·from·'../http/jenkins-http.client';⏎import·{·JenkinsApiResponse·}·from·'../types/jenkins.types
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 4-4: Replace onfig·}·from·'../config/jenkins.config
with redentialError·}·from·'../errors/jenkins.errors
(prettier/prettier)
[error] 5-5: Replace PathBuilder·}·from·'../utils/jenkins.utils
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 7-7: Replace CredentialError·}·from·'../errors/jenkins.error
with ApiResponse·}·from·'../types/jenkins.types';⏎import·{·JenkinsPathBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 30-30: Delete ······
(prettier/prettier)
[error] 33-33: Delete ······
(prettier/prettier)
[error] 35-35: Delete ······
(prettier/prettier)
[error] 57-57: Delete ······
(prettier/prettier)
[error] 60-60: Delete ······
(prettier/prettier)
[error] 65-65: Delete ······
(prettier/prettier)
[error] 67-67: Delete ······
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 90-90: Delete ······
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 126-126: Delete ······
(prettier/prettier)
[error] 128-128: Delete ······
(prettier/prettier)
[error] 130-130: Delete ······
(prettier/prettier)
[error] 133-136: Replace ⏎········credentialId,⏎········'Credential·not·found·or·not·accessible'⏎······
with credentialId,·'Credential·not·found·or·not·accessible'
(prettier/prettier)
[error] 143-143: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 149-149: Delete ······
(prettier/prettier)
[error] 151-151: Delete ······
(prettier/prettier)
[error] 152-152: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Delete ······
(prettier/prettier)
[error] 188-188: Replace folderName,·credentialId,·secretValue,·CredentialType.USERNAME_PASSWORD
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.USERNAME_PASSWORD⏎····
(prettier/prettier)
[error] 201-201: Delete ·
(prettier/prettier)
[error] 204-204: Replace folderName,·credentialId,·secretValue,·CredentialType.SSH_USERNAME_PRIVATE_KEY
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······CredentialType.SSH_USERNAME_PRIVATE_KEY⏎····
(prettier/prettier)
[error] 220-220: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-job.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-7: Replace ·⏎··JenkinsApiResponse,·⏎··FolderConfig,·⏎··CreateJobOptions,⏎··JenkinsJob⏎}·from·'../types/jenkins.type
with ·JenkinsFolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 8-8: Replace Config·}·from·'../config/jenkins.config
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 9-9: Replace ·JenkinsPathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
with ⏎··CreateJobOptions,⏎··FolderConfig,⏎··JenkinsApiResponse,⏎··JenkinsJob,⏎}·from·'../types/jenkins.type
(prettier/prettier)
[error] 10-10: Replace FolderError,·JenkinsJobNotFoundError·}·from·'../errors/jenkins.error
with PathBuilder,·JenkinsXmlBuilder·}·from·'../utils/jenkins.util
(prettier/prettier)
[error] 25-25: Delete ······
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 51-51: Delete ······
(prettier/prettier)
[error] 54-54: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 90-90: Replace ``${path}/doDelete,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/doDelete`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 91-91: Insert );⏎
(prettier/prettier)
[error] 119-119: Delete ·
(prettier/prettier)
[error] 122-122: Delete ······
(prettier/prettier)
[error] 144-144: Replace ``${path}/disable,·'',·JenkinsConfig.HEADERS.JSON);
with `⏎········`${path}/disable`,⏎········'',⏎········JenkinsConfig.HEADERS.JSON`
(prettier/prettier)
[error] 145-145: Insert );⏎
(prettier/prettier)
[error] 160-160: Delete ······
(prettier/prettier)
[error] 171-171: Replace jobName:·string,·configXml:·string,·folderName?:·string
with ⏎····jobName:·string,⏎····configXml:·string,⏎····folderName?:·string⏎··
(prettier/prettier)
[error] 174-174: Replace ``${path}/config.xml,·configXml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········configXml,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 175-175: Insert );⏎
(prettier/prettier)
[error] 189-189: Replace ``${path}/config.xml,·JenkinsConfig.HEADERS.XML);
with `⏎········`${path}/config.xml`,⏎········JenkinsConfig.HEADERS.XML`
(prettier/prettier)
[error] 190-190: Insert );⏎
(prettier/prettier)
[error] 197-197: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 1-1: Replace CredentialType·}·from·'../enums/jenkins.enums
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CredentialType·}·from·'../enums/jenkins.enums
(prettier/prettier)
[error] 45-45: Delete ····
(prettier/prettier)
[error] 64-64: Delete ····
(prettier/prettier)
[error] 67-67: Delete ····
(prettier/prettier)
[error] 87-87: Delete ····
(prettier/prettier)
[error] 107-107: Replace 'SSH·credentials·must·be·in·format·"username::privateKey"·or·"username::privateKey::passphrase"');
with ⏎········'SSH·credentials·must·be·in·format·"username::privateKey"·or·"username::privateKey::passphrase"'
(prettier/prettier)
[error] 108-108: Replace ····}
with ······);
(prettier/prettier)
[error] 109-109: Insert }⏎
(prettier/prettier)
[error] 113-113: Delete ····
(prettier/prettier)
[error] 142-142: Delete ····
(prettier/prettier)
[error] 146-146: Delete ····
(prettier/prettier)
[error] 163-163: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 1-1: Replace HttpClient·}·from·'../http/jenkins-http.client
with Config·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-5: Replace ⏎··JenkinsApiResponse,·⏎··BuildOptions,·⏎··BuildSearchOptions,
with JenkinsBuildTrigger·}·from·'../enums/jenkins.enums';⏎import·{
(prettier/prettier)
[error] 6-6: Replace WaitForBuildOptions
with JenkinsBuildNotFoundError
(prettier/prettier)
[error] 7-7: Insert TimeoutError
(prettier/prettier)
[error] 8-8: Insert NotFoundError,
(prettier/prettier)
[error] 9-9: Replace types/jenkins.type
with errors/jenkins.error
(prettier/prettier)
[error] 10-10: Replace BuildTrigger·}·from·'../enums/jenkins.enums
with HttpClient·}·from·'../http/jenkins-http.client
(prettier/prettier)
[error] 11-12: Replace ·JenkinsConfig·}·from·'../config/jenkins.config';⏎import·{·
with ⏎··BuildOptions,⏎··BuildSearchOptions,⏎··JenkinsApiResponse,
(prettier/prettier)
[error] 13-13: Replace PathBuilder,·
with Build,
(prettier/prettier)
[error] 14-14: Replace TriggerAnalyzer,·
with Job,
(prettier/prettier)
[error] 15-15: Replace JenkinsPollingUtils·
with WaitForBuildOptions,
(prettier/prettier)
[error] 16-16: Replace utils/jenkins.util
with types/jenkins.type
(prettier/prettier)
[error] 17-17: Delete ·
(prettier/prettier)
[error] 18-18: Replace BuildNotFoundError,·
with PathBuilder,
(prettier/prettier)
[error] 19-19: Replace BuildTimeoutError
with PollingUtils
(prettier/prettier)
[error] 20-20: Replace JobNotFoundError·
with TriggerAnalyzer,
(prettier/prettier)
[error] 21-21: Replace errors/jenkins.error
with utils/jenkins.util
(prettier/prettier)
[error] 35-35: Delete ·
(prettier/prettier)
[error] 36-36: Delete ·
(prettier/prettier)
[error] 38-38: Delete ······
(prettier/prettier)
[error] 40-40: Delete ·
(prettier/prettier)
[error] 41-41: Delete ·
(prettier/prettier)
[error] 42-42: Delete ·
(prettier/prettier)
[error] 45-45: Delete ······
(prettier/prettier)
[error] 48-48: Replace ·?·
${options.folderName}/${options.jobName}`` with ⏎········?·
${options.folderName}/${options.jobName}`⏎·······`
(prettier/prettier)
[error] 57-57: Delete ·
(prettier/prettier)
[error] 58-58: Delete ·
(prettier/prettier)
[error] 64-64: Delete ·
(prettier/prettier)
[error] 65-65: Delete ·
(prettier/prettier)
[error] 66-66: Delete ·
(prettier/prettier)
[error] 69-69: Delete ······
(prettier/prettier)
[error] 70-73: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.JSON⏎······
with path,·JenkinsConfig.HEADERS.JSON
(prettier/prettier)
[error] 77-77: Replace buildInfo
with ⏎··········buildInfo⏎········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 151-151: Delete ·
(prettier/prettier)
[error] 152-152: Delete ·
(prettier/prettier)
[error] 153-153: Delete ·
(prettier/prettier)
[error] 157-159: Replace ⏎········path,⏎········JenkinsConfig.HEADERS.PLAIN,
with path,·JenkinsConfig.HEADERS.PLAIN,·{
(prettier/prettier)
[error] 160-160: Replace {·start:·0·}
with start:·0,
(prettier/prettier)
[error] 161-161: Insert }
(prettier/prettier)
[error] 178-178: Insert ,
(prettier/prettier)
[error] 204-204: Insert ,
(prettier/prettier)
[error] 234-234: Delete ········
(prettier/prettier)
[error] 264-264: Delete ·
(prettier/prettier)
[error] 265-265: Delete ·
(prettier/prettier)
[error] 276-276: Delete ·
(prettier/prettier)
[error] 277-277: Delete ·
(prettier/prettier)
[error] 288-288: Delete ·
(prettier/prettier)
[error] 289-289: Delete ·
(prettier/prettier)
[error] 318-318: Replace Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}
with ⏎··················
Found·matching·commit·in·buildsByBranchName·for·branch·${branch}:·${branchSha}⏎················
(prettier/prettier)
[error] 328-328: Replace (param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&·param.value
with ⏎··············(param.name·===·'GIT_COMMIT'·||·param.name·===·'ghprbActualCommit')·&&⏎··············param.value⏎············
(prettier/prettier)
[error] 377-377: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 11-11: Delete ··
(prettier/prettier)
[error] 17-17: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 18-18: Replace 'Accept'
with Accept
(prettier/prettier)
[error] 44-44: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/enums/jenkins.enums.ts
[error] 30-30: Insert ·
(prettier/prettier)
[error] 31-31: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/errors/jenkins.errors.ts
[error] 12-12: Delete ····
(prettier/prettier)
[error] 87-87: Delete ·
(prettier/prettier)
[error] 93-93: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 1-1: Replace axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
with {⏎··JenkinsAuthenticationError,⏎··JenkinsError,⏎··JenkinsRateLimitError,⏎}·from·'../errors/jenkins.error
(prettier/prettier)
[error] 2-2: Replace ClientConfig,·JenkinsApiResponse
with ApiResponse,·JenkinsClientConfig
(prettier/prettier)
[error] 3-7: Replace {·⏎··JenkinsError,·⏎··JenkinsAuthenticationError,·⏎··JenkinsRateLimitError·⏎}·from·'../errors/jenkins.error
with axios,·{·AxiosInstance,·AxiosRequestConfig,·AxiosResponse·}·from·'axio
(prettier/prettier)
[error] 64-68: Replace ⏎················
Jenkins·API·request·failed:·${message},⏎················status,⏎················error⏎··············
with ``Jenkins·API·request·failed:·${message},·status,·error
(prettier/prettier)
[error] 82-82: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 83-83: Delete ·
(prettier/prettier)
[error] 85-85: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 99-99: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 101-101: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 103-103: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 111-111: Delete ····
(prettier/prettier)
[error] 130-130: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 132-132: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 148-148: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 153-153: Delete ····
(prettier/prettier)
[error] 184-184: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/index.ts
[error] 28-28: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/jenkins.client.ts
[error] 1-1: Replace JenkinsHttpClient·}·from·'./http/jenkins-http.client
with CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enums
(prettier/prettier)
[error] 2-2: Replace JobService·}·from·'./services/jenkins-job.service
with HttpClient·}·from·'./http/jenkins-http.client
(prettier/prettier)
[error] 5-9: Replace ⏎··JenkinsClientConfig,⏎··JenkinsApiResponse,⏎··FolderConfig,⏎··CreateJobOptions,
with JenkinsJobService·}·from·'./services/jenkins-job.service';⏎import·{
(prettier/prettier)
[error] 12-12: Replace WaitForBuild
with CreateJob
(prettier/prettier)
[error] 13-13: Replace JenkinsBuild
with FolderConfig,⏎··JenkinsApiResponse
(prettier/prettier)
[error] 14-14: Replace Job
with Build,
(prettier/prettier)
[error] 15-16: Replace }·from·'./types/jenkins.types';⏎import·{·CredentialType,·JenkinsBuildTrigger·}·from·'./enums/jenkins.enum
with ··JenkinsClientConfig,⏎··JenkinsJob,⏎··WaitForBuildOptions,⏎}·from·'./types/jenkins.type
(prettier/prettier)
[error] 142-142: Replace folderName,·credentialId,·secretValue,·credentialType
with ⏎······folderName,⏎······credentialId,⏎······secretValue,⏎······credentialType⏎····
(prettier/prettier)
[error] 165-165: Replace folderName,·credentialId,·username,·password
with ⏎······folderName,⏎······credentialId,⏎······username,⏎······password⏎····
(prettier/prettier)
[error] 380-380: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/types/jenkins.types.ts
[error] 6-6: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 91-91: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 95-95: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 141-141: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 142-142: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 150-150: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 155-155: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 156-156: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 157-157: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 158-158: Replace ·
with ⏎
(prettier/prettier)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 1-1: Replace CreateJobOptions·}·from·'../types/jenkins.types
with JenkinsConfig·}·from·'../config/jenkins.config
(prettier/prettier)
[error] 2-2: Replace JenkinsConfig·}·from·'../config/jenkins.config
with CreateJobOptions·}·from·'../types/jenkins.types
(prettier/prettier)
[error] 12-12: Delete ·
(prettier/prettier)
[error] 21-21: Delete ·
(prettier/prettier)
[error] 48-48: Replace jobName:·string,·buildNumber:·number,·folderName?:·string,·endpoint:·string·=·''
with ⏎····jobName:·string,⏎····buildNumber:·number,⏎····folderName?:·string,⏎····endpoint:·string·=·''⏎··
(prettier/prettier)
[error] 75-75: Delete ·
(prettier/prettier)
[error] 76-76: Delete ·
(prettier/prettier)
[error] 77-77: Delete ·
(prettier/prettier)
[error] 78-78: Delete ·
(prettier/prettier)
[error] 79-79: Replace ·
with ,
(prettier/prettier)
[error] 81-81: Delete ····
(prettier/prettier)
[error] 140-140: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 172-172: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 173-173: Insert (⏎······
(prettier/prettier)
[error] 174-174: Delete ·····
(prettier/prettier)
[error] 175-175: Delete ·····
(prettier/prettier)
[error] 176-176: Replace ·····(action.parameters·&&·action.parameters.some((p:·any)·=>
with (action.parameters·&&⏎········action.parameters.some(
(prettier/prettier)
[error] 176-176: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 177-177: Replace ···p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR'))
with (p:·any)·=>·p.name?.includes('ghpr')·||·p.name?.includes('pull')·||·p.name?.includes('PR')⏎········))⏎····
(prettier/prettier)
[error] 183-183: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 190-190: Replace description.includes('pull·request')·||
with ⏎······description.includes('pull·request')·||⏎·····
(prettier/prettier)
[error] 191-191: Replace ········cause._class?.toLowerCase().includes('pullrequest')
with ······cause._class?.toLowerCase().includes('pullrequest')⏎····
(prettier/prettier)
[error] 195-195: Insert ⏎······
(prettier/prettier)
[error] 196-196: Replace ········
with ······
(prettier/prettier)
[error] 197-197: Replace ··cause._class?.includes('GitLabWebHookCause')
with cause._class?.includes('GitLabWebHookCause')⏎····
(prettier/prettier)
[error] 201-202: Delete ⏎·······
(prettier/prettier)
[error] 206-207: Delete ⏎·······
(prettier/prettier)
[error] 211-212: Delete ⏎·······
(prettier/prettier)
[error] 222-222: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 223-223: Replace build.actions·&&·build.actions.some(
with (⏎······build.actions·&&⏎······build.actions.some(⏎········
(prettier/prettier)
[error] 223-223: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
[error] 224-224: Replace ······action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName
with ··········action._class?.includes('git')·||·action.lastBuiltRevision·||·action.buildsByBranchName⏎······)⏎····
(prettier/prettier)
[error] 242-242: Delete ····
(prettier/prettier)
[error] 245-245: Delete ······
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 253-253: Delete ······
(prettier/prettier)
[error] 264-264: Replace ·
with ⏎
(prettier/prettier)
🪛 Biome (1.9.4)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
🔇 Additional comments (10)
tsconfig.json (1)
7-7
: Confirm TypeScript compilation scope and adjust output pathsThe expanded
rootDir
("./"
) does not pull in any extra.ts
/.tsx
files because yourinclude
/exclude
settings restrict compilation to:
- include:
src/**/*
,tests/**/*
- exclude:
node_modules
,**/*.test.ts
All discovered root‐level
.ts
files (global-setup.ts
,playwright.config.ts
) remain outside the compile set.However, changing
rootDir
from"./src"
to"./"
will alter your output tree underdist/
(e.g.src/foo.ts
→dist/src/foo.js
instead ofdist/foo.js
). Please verify that any build, packaging, or deployment scripts (and import paths, if used) are updated to reference the newdist/src/…
layout.src/rhtap/core/integration/ci/providers/gitlabCI.ts (1)
278-278
: Good consistency improvement.Wrapping the return value in
Promise.resolve()
ensures consistent Promise-based behavior across the interface.src/api/ci/jenkins/enums/jenkins.enums.ts (1)
4-31
: Well-structured enum definitions.The Jenkins enums provide good type safety and cover the essential build results, triggers, and credential types needed for Jenkins integration.
src/api/ci/jenkins/index.ts (1)
1-28
: Excellent module organization!This barrel export file provides a clean, well-organized entry point for the Jenkins client with logical grouping by functionality. The structure follows TypeScript best practices and makes the API easy to consume.
src/api/ci/jenkins/types/jenkins.types.ts (1)
3-158
: Comprehensive and well-structured type definitions.The interfaces provide excellent type safety for Jenkins API interactions with thorough documentation and logical organization. The types cover all major Jenkins concepts including builds, jobs, configuration options, and API responses.
src/api/ci/jenkins/README.md (1)
1-231
: Outstanding documentation!This README provides comprehensive documentation of the refactored Jenkins client architecture. It covers all essential aspects including usage examples, design patterns, configuration, extensibility, and best practices. This will greatly help developers understand and use the new client effectively.
src/api/ci/jenkins/errors/jenkins.errors.ts (1)
1-93
: Excellent error hierarchy design!The error classes provide a well-structured hierarchy for Jenkins-specific errors with appropriate status codes, contextual information, and clear error messages. This will greatly improve error handling and debugging throughout the Jenkins client.
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
12-184
: Well-designed HTTP client with comprehensive error handling.The
JenkinsHttpClient
provides a solid foundation for Jenkins API interactions with proper authentication, timeout configuration, request/response interceptors, and specific error handling. The utility methods (ping
,getVersion
) are valuable additions for server connectivity checks.src/api/ci/jenkins/jenkins.client.ts (1)
22-33
: Well-designed constructor with proper dependency injection.The constructor correctly implements dependency injection by initializing the HTTP client first and then passing it to all services, ensuring they share the same connection configuration.
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
4-10
: Clean interface design for the strategy pattern.The interface appropriately defines the contract for credential strategies with clear method signatures for XML generation and type identification.
//TODO: need to confirm if this is correct | ||
public async getPipelineLogs(projectPath: string, jobId: number): Promise<string> { | ||
try { | ||
// Access the raw REST API client to make a direct request for job logs | ||
const gitlab = this.gitlabClient.getClient(); | ||
|
||
// // GitLab API endpoint for job traces is GET /projects/:id/jobs/:job_id/trace | ||
// const encodedProjectPath = encodeURIComponent(projectPath); | ||
// const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`; | ||
// GitLab API endpoint for job traces is GET /projects/:id/jobs/:job_id/trace | ||
const encodedProjectPath = encodeURIComponent(projectPath); | ||
const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`; | ||
|
||
// // Make the request using the underlying requester | ||
// const jobTrace = await gitlab.request.get(url); | ||
// return jobTrace as string; | ||
// } catch (error) { | ||
// console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error); | ||
// return 'Failed to retrieve job logs'; | ||
// } | ||
// } | ||
// Make the request using the underlying requester | ||
const jobTrace = await gitlab.requester.get(url); | ||
return jobTrace as unknown as string; | ||
} catch (error) { | ||
console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error); | ||
return 'Failed to retrieve job logs'; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Address the TODO and improve error handling.
The method implementation needs verification and better error handling:
- The TODO comment indicates uncertainty about the implementation
- Returning a generic failure message instead of proper error propagation may hide important debugging information
Consider this refactor for better error handling:
public async getPipelineLogs(projectPath: string, jobId: number): Promise<string> {
try {
const gitlab = this.gitlabClient.getClient();
const encodedProjectPath = encodeURIComponent(projectPath);
const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`;
const jobTrace = await gitlab.requester.get(url);
return jobTrace as unknown as string;
} catch (error) {
console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error);
- return 'Failed to retrieve job logs';
+ throw new Error(`Failed to retrieve job logs for job ${jobId}: ${error instanceof Error ? error.message : String(error)}`);
}
}
🏁 Script executed:
#!/bin/bash
# Description: Verify GitLab API endpoint for job traces
# Expected: Confirm the correct API path and method
echo "=== Checking GitLab API documentation reference ==="
echo "Searching for GitLab API trace endpoint usage in codebase..."
rg -A 3 -B 3 "jobs.*trace|trace.*jobs" --type ts
Length of output: 1022
Refine getPipelineLogs
implementation and error handling
Verified that GitLab’s API for raw job logs is indeed
GET /projects/:id/jobs/:job_id/trace
and returns the full log as text. Please remove the lingering TODO and improve error propagation so consumers can handle failures more granularly.
• File: src/api/ci/gitlabciClient.ts (lines 149–166)
- Remove the
//TODO
comment now that the endpoint has been confirmed. - Replace the generic failure return with a thrown Error, preserving the original message.
- (Optional) Explicitly set
Accept: text/plain
in the request if your client doesn’t default to it.
Suggested diff:
public async getPipelineLogs(projectPath: string, jobId: number): Promise<string> {
try {
const gitlab = this.gitlabClient.getClient();
const encodedProjectPath = encodeURIComponent(projectPath);
const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`;
- // Make the request using the underlying requester
+ // Fetch raw job logs as plain text
const jobTrace = await gitlab.requester.get(url);
return jobTrace as unknown as string;
} catch (error) {
- console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error);
- return 'Failed to retrieve job logs';
+ console.error(`Failed to retrieve logs for job ${jobId} in project ${projectPath}:`, error);
+ throw new Error(
+ `getPipelineLogs error for project "${projectPath}", job ${jobId}: ` +
+ (error instanceof Error ? error.message : String(error))
+ );
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
//TODO: need to confirm if this is correct | |
public async getPipelineLogs(projectPath: string, jobId: number): Promise<string> { | |
try { | |
// Access the raw REST API client to make a direct request for job logs | |
const gitlab = this.gitlabClient.getClient(); | |
// // GitLab API endpoint for job traces is GET /projects/:id/jobs/:job_id/trace | |
// const encodedProjectPath = encodeURIComponent(projectPath); | |
// const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`; | |
// GitLab API endpoint for job traces is GET /projects/:id/jobs/:job_id/trace | |
const encodedProjectPath = encodeURIComponent(projectPath); | |
const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`; | |
// // Make the request using the underlying requester | |
// const jobTrace = await gitlab.request.get(url); | |
// return jobTrace as string; | |
// } catch (error) { | |
// console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error); | |
// return 'Failed to retrieve job logs'; | |
// } | |
// } | |
// Make the request using the underlying requester | |
const jobTrace = await gitlab.requester.get(url); | |
return jobTrace as unknown as string; | |
} catch (error) { | |
console.error(`Failed to get logs for job ${jobId} in project ${projectPath}:`, error); | |
return 'Failed to retrieve job logs'; | |
} | |
} | |
//TODO: need to confirm if this is correct | |
public async getPipelineLogs(projectPath: string, jobId: number): Promise<string> { | |
try { | |
const gitlab = this.gitlabClient.getClient(); | |
const encodedProjectPath = encodeURIComponent(projectPath); | |
const url = `projects/${encodedProjectPath}/jobs/${jobId}/trace`; | |
// Fetch raw job logs as plain text | |
const jobTrace = await gitlab.requester.get(url); | |
return jobTrace as unknown as string; | |
} catch (error) { | |
console.error(`Failed to retrieve logs for job ${jobId} in project ${projectPath}:`, error); | |
throw new Error( | |
`getPipelineLogs error for project "${projectPath}", job ${jobId}: ` + | |
(error instanceof Error ? error.message : String(error)) | |
); | |
} | |
} |
🤖 Prompt for AI Agents
In src/api/ci/gitlabciClient.ts lines 149 to 166, remove the TODO comment since
the endpoint is confirmed correct. Modify the error handling by throwing a new
Error with the failure message instead of returning a generic string, so callers
can handle errors properly. Optionally, add an 'Accept: text/plain' header to
the request to explicitly request plain text logs if not already set by the
client.
/** | ||
* Get credential information (without sensitive data) | ||
*/ | ||
async getCredential(folderName: string, credentialId: string): Promise<any> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Define proper types instead of using 'any'.
Using any
type reduces type safety and makes the API contract unclear. Consider defining interfaces for credential responses.
Define proper interfaces:
+interface CredentialInfo {
+ id: string;
+ description?: string;
+ typeName: string;
+ // Add other relevant fields
+}
- async getCredential(folderName: string, credentialId: string): Promise<any> {
+ async getCredential(folderName: string, credentialId: string): Promise<CredentialInfo> {
- async listCredentials(folderName?: string): Promise<any[]> {
+ async listCredentials(folderName?: string): Promise<CredentialInfo[]> {
- const response = await this.httpClient.get<{ credentials: any[] }>(
+ const response = await this.httpClient.get<{ credentials: CredentialInfo[] }>(
Also applies to: 143-143, 152-152
🧰 Tools
🪛 ESLint
[error] 120-120: Unexpected any. Specify a different type.
(@typescript-eslint/no-explicit-any)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-credential.service.ts at lines 120, 143,
and 152, the methods currently return Promise<any>, which reduces type safety
and clarity. Define appropriate TypeScript interfaces representing the structure
of the credential responses and update the method return types to Promise of
those interfaces instead of any. This will improve type safety and make the API
contract explicit.
public override async getPipelineLogs(pipeline: Pipeline): Promise<string> { | ||
throw new Error('GitLab does not support getting pipeline logs.'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Fix unused parameter and clarify the contradiction.
- The unused
pipeline
parameter should be prefixed with underscore to satisfy the linter - This method throws an error indicating GitLab doesn't support pipeline logs, but
gitlabciClient.ts
was just enhanced to support job log retrieval. Consider clarifying this discrepancy.
- public override async getPipelineLogs(pipeline: Pipeline): Promise<string> {
+ public override async getPipelineLogs(_pipeline: Pipeline): Promise<string> {
throw new Error('GitLab does not support getting pipeline logs.');
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public override async getPipelineLogs(pipeline: Pipeline): Promise<string> { | |
throw new Error('GitLab does not support getting pipeline logs.'); | |
} | |
public override async getPipelineLogs(_pipeline: Pipeline): Promise<string> { | |
throw new Error('GitLab does not support getting pipeline logs.'); | |
} |
🧰 Tools
🪛 ESLint
[error] 281-281: 'pipeline' is defined but never used. Allowed unused args must match /^_/u.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
In src/rhtap/core/integration/ci/providers/gitlabCI.ts around lines 281 to 283,
rename the unused parameter 'pipeline' to '_pipeline' to satisfy the linter.
Update the error message to clarify that while GitLab does not support
retrieving full pipeline logs, job log retrieval is supported, reflecting the
recent enhancement in gitlabciClient.ts.
139b04a
to
91642e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (15)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: Address the static-only class anti-pattern identified in previous reviews.The static analysis and previous reviews correctly identified that using a class with only static members is an anti-pattern in TypeScript. This should be refactored to use a const object or namespace instead.
src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-60
: Fix variable scoping in switch statement.The
retryAfter
variable can be accessed by other switch cases due to lack of block scoping.
112-117
: Remove redundant status check.This status check is unnecessary since the response interceptor already handles non-2xx status codes.
src/api/ci/jenkins/strategies/credential.strategy.ts (2)
29-36
: Extract duplicated XML escaping logic to shared utility.The XML escaping method is duplicated across all credential strategy classes, violating DRY principles.
130-163
: Refactor static-only factory class.The factory class contains only static members, which is an anti-pattern in TypeScript and should be refactored to use functions or namespace.
src/api/ci/jenkins/services/jenkins-credential.service.ts (4)
62-67
: Extract duplicated credential path building logic.The path building logic is duplicated across multiple methods and should be extracted to a utility method.
120-120
: Define proper types instead of using 'any'.Using
any
types reduces type safety and should be replaced with proper interfaces for credential responses.
143-143
: Define proper types instead of using 'any'.Using
any
types reduces type safety and should be replaced with proper interfaces for credential responses.
152-152
: Define proper types instead of using 'any'.Using
any
types reduces type safety and should be replaced with proper interfaces for credential responses.src/api/ci/jenkins/services/jenkins-job.service.ts (1)
53-56
: Use appropriate error type for job creation failureThrowing
JenkinsJobNotFoundError
when job creation fails is semantically incorrect. Consider creating aJenkinsJobCreationError
or using a more genericJenkinsError
with appropriate context.} catch (error) { const jobPath = options.folderName ? `${options.folderName}/${options.jobName}` : options.jobName; - throw new JenkinsJobNotFoundError(jobPath); + throw new JenkinsError( + `Failed to create job: ${jobPath}`, + undefined, + error instanceof Error ? error : undefined + ); }src/api/ci/jenkins/utils/jenkins.utils.ts (3)
7-52
: Consider refactoring static utility class to functions.The
JenkinsPathBuilder
class contains only static methods. Consider refactoring to standalone functions for better tree-shaking and cleaner code. Also, replacethis
with the class name in static contexts.-export class JenkinsPathBuilder { - /** - * Build a job path for API calls - */ - static buildJobPath(jobName: string, folderName?: string): string { +/** + * Build a job path for API calls + */ +export function buildJobPath(jobName: string, folderName?: string): string { return folderName ? `job/${encodeURIComponent(folderName)}/job/${encodeURIComponent(jobName)}` : `job/${encodeURIComponent(jobName)}`; - } +} - static buildBuildPath(jobName: string, buildNumber: number, folderName?: string, endpoint: string = ''): string { - const jobPath = this.buildJobPath(jobName, folderName); +export function buildBuildPath(jobName: string, buildNumber: number, folderName?: string, endpoint: string = ''): string { + const jobPath = buildJobPath(jobName, folderName); return endpoint ? `${jobPath}/${buildNumber}/${endpoint}` : `${jobPath}/${buildNumber}`; - } -} +}Continue this pattern for all methods in the class.
57-131
: Refactor XML builder to functions and fix static method references.Like
JenkinsPathBuilder
, this static-only class should be refactored to functions. The XML escaping implementation is excellent and properly handles all special characters.-export class JenkinsXmlBuilder { - static buildFolderXml(description: string = ''): string { +export function buildFolderXml(description: string = ''): string { return `<?xml version='1.1' encoding='UTF-8'?> <com.cloudbees.hudson.plugins.folder.Folder> - <description>${this.escapeXml(description)}</description> + <description>${escapeXml(description)}</description> <properties/> <folderViews/> <healthMetrics/> </com.cloudbees.hudson.plugins.folder.Folder>`; - } +} - private static escapeXml(text: string): string { +function escapeXml(text: string): string { return text .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); - } -} +}
136-226
: Improve type safety and code consistency in trigger analyzer.The
JenkinsTriggerAnalyzer
has comprehensive logic but usesany
types and inconsistent optional chaining. Consider:
- Define proper types for build objects instead of using
any
- Use optional chaining consistently
- Consider refactoring to functions
+interface BuildAction { + _class?: string; + pullRequest?: { source?: { commit?: string } }; + parameters?: Array<{ name?: string; value?: string }>; + lastBuiltRevision?: { SHA1?: string }; + buildsByBranchName?: Record<string, { revision?: { SHA1?: string } }>; +} + +interface Build { + actions?: BuildAction[]; + causes?: Array<{ shortDescription?: string; _class?: string }>; + displayName?: string; + description?: string; +} -export class JenkinsTriggerAnalyzer { - static determineBuildTrigger(build: any): string { +export function determineBuildTrigger(build: Build): string { // Check if build has actions array - if (build.actions && Array.isArray(build.actions)) { + if (build.actions?.length) { // Look for pull request related information in actions for (const action of build.actions) { - if (this.isPullRequestTrigger(action)) { + if (isPullRequestTrigger(action)) { return 'PULL_REQUEST'; } } } - if (action.parameters && action.parameters.some((p: any) => - p.name?.includes('ghpr') || p.name?.includes('pull') || p.name?.includes('PR'))) { + if (action.parameters?.some((p) => + p.name?.includes('ghpr') || p.name?.includes('pull') || p.name?.includes('PR'))) {src/api/ci/jenkins/services/jenkins-build.service.ts (2)
210-253
: Remove debug console.log statementsMultiple console.log statements appear to be debug code that should not be in production. Consider using a proper logging framework with configurable log levels or removing these statements entirely.
Remove all console.log statements in this method:
- Line 210
- Line 221
- Line 224
- Line 232
- Lines 242-244
- Lines 251-253
307-365
: Remove additional debug console.log statementsThis method also contains multiple console.log statements that should be removed or replaced with proper logging.
Remove console.log statements at:
- Line 307
- Line 318
- Line 331
- Line 342
- Line 353
- Line 361
- Line 364
Additionally, consider using optional chaining for cleaner code:
-if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) { +if (cause.shortDescription?.includes(normalizedCommitSha)) {-if (build.displayName && build.displayName.includes(normalizedCommitSha)) { +if (build.displayName?.includes(normalizedCommitSha)) {-} else if (build.description && build.description.includes(normalizedCommitSha)) { +} else if (build.description?.includes(normalizedCommitSha)) {
🧹 Nitpick comments (2)
src/api/ci/jenkins/README.md (1)
20-43
: Add language specification to fenced code block.The directory structure code block should specify a language for better rendering and accessibility.
-``` +```text jenkins/ ├── enums/ # Enums for Jenkins constants │ └── jenkins.enums.ts ├── types/ # TypeScript type definitions │ └── jenkins.types.ts ├── config/ # Configuration constants │ └── jenkins.config.ts ├── errors/ # Custom error classes │ └── jenkins.errors.ts ├── utils/ # Utility classes │ └── jenkins.utils.ts ├── strategies/ # Strategy pattern implementations │ └── credential.strategy.ts ├── http/ # HTTP client abstraction │ └── jenkins-http.client.ts ├── services/ # Business logic services │ ├── jenkins-job.service.ts │ ├── jenkins-build.service.ts │ └── jenkins-credential.service.ts ├── jenkins.client.ts # Main client facade ├── index.ts # Module exports └── README.md # This file -``` +```src/api/ci/jenkins/services/jenkins-job.service.ts (1)
24-24
: Consider extracting folder mode constant.The folder mode
com.cloudbees.hudson.plugins.folder.Folder
is hardcoded. Consider moving it toJenkinsConfig
for better maintainability.Add to
JenkinsConfig
:public static readonly FOLDER_MODE = 'com.cloudbees.hudson.plugins.folder.Folder';Then update this line:
-const path = `${JenkinsConfig.ENDPOINTS.CREATE_ITEM}?name=${encodeURIComponent(folderConfig.name)}&mode=com.cloudbees.hudson.plugins.folder.Folder`; +const path = `${JenkinsConfig.ENDPOINTS.CREATE_ITEM}?name=${encodeURIComponent(folderConfig.name)}&mode=${JenkinsConfig.FOLDER_MODE}`;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/api/ci/gitlabciClient.ts
(1 hunks)src/api/ci/jenkins/README.md
(1 hunks)src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks)src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks)src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks)src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks)src/api/ci/jenkins/index.ts
(1 hunks)src/api/ci/jenkins/jenkins.client.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks)src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks)src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks)src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks)src/rhtap/core/integration/ci/providers/gitlabCI.ts
(1 hunks)src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(2 hunks)src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks)tests/api/ci/jenkinsClient.test.ts
(1 hunks)
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/utils/jenkins.utils.ts (4)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/index.ts (1)
JenkinsConfig
(8-8)src/api/ci/jenkins/types/jenkins.types.ts (1)
CreateJobOptions
(33-40)src/api/ci/jenkins/jenkins.client.ts (1)
build
(181-198)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
✅ Files skipped from review due to trivial changes (2)
- src/api/ci/jenkins/enums/jenkins.enums.ts
- src/api/ci/jenkins/index.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
- tests/api/ci/jenkinsClient.test.ts
- src/rhtap/core/integration/ci/providers/jenkinsCI.ts
- src/rhtap/core/integration/ci/providers/gitlabCI.ts
- src/api/ci/gitlabciClient.ts
- src/api/ci/jenkins/types/jenkins.types.ts
- src/api/ci/jenkins/errors/jenkins.errors.ts
- src/api/ci/jenkins/jenkins.client.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/utils/jenkins.utils.ts (4)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/index.ts (1)
JenkinsConfig
(8-8)src/api/ci/jenkins/types/jenkins.types.ts (1)
CreateJobOptions
(33-40)src/api/ci/jenkins/jenkins.client.ts (1)
build
(181-198)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 352-352: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 360-360: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 363-363: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
src/api/ci/jenkins/services/jenkins-job.service.ts (1)
62-74
: LGTM!The method correctly handles job path formatting for nested folders and has appropriate error handling.
|
||
// Determine trigger type if requested | ||
if (includeTriggerInfo) { | ||
buildInfo.triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo) as JenkinsBuildTrigger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid unsafe type assertion for trigger type.
The type assertion as JenkinsBuildTrigger
could hide type mismatches. Consider validating the trigger type.
-buildInfo.triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo) as JenkinsBuildTrigger;
+const triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo);
+buildInfo.triggerType = Object.values(JenkinsBuildTrigger).includes(triggerType as JenkinsBuildTrigger)
+ ? triggerType as JenkinsBuildTrigger
+ : JenkinsBuildTrigger.UNKNOWN;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
buildInfo.triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo) as JenkinsBuildTrigger; | |
// Validate that the determined trigger is a known JenkinsBuildTrigger, | |
// fallback to UNKNOWN if it’s not a valid enum member. | |
const triggerType = JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo); | |
buildInfo.triggerType = Object | |
.values(JenkinsBuildTrigger) | |
.includes(triggerType as JenkinsBuildTrigger) | |
? (triggerType as JenkinsBuildTrigger) | |
: JenkinsBuildTrigger.UNKNOWN; |
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-build.service.ts at line 77, avoid using
the unsafe type assertion 'as JenkinsBuildTrigger' for the triggerType
assignment. Instead, validate the result of
JenkinsTriggerAnalyzer.determineBuildTrigger(buildInfo) to ensure it matches the
expected JenkinsBuildTrigger type before assignment. Implement a type guard or
conditional check to confirm the type and handle unexpected values appropriately
to prevent type mismatches.
export class JenkinsPollingUtils { | ||
/** | ||
* Generic polling utility with timeout | ||
*/ | ||
static async pollUntil<T>( | ||
pollFn: () => Promise<T>, | ||
conditionFn: (result: T) => boolean, | ||
timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS, | ||
intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS | ||
): Promise<T> { | ||
const startTime = Date.now(); | ||
|
||
while (true) { | ||
const result = await pollFn(); | ||
|
||
if (conditionFn(result)) { | ||
return result; | ||
} | ||
|
||
if (Date.now() - startTime > timeoutMs) { | ||
throw new Error(`Polling timed out after ${timeoutMs}ms`); | ||
} | ||
|
||
await this.sleep(intervalMs); | ||
} | ||
} | ||
|
||
/** | ||
* Sleep utility | ||
*/ | ||
static sleep(ms: number): Promise<void> { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor polling utilities to functions.
Convert this static-only class to standalone functions for consistency with other utilities.
-export class JenkinsPollingUtils {
- static async pollUntil<T>(
+export async function pollUntil<T>(
pollFn: () => Promise<T>,
conditionFn: (result: T) => boolean,
timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS,
intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS
): Promise<T> {
// ... implementation ...
- await this.sleep(intervalMs);
+ await sleep(intervalMs);
}
- }
+}
- static sleep(ms: number): Promise<void> {
+export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
- }
-}
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export class JenkinsPollingUtils { | |
/** | |
* Generic polling utility with timeout | |
*/ | |
static async pollUntil<T>( | |
pollFn: () => Promise<T>, | |
conditionFn: (result: T) => boolean, | |
timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS, | |
intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS | |
): Promise<T> { | |
const startTime = Date.now(); | |
while (true) { | |
const result = await pollFn(); | |
if (conditionFn(result)) { | |
return result; | |
} | |
if (Date.now() - startTime > timeoutMs) { | |
throw new Error(`Polling timed out after ${timeoutMs}ms`); | |
} | |
await this.sleep(intervalMs); | |
} | |
} | |
/** | |
* Sleep utility | |
*/ | |
static sleep(ms: number): Promise<void> { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
} | |
/** | |
* Generic polling utility with timeout | |
*/ | |
export async function pollUntil<T>( | |
pollFn: () => Promise<T>, | |
conditionFn: (result: T) => boolean, | |
timeoutMs: number = JenkinsConfig.DEFAULT_TIMEOUT_MS, | |
intervalMs: number = JenkinsConfig.DEFAULT_POLL_INTERVAL_MS | |
): Promise<T> { | |
const startTime = Date.now(); | |
while (true) { | |
const result = await pollFn(); | |
if (conditionFn(result)) { | |
return result; | |
} | |
if (Date.now() - startTime > timeoutMs) { | |
throw new Error(`Polling timed out after ${timeoutMs}ms`); | |
} | |
await sleep(intervalMs); | |
} | |
} | |
/** | |
* Sleep utility | |
*/ | |
export function sleep(ms: number): Promise<void> { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/utils/jenkins.utils.ts from lines 231 to 264, refactor the
JenkinsPollingUtils static class into standalone functions. Extract the
pollUntil method into an async function named pollUntil, and the sleep method
into a separate function named sleep. Remove the class wrapper and export these
functions individually to align with the style of other utility functions in the
codebase.
91642e7
to
676dbf8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (18)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: Static-only class anti-pattern still needs addressing.This issue was previously identified and the suggested refactor to use a const object instead of a static-only class is still valid.
src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-60
: Fix variable scoping in switch statement.The scoping issue in the switch case was previously identified and still needs to be addressed.
112-117
: Remove redundant status check.This redundant status check was previously identified and should be removed as suggested.
src/api/ci/jenkins/strategies/credential.strategy.ts (2)
29-36
: DRY violation: Extract duplicated XML escaping logic.The XML escaping logic duplication was previously identified and is now present in three places (including the new SSH strategy). This should be extracted to a shared utility as suggested.
130-163
: Refactor static-only factory class.The static-only class anti-pattern was previously identified and should be refactored to use module-level functions as suggested.
src/api/ci/jenkins/services/jenkins-credential.service.ts (2)
62-67
: Extract credential path building to utility methodThe path building logic is duplicated across
updateCredential
,deleteCredential
, and other methods. Consider adding a helper method toJenkinsPathBuilder
for credential-specific paths.This would improve maintainability and ensure consistent path construction.
120-120
: Define proper types instead of using 'any'.Using
any
type reduces type safety and makes the API contract unclear. Consider defining interfaces for credential responses.Also applies to: 143-143, 152-152
src/api/ci/jenkins/services/jenkins-job.service.ts (1)
53-56
: Use appropriate error type for job creation failureThrowing
JenkinsJobNotFoundError
when job creation fails is semantically incorrect. Consider creating aJenkinsJobCreationError
or using a more genericJenkinsError
with appropriate context.src/api/ci/jenkins/utils/jenkins.utils.ts (4)
7-52
: Consider refactoring static utility class to functions.The
JenkinsPathBuilder
class contains only static methods. Consider refactoring to standalone functions for better tree-shaking and cleaner code. Also, replacethis
with the class name in static contexts.
54-131
: Refactor XML builder to functions and fix static method references.Like
JenkinsPathBuilder
, this static-only class should be refactored to functions. The XML escaping implementation is excellent and properly handles all special characters.
136-226
: Improve type safety and code consistency in trigger analyzer.The
JenkinsTriggerAnalyzer
has comprehensive logic but usesany
types and inconsistent optional chaining. Consider:
- Define proper types for build objects instead of using
any
- Use optional chaining consistently
- Consider refactoring to functions
231-264
: Refactor polling utilities to functions.Convert this static-only class to standalone functions for consistency with other utilities.
src/api/ci/jenkins/services/jenkins-build.service.ts (3)
79-79
: Avoid unsafe type assertion for trigger type.The type assertion
as JenkinsBuildTrigger
could hide type mismatches. Consider validating the trigger type.
212-255
: Remove debug console.log statementsMultiple console.log statements appear to be debug code that should not be in production. Consider using a proper logging framework with configurable log levels or removing these statements entirely.
309-367
: Remove additional debug console.log statementsThis method also contains multiple console.log statements that should be removed or replaced with proper logging.
src/api/ci/jenkins/jenkins.client.ts (3)
72-87
: Add runtime validation for legacy method parameters.The non-null assertion on line 76 (
repoUrl!
) could cause runtime errors if the method is called with undefined parameters. Consider adding validation.
299-320
: Validate required parameters in waitForBuildCompletion.The non-null assertion on line 310 should be replaced with proper validation.
332-351
: Validate required parameters in getBuildByCommitSha.The non-null assertion on line 342 should be replaced with validation.
🧹 Nitpick comments (2)
src/api/ci/jenkins/README.md (1)
20-43
: Specify language for fenced code block.The directory structure code block should specify a language for better markdown compliance.
-``` +```text jenkins/ ├── enums/ # Enums for Jenkins constants │ └── jenkins.enums.tssrc/api/ci/jenkins/strategies/credential.strategy.ts (1)
104-114
: Consider validation for SSH private key format.While the parsing logic is sound, consider adding basic validation to ensure the private key appears to be in valid format (e.g., starts with
-----BEGIN
and ends with-----END
).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/api/ci/gitlabciClient.ts
(1 hunks)src/api/ci/jenkins/README.md
(1 hunks)src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks)src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks)src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks)src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks)src/api/ci/jenkins/index.ts
(1 hunks)src/api/ci/jenkins/jenkins.client.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks)src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks)src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks)src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks)src/rhtap/core/integration/ci/providers/gitlabCI.ts
(1 hunks)src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(4 hunks)src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks)tests/api/ci/jenkinsClient.test.ts
(1 hunks)
🧬 Code Graph Analysis (2)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
✅ Files skipped from review due to trivial changes (3)
- src/rhtap/core/integration/ci/providers/gitlabCI.ts
- src/api/ci/jenkins/enums/jenkins.enums.ts
- src/api/ci/jenkins/index.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
- tests/api/ci/jenkinsClient.test.ts
- src/api/ci/gitlabciClient.ts
- src/api/ci/jenkins/errors/jenkins.errors.ts
- src/rhtap/core/integration/ci/providers/jenkinsCI.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
🔇 Additional comments (4)
src/api/ci/jenkins/README.md (1)
1-231
: Excellent comprehensive documentation.The README provides thorough documentation of the refactored architecture, usage examples, design patterns, and extensibility guidelines. This will greatly help developers understand and maintain the Jenkins client.
src/api/ci/jenkins/types/jenkins.types.ts (1)
1-179
: Comprehensive and well-structured type definitions.The type definitions provide excellent TypeScript support for the Jenkins client with:
- Strong typing for all API responses and configuration objects
- Proper use of enums for build results and triggers
- Clear interface structure matching Jenkins API patterns
- Good separation of concerns between different operation types
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
12-184
: Well-designed HTTP client abstraction.The HTTP client provides excellent abstraction with:
- Proper error handling and custom Jenkins-specific errors
- Consistent API response structure
- Utility methods for ping and version checking
- Centralized request/response interceptors
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
84-125
: Well-implemented SSH credential strategy.The SSH private key credential strategy is well-implemented with:
- Proper credential parsing with delimiter separation (
::
)- Validation for required fields
- Support for optional passphrase
- Correct Jenkins XML structure for SSH credentials
// Method 5: Check in build causes | ||
if (build.causes) { | ||
for (const cause of build.causes) { | ||
if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use optional chaining for safer property access
Consider using optional chaining for safer property access to prevent potential runtime errors.
- if (build.causes) {
+ if (build.causes?.length) {
for (const cause of build.causes) {
- if (cause.shortDescription && cause.shortDescription.includes(normalizedCommitSha)) {
+ if (cause.shortDescription?.includes(normalizedCommitSha)) {
console.log(`Found matching commit in build causes: ${cause.shortDescription}`);
return true;
}
}
}
// Method 6: Check in build display name or description
- if (build.displayName && build.displayName.includes(normalizedCommitSha)) {
+ if (build.displayName?.includes(normalizedCommitSha)) {
console.log(`Found matching commit in build display name: ${build.displayName}`);
return true;
- } else if (build.description && build.description.includes(normalizedCommitSha)) {
+ } else if (build.description?.includes(normalizedCommitSha)) {
console.log(`Found matching commit in build description: ${build.description}`);
return true;
}
Also applies to: 362-365
🧰 Tools
🪛 Biome (1.9.4)
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-build.service.ts at lines 354 and
362-365, replace direct property accesses like cause.shortDescription with
optional chaining (cause?.shortDescription) to safely handle cases where cause
or its properties might be undefined, preventing runtime errors.
676dbf8
to
36ca4ca
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (14)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: Refactor to avoid static-only class anti-pattern.src/api/ci/jenkins/strategies/credential.strategy.ts (2)
29-36
: DRY violation: Duplicated XML escaping logic.Also applies to: 71-78, 117-124
130-163
: Refactor static-only factory class to use functions or namespace.src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-61
: Fix variable scoping in switch statement.
112-117
: Remove redundant status check.src/api/ci/jenkins/services/jenkins-job.service.ts (1)
53-56
: Use appropriate error type for job creation failure.src/api/ci/jenkins/utils/jenkins.utils.ts (4)
7-52
: Consider refactoring static utility class to functions.The previous review comment about converting this static-only class to standalone functions is still applicable. The class contains only static methods and should be refactored for better tree-shaking and cleaner code structure.
57-131
: Refactor XML builder to functions and fix static method references.The previous review comment about refactoring this static-only class to standalone functions is still applicable. The XML escaping implementation is excellent, but the class should be converted to functions for consistency.
136-226
: Improve type safety and code consistency in trigger analyzer.The previous review comment about defining proper types instead of using
any
and refactoring to functions is still applicable. The class needs better type definitions and consistent optional chaining usage.
231-264
: Refactor polling utilities to functions.The previous review comment about converting this static-only class to standalone functions for consistency is still applicable.
src/api/ci/jenkins/services/jenkins-build.service.ts (4)
212-256
: Remove debug console.log statementsThe previous review comment about removing console.log statements used for debugging is still applicable. Multiple console.log statements appear throughout this method (lines 212, 222, 226, 234, 244-246, 253-255) and should be removed from production code.
309-366
: Remove additional debug console.log statementsThe previous review comment about removing console.log statements is still applicable. This method contains multiple debug logging statements (lines 309, 320, 333, 344, 355, 363, 366) that should be removed from production code.
354-365
: Use optional chaining for safer property accessThe previous review comment about using optional chaining for safer property access is still applicable. Consider updating the property access patterns to use optional chaining consistently.
79-79
: Avoid unsafe type assertion for trigger type.The previous review comment about avoiding the unsafe type assertion
as JenkinsBuildTrigger
is still applicable. Consider validating the trigger type before assignment to prevent type mismatches.
🧹 Nitpick comments (2)
src/api/ci/jenkins/README.md (1)
20-43
: Add language specification to fenced code block.The directory structure code block should specify a language for proper syntax highlighting.
-``` +``` jenkins/ ├── enums/ # Enums for Jenkins constants │ └── jenkins.enums.ts -``` +```src/api/ci/jenkins/services/jenkins-build.service.ts (1)
439-468
: Consider removing or replacing console.log statements with proper logging.Additional console.log statements are present in the
waitForMultipleJobsToComplete
method that weren't addressed in previous reviews. For consistency with the debug logging cleanup, consider using a proper logging framework or removing these statements.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/api/ci/gitlabciClient.ts
(1 hunks)src/api/ci/jenkins/README.md
(1 hunks)src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks)src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks)src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks)src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks)src/api/ci/jenkins/index.ts
(1 hunks)src/api/ci/jenkins/jenkins.client.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks)src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks)src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks)src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks)src/rhtap/core/integration/ci/providers/gitlabCI.ts
(1 hunks)src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(4 hunks)src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks)tests/api/ci/jenkinsClient.test.ts
(1 hunks)
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/services/jenkins-job.service.ts (5)
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
JenkinsHttpClient
(12-184)src/api/ci/jenkins/types/jenkins.types.ts (4)
FolderConfig
(25-28)JenkinsApiResponse
(6-11)CreateJobOptions
(33-40)JenkinsJob
(114-158)src/api/ci/jenkins/utils/jenkins.utils.ts (2)
JenkinsXmlBuilder
(57-131)JenkinsPathBuilder
(7-52)src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/errors/jenkins.errors.ts (2)
JenkinsFolderError
(65-70)JenkinsJobNotFoundError
(23-29)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
✅ Files skipped from review due to trivial changes (3)
- tests/api/ci/jenkinsClient.test.ts
- src/api/ci/jenkins/enums/jenkins.enums.ts
- src/api/ci/jenkins/index.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
- src/rhtap/core/integration/ci/providers/gitlabCI.ts
- src/api/ci/gitlabciClient.ts
- src/api/ci/jenkins/types/jenkins.types.ts
- src/api/ci/jenkins/errors/jenkins.errors.ts
- src/rhtap/core/integration/ci/providers/jenkinsCI.ts
- src/api/ci/jenkins/services/jenkins-credential.service.ts
- src/api/ci/jenkins/jenkins.client.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/services/jenkins-job.service.ts (5)
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
JenkinsHttpClient
(12-184)src/api/ci/jenkins/types/jenkins.types.ts (4)
FolderConfig
(25-28)JenkinsApiResponse
(6-11)CreateJobOptions
(33-40)JenkinsJob
(114-158)src/api/ci/jenkins/utils/jenkins.utils.ts (2)
JenkinsXmlBuilder
(57-131)JenkinsPathBuilder
(7-52)src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/errors/jenkins.errors.ts (2)
JenkinsFolderError
(65-70)JenkinsJobNotFoundError
(23-29)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
} catch (error) { | ||
const jobPath = folderName ? `${folderName}/${jobName}` : jobName; | ||
throw new JenkinsJobNotFoundError(jobPath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use appropriate error type for job deletion failure.
Throwing JenkinsJobNotFoundError
when job deletion fails is semantically incorrect. The job may exist but the deletion operation failed for other reasons.
} catch (error) {
const jobPath = folderName ? `${folderName}/${jobName}` : jobName;
- throw new JenkinsJobNotFoundError(jobPath);
+ throw new JenkinsError(
+ `Failed to delete job: ${jobPath}`,
+ undefined,
+ error instanceof Error ? error : undefined
+ );
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
} catch (error) { | |
const jobPath = folderName ? `${folderName}/${jobName}` : jobName; | |
throw new JenkinsJobNotFoundError(jobPath); | |
} | |
} catch (error) { | |
const jobPath = folderName ? `${folderName}/${jobName}` : jobName; | |
throw new JenkinsError( | |
`Failed to delete job: ${jobPath}`, | |
undefined, | |
error instanceof Error ? error : undefined | |
); | |
} |
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-job.service.ts around lines 93 to 96, the
catch block throws JenkinsJobNotFoundError on any job deletion failure, which is
incorrect because the job might exist but deletion failed for other reasons.
Replace JenkinsJobNotFoundError with a more appropriate error type that reflects
a deletion failure, such as a generic JenkinsJobDeletionError or a custom error
indicating deletion failure, and ensure the error message clearly states the
deletion operation failed.
} catch (error) { | ||
const jobPath = folderName ? `${folderName}/${jobName}` : jobName; | ||
throw new JenkinsJobNotFoundError(jobPath); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use appropriate error types for operation failures.
Multiple methods incorrectly throw JenkinsJobNotFoundError
for operation failures (disable, enable, update config, get config). These operations may fail for reasons other than the job not existing.
Consider creating more specific error types or using generic JenkinsError
with descriptive messages:
} catch (error) {
const jobPath = folderName ? `${folderName}/${jobName}` : jobName;
- throw new JenkinsJobNotFoundError(jobPath);
+ throw new JenkinsError(
+ `Failed to [operation] job: ${jobPath}`,
+ undefined,
+ error instanceof Error ? error : undefined
+ );
}
Also applies to: 162-165, 177-180, 192-195
🤖 Prompt for AI Agents
In src/api/ci/jenkins/services/jenkins-job.service.ts around lines 147 to 150,
the catch blocks throw JenkinsJobNotFoundError for various operation failures
that may not be related to the job's existence. To fix this, create more
specific error classes for each failure type or use a generic JenkinsError with
detailed messages describing the actual failure cause. Apply this change
consistently to the catch blocks at lines 162-165, 177-180, and 192-195 as well.
36ca4ca
to
a950535
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (15)
src/api/ci/jenkins/config/jenkins.config.ts (1)
4-44
: Static-only class anti-pattern persists.This issue was previously identified and the recommended refactor to use a const object or namespace instead of a static-only class has not been implemented.
src/api/ci/jenkins/http/jenkins-http.client.ts (2)
58-61
: Variable scoping issue in switch statement persists.The retryAfter variable declaration can still be accessed by other switch cases. The previously suggested fix to wrap the case in braces has not been implemented.
112-117
: Redundant status check still present.The unnecessary status check in the post method that duplicates the response interceptor's error handling has not been removed as previously suggested.
src/api/ci/jenkins/strategies/credential.strategy.ts (2)
29-36
: DRY violation in XML escaping logic persists and has worsened.The XML escaping duplication issue previously identified has not been addressed and now exists in three locations (lines 29-36, 71-78, and 117-124). The suggested utility function extraction has not been implemented.
130-163
: Static-only factory class pattern still not refactored.The previously identified issues with the static-only class and confusing 'this' usage in static context have not been addressed. The suggested refactor to module-level functions has not been implemented.
src/api/ci/jenkins/services/jenkins-credential.service.ts (2)
62-67
: Credential path building duplication persists.The duplicated path construction logic identified in the previous review has not been addressed. The same pattern exists in multiple methods (updateCredential, deleteCredential, getCredential, listCredentials).
120-120
: Usage of 'any' type instead of proper interfaces persists.The methods still return Promise instead of properly typed interfaces as previously suggested. This affects type safety and API clarity.
src/api/ci/jenkins/utils/jenkins.utils.ts (4)
7-52
: The static-only class refactoring suggestion remains unaddressed.The previous review comment about converting
JenkinsPathBuilder
to standalone functions is still applicable. This class contains only static methods and should be refactored for better tree-shaking and cleaner code structure.
57-131
: The XML builder refactoring suggestion remains unaddressed.The previous review comment about converting
JenkinsXmlBuilder
to standalone functions is still applicable. This static-only class should be refactored to improve code structure and eliminate static context confusion.
136-226
: The type safety and refactoring suggestions remain unaddressed.The previous review comment about improving type safety by replacing
any
types with proper interfaces and considering refactoring to functions is still applicable. The extensive use ofany
reduces code safety and clarity.
231-264
: The polling utilities refactoring suggestion remains unaddressed.The previous review comment about converting
JenkinsPollingUtils
to standalone functions is still applicable. This static-only class should be refactored for consistency with other utilities.src/api/ci/jenkins/services/jenkins-build.service.ts (4)
79-79
: The unsafe type assertion issue remains unaddressed.The previous review comment about avoiding the unsafe type assertion
as JenkinsBuildTrigger
is still applicable. This could hide type mismatches and should be replaced with proper type validation.
212-255
: Debug console.log statements remain unaddressed.The previous review comment about removing console.log statements used for debugging purposes is still applicable. Multiple console.log statements are present throughout this method and should be removed or replaced with proper logging.
309-366
: Debug console.log statements remain unaddressed.The previous review comment about removing console.log statements in this method is still applicable. Multiple debugging statements should be cleaned up from production code.
354-365
: Optional chaining improvements remain unaddressed.The previous review comment about using optional chaining for safer property access is still applicable. Lines 354, 362, and 365 should use optional chaining to prevent potential runtime errors.
🧹 Nitpick comments (2)
src/api/ci/jenkins/README.md (1)
20-43
: Add language specification to fenced code block.The directory structure code block is missing a language specification which affects syntax highlighting and documentation tools.
-``` +``` jenkins/src/api/ci/jenkins/services/jenkins-build.service.ts (1)
439-468
: Consider replacing console.log with proper logging framework.The console.log statements in this method appear to be intentional monitoring logs rather than debug statements. Consider using a proper logging framework with configurable log levels instead of direct console.log calls.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/api/ci/gitlabciClient.ts
(1 hunks)src/api/ci/jenkins/README.md
(1 hunks)src/api/ci/jenkins/config/jenkins.config.ts
(1 hunks)src/api/ci/jenkins/enums/jenkins.enums.ts
(1 hunks)src/api/ci/jenkins/errors/jenkins.errors.ts
(1 hunks)src/api/ci/jenkins/http/jenkins-http.client.ts
(1 hunks)src/api/ci/jenkins/index.ts
(1 hunks)src/api/ci/jenkins/jenkins.client.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-build.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-credential.service.ts
(1 hunks)src/api/ci/jenkins/services/jenkins-job.service.ts
(1 hunks)src/api/ci/jenkins/strategies/credential.strategy.ts
(1 hunks)src/api/ci/jenkins/types/jenkins.types.ts
(1 hunks)src/api/ci/jenkins/utils/jenkins.utils.ts
(1 hunks)src/rhtap/core/integration/ci/providers/gitlabCI.ts
(1 hunks)src/rhtap/core/integration/ci/providers/jenkinsCI.ts
(4 hunks)src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
(1 hunks)tests/api/ci/jenkinsClient.test.ts
(0 hunks)
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/services/jenkins-credential.service.ts (6)
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
JenkinsHttpClient
(12-184)src/api/ci/jenkins/types/jenkins.types.ts (1)
JenkinsApiResponse
(6-11)src/api/ci/jenkins/strategies/credential.strategy.ts (1)
CredentialStrategyFactory
(130-163)src/api/ci/jenkins/utils/jenkins.utils.ts (1)
JenkinsPathBuilder
(7-52)src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/errors/jenkins.errors.ts (1)
JenkinsCredentialError
(55-60)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
💤 Files with no reviewable changes (1)
- tests/api/ci/jenkinsClient.test.ts
✅ Files skipped from review due to trivial changes (1)
- src/api/ci/jenkins/enums/jenkins.enums.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- src/rhtap/postcreation/strategies/commands/addJenkinsSecretsCommand.ts
- src/api/ci/gitlabciClient.ts
- src/rhtap/core/integration/ci/providers/gitlabCI.ts
- src/api/ci/jenkins/index.ts
- src/api/ci/jenkins/types/jenkins.types.ts
- src/api/ci/jenkins/errors/jenkins.errors.ts
- src/api/ci/jenkins/services/jenkins-job.service.ts
- src/rhtap/core/integration/ci/providers/jenkinsCI.ts
- src/api/ci/jenkins/jenkins.client.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/api/ci/jenkins/services/jenkins-credential.service.ts (6)
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
JenkinsHttpClient
(12-184)src/api/ci/jenkins/types/jenkins.types.ts (1)
JenkinsApiResponse
(6-11)src/api/ci/jenkins/strategies/credential.strategy.ts (1)
CredentialStrategyFactory
(130-163)src/api/ci/jenkins/utils/jenkins.utils.ts (1)
JenkinsPathBuilder
(7-52)src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)src/api/ci/jenkins/errors/jenkins.errors.ts (1)
JenkinsCredentialError
(55-60)
src/api/ci/jenkins/http/jenkins-http.client.ts (3)
src/api/ci/jenkins/index.ts (1)
JenkinsHttpClient
(20-20)src/api/ci/jenkins/types/jenkins.types.ts (2)
JenkinsClientConfig
(16-20)JenkinsApiResponse
(6-11)src/api/ci/jenkins/errors/jenkins.errors.ts (3)
JenkinsError
(4-18)JenkinsAuthenticationError
(75-80)JenkinsRateLimitError
(85-93)
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
src/api/ci/jenkins/config/jenkins.config.ts (1)
JenkinsConfig
(4-44)
🪛 Biome (1.9.4)
src/api/ci/jenkins/services/jenkins-build.service.ts
[error] 354-354: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 362-362: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 365-365: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/api/ci/jenkins/config/jenkins.config.ts
[error] 4-44: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
src/api/ci/jenkins/http/jenkins-http.client.ts
[error] 59-59: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
src/api/ci/jenkins/strategies/credential.strategy.ts
[error] 130-163: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 141-141: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 161-161: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
src/api/ci/jenkins/utils/jenkins.utils.ts
[error] 7-52: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 49-49: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 57-131: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 64-64: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 100-100: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 101-101: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 106-106: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 113-113: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 136-226: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 145-145: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 154-154: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 162-162: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 176-177: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 223-224: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 231-264: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 254-254: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
🪛 markdownlint-cli2 (0.17.2)
src/api/ci/jenkins/README.md
20-20: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Red Hat Konflux / tssc-test-on-pull-request
🔇 Additional comments (4)
src/api/ci/jenkins/README.md (1)
1-231
: Excellent comprehensive documentation.This README provides thorough coverage of the refactored architecture, including:
- Clear architectural overview with benefits
- Well-structured directory layout
- Multiple usage examples (backwards compatible and new patterns)
- Design patterns explanation
- Extension guidelines
- Testing, performance, and security considerations
The documentation will greatly help developers understand and use the new Jenkins client architecture.
src/api/ci/jenkins/http/jenkins-http.client.ts (1)
1-184
: Well-structured HTTP client with proper abstraction.The implementation provides:
- Clean Axios wrapper with appropriate configuration
- Proper error handling with custom Jenkins error types
- Comprehensive HTTP methods (GET, POST, PUT, DELETE)
- Utility methods for ping and version checking
- Consistent response formatting
The architecture separation between HTTP concerns and business logic is excellent.
src/api/ci/jenkins/strategies/credential.strategy.ts (1)
4-126
: Solid strategy pattern implementation.The credential strategy interface and concrete implementations provide:
- Clean separation of concerns for different credential types
- Proper XML generation for Jenkins credential API
- Good input validation and parsing logic
- Extensible design for adding new credential types
The overall architecture effectively uses the Strategy pattern to handle credential type variations.
src/api/ci/jenkins/services/jenkins-credential.service.ts (1)
1-220
: Comprehensive credential service with good error handling.The service provides:
- Complete CRUD operations for Jenkins credentials
- Proper integration with the strategy pattern for XML generation
- Consistent error handling with custom JenkinsCredentialError
- Convenient methods for different credential types
- Support for both folder-scoped and system-scoped credentials
The service layer effectively abstracts Jenkins credential API complexity and provides a clean interface for credential management.
/lgtm |
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Documentation
Tests
Chores