如何在GitHub Action的Job与Service间共享环境变量避免重复?
问题描述
我正在编写连接数据库的测试,在GitHub CI中使用部署PostgreSQL容器的Service,需向该Service传递数据库连接信息(dbuser、dbname、password)。参考文档后我写了如下配置,但Service和Build Job里的连接数据重复了,请问有没有办法避免这种重复?
原重复配置片段:
services: postgres: env: POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword"
jobs: build: env: POSTGRES_HOSTNAME: "localhost" POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword"
完整重复配置:
jobs: build: env: POSTGRES_HOSTNAME: "localhost" POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword" steps: - ... - name: Run Tests run: run_my_tests services: postgres: ports: - 5432:5432 env: POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword" image: postgres
解决方案
可以通过以下几种方式避免重复配置:
方法1:使用YAML锚点与别名
利用YAML原生的锚点(&)和别名(*)语法,将重复配置片段定义一次后多处引用:
# 定义可复用的数据库配置锚点 postgres-config: &postgres-config POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword" jobs: build: env: POSTGRES_HOSTNAME: "localhost" # 合并锚点配置到当前env块 <<: *postgres-config steps: - ... - name: Run Tests run: run_my_tests services: postgres: ports: - 5432:5432 env: # 合并锚点配置到当前env块 <<: *postgres-config image: postgres
方法2:使用GitHub Actions全局环境变量
在Workflow顶层定义env字段,所有Job和Service可直接继承这些变量,仅需单独定义Job特有的变量:
# 全局环境变量,所有Job和Service均可访问 env: POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" POSTGRES_PASSWORD: "mypassword" jobs: build: env: # 仅定义Job独有的变量 POSTGRES_HOSTNAME: "localhost" steps: - ... - name: Run Tests run: run_my_tests services: postgres: ports: - 5432:5432 image: postgres
注意:PostgreSQL官方镜像默认识别POSTGRES_DB作为数据库名,若使用自定义的POSTGRES_DBNAME需确认镜像是否支持,建议改为官方标准的POSTGRES_DB以避免兼容问题。
方法3:结合GitHub Secrets(敏感信息推荐)
如果数据库密码等敏感信息不想明文出现在配置文件中,可存入GitHub Secrets,再结合上述方法减少重复:
env: POSTGRES_PORT: "5432" POSTGRES_USER: "myuser" POSTGRES_DBNAME: "mydbname" jobs: build: env: POSTGRES_HOSTNAME: "localhost" POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} steps: - ... - name: Run Tests run: run_my_tests services: postgres: ports: - 5432:5432 env: POSTGRES_PORT: ${{ env.POSTGRES_PORT }} POSTGRES_USER: ${{ env.POSTGRES_USER }} POSTGRES_DBNAME: ${{ env.POSTGRES_DBNAME }} POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} image: postgres
内容的提问来源于stack exchange,提问作者Nicolas Seiller
相关产品推荐
相关产品推荐

