Netlify为私有网络上的自我托管的GitLab提供部署预览
Netlify提供了一个与GitLab的集成,可以通过其Webhook集成轻松地将网站部署到Netlify上。然而,在一个私有的、自我托管的GitLab实例上使用现有的集成可能会很麻烦。该集成要求自我托管的GitLab实例对互联网开放,因此托管在VPN或防火墙后面的实例将无法使用该功能。在一些项目中,由于组织的安全政策,通过公共互联网访问GitLab实例是不可行的,这一限制最终成为使用这一功能的障碍。在这篇文章中,我们将介绍如何设置用于部署预览的GitLab CI管道,使用 netlify-cli工具和它的手动部署功能来设置GitLab CI管道。通过这样的设置,可以从托管在VPN或防火墙后面的GitLab实例向Netlify进行部署。
安装netlify-cli
在本地开发机器上,安装netlify-cli:
npm install netlify-cli -g
创建一个Netlify站点
创建一个新的Netlify站点:
netlify sites:create
选择一个Netlify团队来使用,并提供网站名称。记下由Netlify提供的站点ID。
创建一个Netlify个人访问令牌
在Netlify用户设置页面,创建一个个人访问令牌。复制并保存访问令牌在一个安全的地方。
将令牌添加到GitLab CI设置中
将保存的令牌作为NETLIFY_SITE_ID ,并在仓库CI/CD设置页面将NETLIFY_AUTH_TOKEN ,作为GitLab CI环境变量。
设置GitLab CI管道
在仓库的根目录下创建一个.gitlab-ci.yml 文件:
image: node:17-alpine3.14
variables:
NETLIFY_SITE_ID: $NETLIFY_SITE_ID
NETLIFY_AUTH_TOKEN: $NETLIFY_AUTH_TOKEN
stages:
- preview
preview:
stage: preview
script:
- npm install
- apk add --no-cache zip curl
- npm run build-storybook
- npm install netlify-cli --save-dev
- npx netlify deploy --site $NETLIFY_SITE_ID --auth $NETLIFY_AUTH_TOKEN --dir storybook-static/
artifacts:
paths:
- storybook-static
tags:
- netlify
在这个例子中,我们将使用一个storybook 项目。上述管道安装所需的npm 依赖项,在GitLab运行器上本地构建一个Storybook应用程序,然后将其部署到Netlify。Netlify上的部署预览是持久性的,因此可以保留部署的历史,以供将来参考。
缓存npm的依赖项
为了使流水线运行得更快一些,在流水线中为.npm ,设置一个缓存:
cache:
paths:
- .npm/
key:
files:
- package-lock.json
并使用npm ci ,而不是npm install :
- - npm install
- - apk add --no-cache zip curl
- - npm run build-storybook
- - npm install netlify-cli --save-dev
+ - npm ci --cache .npm --prefer-offline
+ - apk add --no-cache zip curl
+ - npm run build-storybook
注意,npm ci 需要在版本库中存在一个package-lock.json 。关于GitLab上npm 缓存的更多细节,请参考StackOverflow上的这个答案。
防止GitLab创建重复的流水线
当有一个开放的MR,并且代码被推送到源代码分支时,GitLab会创建一个合并请求管道和一个分支管道,导致重复的管道被创建。为了避免创建重复的管道,请在preview 工作中添加下面的rules ,这样preview ,只为合并请求管道运行:
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
当使用GitLab 13.8或更新版本时,可以使用下面的workflow ,以使preview 也能处理分支管道,而不产生重复的管道:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_BRANCH'
用部署状态说明更新MR
在MR中加入部署状态的注释和部署预览URL的链接,可以更容易地跟踪部署情况。为了设置这个,请创建一个GitLab项目访问令牌。接下来在GitLab项目设置中把访问令牌保存为一个GITLAB_API_TOKEN 变量。为了向GitLab API发送POST ,以创建MR注释,请对管道做如下修改:
variables:
+ GITLAB_API_TOKEN: $GITLAB_API_TOKEN
preview:
script:
- - npx netlify deploy --site $NETLIFY_SITE_ID --auth $NETLIFY_AUTH_TOKEN --dir storybook-static/
+ - npx netlify deploy --site $NETLIFY_SITE_ID --auth $NETLIFY_AUTH_TOKEN --dir storybook-static/ | tee netlify_output.txt
+ - if [ -z ${CI_MERGE_REQUEST_IID+x} ]; then exit 0; fi
+ - export DRAFT_URL=$(cat netlify_output.txt | grep 'Draft.*https' | sed 's/\[39m//g' | awk -F " " '{print $NF}')
+ - 'curl --request POST
+ --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN"
+ --data-urlencode "body=✔ **Deploy Preview ready for [Pipeline $CI_PIPELINE_IID]($CI_PIPELINE_URL)**
+
+
+
+ 🔨 Explore the source changes: $CI_COMMIT_SHA
+
+
+
+ 😎 Browse the preview: $DRAFT_URL"
+ "https://$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"'
现在,只要合并请求管道在Netlify上的部署成功,管道就会在MR上添加一个注释,其中包含提交差异的链接和部署预览的URL。
总结
有了这样的设置,我们现在可以从自我托管的GitLab实例向Netlify部署预览,即使GitLab实例是在私人网络中。