post-receive钩子不执行的主因是权限不足、换行符错误、receive.denycurrentbranch未设为ignore,或工作目录不可写且属主不匹配。

git push 触发部署时,post-receive 钩子不执行的常见原因
直接 git push 到远程 bare 仓库后工作目录没更新,大概率是钩子没跑起来,而不是代码没传过去。
关键检查点:
-
post-receive文件必须在.git/hooks/下,且权限为755(chmod +x post-receive) - 脚本第一行必须是
#!/bin/sh或#!/usr/bin/env bash,Windows 编辑后换行符为 CRLF 会导致静默失败 -
git config receive.denyCurrentBranch必须设为ignore,否则 push 会被拒绝(错误信息:remote: error: refusing to update checked out branch) - 钩子中
cd ..后执行git checkout -f前,要确认当前工作区路径可写,且属主是运行 git 的用户(比如deployuser)
Jenkins 拉取 Git 分支后如何精准编译 IRIS 类并加载到命名空间
IRIS 不像 Java 那样有标准构建产物,它的“编译”本质是类文件解析+命名空间内加载,所以 Jenkins 流水线里不能只跑 mvn compile 这类通用命令。
推荐做法:
- 用
iris session连接目标实例,执行##class(%SYS.Packages).Compile()或逐个调用##class(%SYS.Journal.System).Load() - 若代码组织为
src/cls/目录结构,可在 Jenkins 脚本中先find src/cls -name "*.cls" -exec iris session IRIS -U SAMPLES "do ##class(%SYS.Journal.System).Load('{}')" \; - 避免在
post-receive中直接调 IRIS 命令——SSH 连接可能无完整环境变量,iris命令找不到;建议封装成独立 shell 脚本,并在其中显式设置IRISDIR和PATH - 加载前加锁判断:IRIS 命名空间是否正被其他进程使用(查
^%SYS("LOCK")或用##class(%SYS.Lock).IsLocked()),防止并发冲突
.gitlab-ci.yml 中按分支名自动映射部署目标环境
GitLab CI 默认对所有分支都跑同一套流水线,但你不会想让 feat/login 分支的代码直接推到生产 IRIS 实例上。
利用 rules 实现分支路由:
deploy-to-dev:
stage: deploy
script:
- ssh deployuser@dev-server "cd /home/deploy && git pull && ./load-iris.sh"
rules:
- if: $CI_COMMIT_BRANCH == "develop"
when: on_success
<p>deploy-to-prod:
stage: deploy
script:</p>
- ssh deployuser@prod-server "cd /home/deploy && git pull && ./load-iris.sh" rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
allow_failure: false
注意:
when: manual强制人工点击触发,避免误操作;$CI_COMMIT_BRANCH是 GitLab 内置变量,不要写成$BRANCH_NAME这类自定义变量(未定义)。
多环境 IRIS 部署时,如何隔离命名空间和配置参数
IRIS 实例本身不天然支持“环境感知”,同一台服务器上多个命名空间共存时,配置项(如数据库连接串、API 密钥)容易混用。
可行方案:
- 每个环境用独立 IRIS 实例(推荐),通过
iris start IRIS_DEV/iris start IRIS_PROD区分,Jenkins 脚本中用不同-U参数指定命名空间 - 若必须复用实例,则把配置抽离到外部 JSON/YAML 文件,用
##class(MyApp.Config).Load("/opt/config/dev.json")加载,CI 流水线根据分支名复制对应环境配置到目标路径 - 禁止在类定义里硬编码配置值,例如
set url = "https://api.dev.example.com"—— 这类字符串一旦进 Git,就失去环境灵活性 - IRIS 的
%SYS.Task或%SYS.Monitor类可用于部署后健康检查,但需提前在目标命名空间中存在,不能靠 CI 临时注册
真正麻烦的不是怎么写脚本,而是谁来维护那几份分散在 config/ 目录下的 YAML 文件与 IRIS 命名空间之间的映射关系——它很容易脱离版本控制,变成“只有老张知道”的隐性知识。










