Skip to content

fix: remove git settings from values#1018

Open
merll wants to merge 34 commits into
mainfrom
APL-1960
Open

fix: remove git settings from values#1018
merll wants to merge 34 commits into
mainfrom
APL-1960

Conversation

@merll

@merll merll commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

This PR changes the Git configuration for longer requiring environment variables, but read the Git configuration from the same Secret apl-secets/apl-git-config as apl-operator.

Currently still breaks when Gitea is used in addition to an external repository, as Gitea admin password is not separated cleanly from internal Git credentials.

Comment thread src/otomi-stack.ts Fixed
@merll merll changed the title fix: remove git settings from schemas fix: remove git settings from values Jun 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors how Git configuration is handled by moving credentials/config out of values and into a dedicated Kubernetes Secret, and updates related Git helper logic and sanitization.

Changes:

  • Introduces GitConfig and stores/reads Git config from a cluster Secret (apl-git-config) with defaults (GIT_DEFAULT_CONFIG / GIT_LEGACY_CONFIG).
  • Updates git client initialization/migration flow to use GitConfig objects rather than individual env vars.
  • Changes sanitization/tests to mask credentials embedded in repo URLs instead of replacing raw password tokens.

Reviewed changes

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

Show a summary per file
File Description
src/validators.ts Makes git env vars optional by default (undefined).
src/utils/workloadUtils.ts Adds note about internal Gitea credential encoding behavior.
src/utils/codeRepoUtils.ts Adds note about Gitea-specific branch extraction behavior.
src/utils.ts Changes credential sanitization to mask URL-embedded credentials.
src/utils.test.ts Updates sanitization tests to match URL-masking behavior.
src/otomi-stack.ts Adds Secret-backed Git config management and re-init logic.
src/otomi-stack.test.ts Updates tests to align with new Git constructor/config flow.
src/otomi-models.ts Adds GitConfig type used across stack/git layers.
src/middleware/session.ts Makes cleanAllSessions async and deletes session root via rm.
src/git/connect.ts Refactors remote SHA lookup + adds Git URL auth helpers.
src/git.ts Refactors Git to accept GitConfig for auth/remote operations.
src/git.test.ts Updates tests for GitConfig-based APIs.
src/constants.ts Adds Secret name and default/legacy Git config constants.
src/app.ts Refreshes Git config/client before checking latest remote SHA.
src/api/v2/git.ts Updates migration endpoint to accept GitConfig payload.
Comments suppressed due to low confidence (2)

src/utils/workloadUtils.ts:387

  • If GIT_USER/GIT_PASSWORD are not set, this will generate URLs containing the literal string undefined, which will always fail authentication and can be hard to diagnose. Guard against missing credentials before encoding them into the URL.
  // FIXME: When Gitea is present and hosting charts, but the Values repo is somewhere else, this breaks
  const [protocol, bareUrl] = url.split('://')
  const encodedUser = encodeURIComponent(process.env.GIT_USER as string)
  const encodedPassword = encodeURIComponent(process.env.GIT_PASSWORD as string)
  return `${protocol}://${encodedUser}:${encodedPassword}@${bareUrl}`

src/utils/codeRepoUtils.ts:180

  • If GIT_USER/GIT_PASSWORD are not set, this will embed undefined into the URL. Add a guard to avoid producing an invalid URL (and to make failures easier to understand).
      // FIXME: When values is not on Gitea, this is broken
      const username = process.env.GIT_USER as string
      const accessToken = process.env.GIT_PASSWORD as string
      formattedRepoUrl = repoUrl.replace(
        'https://',
        `https://${encodeURIComponent(username)}:${encodeURIComponent(accessToken)}@`,
      )

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

Comment thread src/api/v2/git.ts
Comment thread src/otomi-stack.ts
Comment thread src/otomi-stack.ts
Comment thread src/git/connect.ts
Comment thread src/git.ts
Comment thread src/api/v2/git.ts Outdated
Comment thread src/git/connect.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

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

Comments suppressed due to low confidence (2)

