Netlify为私有网络上自我托管的GitLab提供部署预览

416 阅读3分钟

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实例是在私人网络中。