之前 ci/release 各自 inline 拼 payload + curl, 重复 25 行 x 2. device_key / endpoint / group / ttl 硬编码两次, 改一处忘另一处 会出现两个不同 group 的推送. 新建 .github/scripts/bark-notify.sh: bash .github/scripts/bark-notify.sh "<title>" "<body>" 脚本封装: - endpoint / device_key / group (Gitea) / isArchive / ttl 单一来源 - heredoc 拼 JSON, 不依赖 jq - 错误用法打印 usage 并 exit 1 (set -euo pipefail) workflow 两处都改成一行: bash .github/scripts/bark-notify.sh "CI \${REF_NAME} \${STATUS}" "\${BODY}" bash .github/scripts/bark-notify.sh "\${TAG_NAME} \${STATUS}" "\${BODY}" emoji (✅/❌) 跟 status 映射仍在 workflow 里, 因为不同 job 拼 不同的 title prefix (CI vs release), 脚本不管这个, 调用方传什么 就推什么. chmod +x 加在 commit 里, 但 git mode bit 在 .gitattributes 或 core.fileMode 关时可能丢. runner 一般会按 working tree 模式跑, 不需要额外 chmod 在 step 里. Co-Authored-By: Claude <noreply@anthropic.com>