src/utils/workloadUtils.ts:387

  • encodeGitCredentials now unconditionally casts process.env.GIT_USER/GIT_PASSWORD to string. With GIT_USER/GIT_PASSWORD made optional in validators.ts, this can inject literal undefined into the URL (e.g. http://undefined:undefined@...) and cause hard-to-debug auth failures. Guard for missing env vars (or better: plumb credentials from the new GitConfig/Secret), and avoid encoding when credentials are absent.
  // FIXME: When Gitea is present and hosting charts, but the Values repo is somewhere else, this breaks
  const [protocol, bareUrl] = url.split('://')
  const encodedUser = encodeURIComponent(process.env.GIT_USER as string)
  const encodedPassword = encodeURIComponent(process.env.GIT_PASSWORD as string)
  return `${protocol}://${encodedUser}:${encodedPassword}@${bareUrl}`

src/utils/codeRepoUtils.ts:180

  • extractRepositoryRefs casts process.env.GIT_USER/GIT_PASSWORD to string and always injects them into the URL for https://gitea... repos. Since those env vars are now optional, this can generate https://undefined:undefined@... and break remote listing. Only inject credentials when both env vars are present (or switch to Secret/GitConfig-based credentials).
      // FIXME: When values is not on Gitea, this is broken
      const username = process.env.GIT_USER as string
      const accessToken = process.env.GIT_PASSWORD as string
      formattedRepoUrl = repoUrl.replace(
        'https://',
        `https://${encodeURIComponent(username)}:${encodeURIComponent(accessToken)}@`,
      )

Comment thread src/otomi-stack.ts
Comment thread src/otomi-stack.ts Outdated
Comment thread src/git/connect.ts
Comment thread src/api/v2/git.ts
Comment on lines +48 to +51
if (remoteHasContent) {
res.json({ message: 'New repository is not empty', statusCode: 400 })
return
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is very obscure indeed, but currently this is the way Console handles this. Need to check first if we can adjust without breaking it.

Comment thread src/api/v2/git.ts
Comment thread src/git.ts
Comment thread src/otomi-stack.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

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

Comments suppressed due to low confidence (4)

src/middleware/session.ts:70

  • cleanAllSessions() currently resets the module-level readOnlyStack to undefined. With the new refreshGitClient() flow (which calls cleanAllSessions() and then reinitializes a stack), clearing readOnlyStack breaks subsequent lockApi() calls (they dereference readOnlyStack unconditionally) and can leave the API in an inconsistent state. Since cleanAllSessions() is now async and is awaited by refreshGitClient(), it’s safer to keep readOnlyStack and let the caller reinitialize it as needed.
  await rm(rootPath, { recursive: true, force: true })
  sessions = {}
  // @ts-ignore
  readOnlyStack = undefined
}

src/utils/workloadUtils.ts:387

  • encodeGitCredentials() will embed the literal string 'undefined' into the URL when GIT_USER/GIT_PASSWORD are not set, because of the as string casts. That produces an invalid credential URL and can accidentally leak confusing values into logs. If credentials are missing, return the original URL (or throw a clear error) instead of encoding undefined.
  const [protocol, bareUrl] = url.split('://')
  const encodedUser = encodeURIComponent(process.env.GIT_USER as string)
  const encodedPassword = encodeURIComponent(process.env.GIT_PASSWORD as string)
  return `${protocol}://${encodedUser}:${encodedPassword}@${bareUrl}`

src/utils/codeRepoUtils.ts:179

  • extractRepositoryRefs() builds an authenticated URL for Gitea using process.env.GIT_USER / process.env.GIT_PASSWORD cast to string. If either env var is unset, the resulting URL will contain undefined:undefined@... and auth will fail in a non-obvious way. Add a guard so you either skip auth rewriting or throw a clear error when creds are missing.
      const username = process.env.GIT_USER as string
      const accessToken = process.env.GIT_PASSWORD as string
      formattedRepoUrl = repoUrl.replace(
        'https://',
        `https://${encodeURIComponent(username)}:${encodeURIComponent(accessToken)}@`,

src/api/v2/git.ts:43

  • These error paths return a JSON body with statusCode, but they never set the actual HTTP response status (so it stays 200). Other v2 endpoints use res.status(...), and clients may treat these failures as success unless the HTTP status is set explicitly.
      const error = { message: `Cannot connect to new git remote`, statusCode: 404 }
      res.json(error)
      return
    } else {
      const error = { message: `Error connecting to new git remote`, statusCode: 400 }

Comment thread src/git/connect.ts
Comment thread src/otomi-stack.ts Outdated
Comment thread src/otomi-stack.ts
Comment thread src/otomi-stack.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants