Gitlab CI_CD

传统传统应用开发模式

开发本地开发、测试,提交到代码版本管理库

运维把应用部署到测试环境,供 QA 测试,测试通过部署到生产环境

QA 进行测试,通过后通知运维发布到生产

问题

错误发现不及时

人工错误发生

团队沟通效率

自动化运维环境开发模式

持续集成(Continuous Integration,CI):代码合并、部署、自动化测试都在一起,不断执行过程,反馈结果

持续交付(Continuous Delivery,CD):一种软件工程方法,让软件的产出过程在一个短周期内完成,保持随时可发布状态。与持续集成相比,持续交付偏向可交付的产物

持续部署(Continuous Deployment,CD):通过自动化部署的手段将软件频繁的交付,部署到期望的环境。

Gitlab CI/CD

代码审查、问题跟踪、项目 wiki、多角色、CI 工具集成,有开源版本

Gitlab CI/CD

  • Gitlab 的一部分
  • Gitlab Runner,一个处理构建的应用程序,可单独部署,可通过 API 与 Gitlab CI/CD 一起使用
  • .gitlab-ci.yml

将代码托管到 Git 仓库

在项目根目录创建 ci 文件.gitlab-ci.yml,在文件中指定构建,测试和部署脚本

Gitlab 将检测到它并使用名为 Gitlab Runner 的工具运行脚本

脚本被分组作业,它们共同组成一个管道

安装 Gitlab

rpm 方式

kubernetes 方式

docker 方式

graphql 复制代码
docker pull docker.xuanyuan.run/gitlab/gitlab-ce:latest
docker image ls
docker tag fef3e02c1cc7 gitlab/gitlab-ce
docker image rm docker.xuanyuan.run/gitlab/gitlab-ce

vim /etc/hosts
mkdir -p ~/data/gitlab/config ~/data/gitlab/logs ~/data/gitlab/data
docker run -d  -p 443:443 -p 80:80 -p 2222:22 --name gitlab --memory 4g --cpus 2 --restart always -v /root/data/gitlab/config:/etc/gitlab -v /root/data/gitlab/logs:/var/log/gitlab -v /root/data/gitlab/data:/var/opt/gitlab gitlab/gitlab-ce:latest

vim /root/data/gitlab/config/gitlab.rb 
external_url 'http://192.168.1.28'
gitlab_rails['gitlab_shell_ssh_port'] = 2222

docker exec -it gitlab /bin/bash
gitlab-ctl reconfigure

docker exec -it gitlab cat /etc/gitlab/initial_root_password
# WARNING: This password is only valid if ALL of the following are true:
#          • You set it manually via the GITLAB_ROOT_PASSWORD environment variable
#            OR the gitlab_rails['initial_root_password'] setting in /etc/gitlab/gitlab.rb
#          • You set it BEFORE the initial database setup (typically during first installation)
#          • You have NOT changed the password since then (via web UI or command line)
#
#          If this password doesn't work, reset the admin password using:
#          https://docs.gitlab.com/security/reset_user_password/#reset-the-root-password

Password: 85yB+P0RKPxDFAi4LIlXRb6ZmLwNrXiCZqkjJEgt+ag=

# NOTE: This file is automatically deleted after 24 hours on the next reconfigure run.

user:root

pass:85yB+P0RKPxDFAi4LIlXRb6ZmLwNrXiCZqkjJEgt+ag=

账户密码的修改

Runner

https://docs.gitlab.com/runner/install/linux-repository/

https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/

graphql 复制代码
根据自己的发行版安装对应版本

lsb_release -a

GitLab Runner 是一个与 GitLab CI/CD 配合使用的应用程序,用于在流水线中运行作业。可以理解为 agent

Runner 需要独立部署且版本最好跟 gitlab 同步版本

runner 支持本地、docker、windows 等

支持热加载,修改配置,无需重启

graphql 复制代码
docker 部署
mkdir -p ~/data/devops/gitlab-runner/config

docker pull docker.xuanyuan.run/gitlab/gitlab-runner:bleeding
docker image ls
docker tag e7e660656e98 gitlab/gitlab-runner
docker image rm docker.xuanyuan.run/gitlab/gitlab-runner:bleeding
docker run --rm -t -id -v ~/data/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner:latest


注册
gitlab-runner register

Runner 类型与状态(旧版)

  • shared,共享类型,运行整个平台的作业(gitlab)
  • group ,项目组类型,运行特定 group 下的所有项目作业(group)
  • specific,项目类型,运行指定的项目作业(project)

状态

  • locked,锁定状态,无法运行项目作业
  • paused,暂停状态,暂时不会接受新的作业

Runner 类型与状态(新版)

  • Instance,整个实例,对应shared
  • group,项目组类型,对应group
  • project,某个项目,对应specific

状态

  • locked,锁定状态,无法运行项目作业
  • paused,暂停状态,暂时不会接受新的作业

其实没有区别,基本上是继承状态,只是名字换了

Runner 注册

获取 runner token ------》注册

旧版:gitlab-runner register

新版:gitlab-runner register 或 gitlab-runner register --url ... --token ...

创建 runner

复制命令执行就行了

执行器

  • Docker 执行器 → 在容器里执行 Job;
  • Shell 执行器 → 直接在宿主机上执行;
  • Kubernetes 执行器 → 在 K8s Pod 中执行;

一台机器上可以做多台 runner,只要资源允许

Runner 命令

启动命令

graphql 复制代码
gitlab-runner --debug <command>   #调试模式排查错误特别有用。
gitlab-runner <command> --help    #获取帮助信息
gitlab-runner run       #普通用户模式  配置文件位置 ~/.gitlab-runner/config.toml
sudo gitlab-runner run  # 超级用户模式  配置文件位置/etc/gitlab-runner/config.toml

注册命令

graphql 复制代码
gitlab-runner register  #默认交互模式下使用,非交互模式添加 --non-interactive
gitlab-runner list      #此命令列出了保存在配置文件中的所有运行程序
gitlab-runner verify    #此命令检查注册的runner是否可以连接,但不验证GitLab服务是否正在使用runner。 --delete 删除
gitlab-runner unregister   #该命令使用GitLab取消已注册的runner。


#使用令牌注销
gitlab-runner unregister --url http://gitlab.example.com/ --token t0k3n

#使用名称注销(同名删除第一个)
gitlab-runner   --name test-runner

#注销所有
gitlab-runner unregister --all-runners

服务管理

graphql 复制代码
gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner

# --user指定将用于执行构建的用户
#`--working-directory  指定将使用**Shell** executor 运行构建时所有数据将存储在其中的根目录

gitlab-runner uninstall #该命令停止运行并从服务中卸载GitLab Runner。

gitlab-runner start     #该命令启动GitLab Runner服务。

gitlab-runner stop      #该命令停止GitLab Runner服务。

gitlab-runner restart   #该命令将停止,然后启动GitLab Runner服务。

gitlab-runner status #此命令显示GitLab Runner服务的状态。当服务正在运行时,退出代码为零;而当服务未运行时,退出代码为非零。

测试 Runner

测试流水线

pipeline 语法

pipeline 语法 1

job

每个项目中,使用.gitlab.ci.yml 的 yaml 文件配置 gitlab ci/cd

  • 可以定义多个作业(job)
  • 每个作业必须唯一
  • 每个作业独立执行
  • 一个作业最少包含一个 script
yaml 复制代码
job1:
	script:"execute-script-for-job1"
job2:
	script:"execute-script-for-job2"
# 这里在pipeline中定义了两个作业,每个作业运行不同的命令。命令可以是shell或脚本。
script
yaml 复制代码
job:
  script:
    - uname -a
    - bundle exec rspec

有时, script命令将需要用单引号或双引号引起来. 例如,包含冒号命令( : )需要加引号,以便被包裹的YAML解析器知道来解释整个事情作为一个字符串,而不是一个"键:值"对. 使用特殊字符时要小心: : , { , } , [ , ] , , , & , * , # , ? , | , - , < , > , = ! , % , @ , ```.

before_script

用于作业之前运行,必须是一个数组。指定 script 与主脚本中指定的任何脚本串联在一起,并在单个 shell 中一起执行,job 里的 before_script 会覆盖全局 before_script

after_script

用于定义每个作业(包括失败的)之后运行的命令,必须是一个数组。指定脚本在新的 shell 中执行,与任何 before_script 或 script 脚本分开。

可以在全局定义,也可以在 job 中定义。在 job 中定义会覆盖全局

stages & stage

阶段,用于控制作业使用的阶段,全局定义,通过 stages 定义阶段顺序与 job,

可以并行 job,但是 job 的名字必须唯一, stage 声明这里是那个阶段,下面的流水线可以是乱的,只要 stage 声明好,stages 做好顺序就行

并行的时候,如果是一个 runner,会依次执行,如果需要同时执行,最要使用两个 runner,或者 /etc/gitlab-runner/config.toml 里配置

plain 复制代码
# 同时运行 10 个job任务
concurrent = 10
yaml 复制代码
stages:
  - build
  - test
  - deploy
  
......
build1:
  stage: build

build2:
	stage: build

test:
	stage: echo "run test"

before_script (全局):

echo "before-script!!" - 这个会在每个 job 执行前运行

variables:

定义了一个全局变量 DOMAIN: example.com,所有 job 都可以使用

stages:

定义了两个阶段:build 作业和 deploy 作业,将按顺序执行

yaml 复制代码
before_script:
  - echo "before-script!!"

variables:
  DOMAIN: example.com

stages:
  - build
  - deploy
 

build:
  before_script:
    - echo "before-script in job"
  stage: build
  script:
    - echo "mvn clean "
    - echo "mvn install"
  after_script:
    - echo "after script in job"


deploy:
  stage: deploy
  script:
    - echo "hello deploy"
    
after_script:
  - echo "after-script"
.pre & .post

.pre始终是整个管道的第一个运行阶段,.post始终是整个管道的最后一个运行阶段。 用户定义的阶段都在两者之间运行。.pre和.post的顺序无法更改。如果管道仅包含.pre或.post阶段的作业,则不会创建管道。

variables

全局变量,pipeline 变量、job 变量、Runne 变量。job 变量优先级最大

pipeline 语法 2

tags

指定 job 在那个 runner 上运行

开启运行未指定 runner 的 job

plain 复制代码
job:
  tags:
    - ruby
    - postgres
    - shared
allow_failure

允许作业失败,默认为 false,默认不允许失败,如果 allow_failure: true,失败了也会继续运行。

false 不允许失败

true 允许失败

plain 复制代码
job1:
  stage: test
  script:
    - execute_script_that_will_fail
  allow_failure: true
when

控制作业允许

  • on_success:默认值,前面的作业都成功了才执行这个作业
  • on_failure:当前面作业失败了,才执行这个作业
  • always:总是执行作业
  • manual:手动执行作业
  • delayed:延迟执行作业

需要手动执行

延迟执行

测试.gitlab.ci.yml 文件

yaml 复制代码
before_script:
  - echo "before-script!!"

variables:
  DOMAIN: example.com
  
stages:
  - build
  - test
  - codescan
  - deploy

build:
  before_script:
    - echo "before-script in job"
  stage: build
  script:
    - echo "mvn clean "
    - echo "mvn install"
    - echo "$DOMAIN"
  after_script:
    - echo "after script in buildjob"

unittest:
  stage: test
  script:
    - ech "run test"
  when: delayed
  start_in: '10'
  allow_failure: true
  

deploy:
  stage: deploy
  script:
    - echo "hello deploy"
    - sleep 2;
  when: manual
  
codescan:
  stage: codescan
  script:
    - echo "codescan"
    - sleep 5;
  when: on_success
 
after_script:
  - echo "after-script"
  - ech
  
retry

失败重试次数

yaml 复制代码
deploy:
  stage: deploy
  script:
    - echo "hello deploy"
    - sleep 2;
  when: manual
  retry: 2

max:最大重试次数

when :重试失败的案例

最大重试次数必须小于或等于 2

yaml 复制代码
unittest:
  stage: test
  script:
    - ech "run test"
  when: delayed
  start_in: '3'
  retry: 
    max: 2
    when: 
      - script_failure
yaml 复制代码
always :在发生任何故障时重试(默认).
unknown_failure :当失败原因未知时。
script_failure :脚本失败时重试。
api_failure :API失败重试。
stuck_or_timeout_failure :作业卡住或超时时。
runner_system_failure :运行系统发生故障。
missing_dependency_failure: 如果依赖丢失。
runner_unsupported :Runner不受支持。
stale_schedule :无法执行延迟的作业。
job_execution_timeout :脚本超出了为作业设置的最大执行时间。
archived_failure :作业已存档且无法运行。
unmet_prerequisites :作业未能完成先决条件任务。
scheduler_failure :调度程序未能将作业分配给运行scheduler_failure。
data_integrity_failure :检测到结构完整性问题。
timeout

作业超时,两种写法

yaml 复制代码
build:
  script: build.sh
  timeout: 1 hours 30 minutes
  
or

test:
  script: rspec
  timeout: 3h 30m

Runner 的超时

runner 设置 24h,项目 cicd 设置 为 2 小时,该工作超时为 2 小时

runner 不设置,项目 cide 设置 2 小时,该工作超时 为 2 小时

parallel

并行作业,配置要并行运行的作业实例数,此值必须大于或等于2并且小于或等于50。

yaml 复制代码
codescan:
  stage: codescan
  script:
    - echo "codescan"
    - sleep 2;
  when: on_success
  parallel: 5

pipeline 语法 3

only & except

only 和 except 是两个参数用分支策略来限制jobs构建

  • only定义哪些分支和标签的git项目将会被job执行
  • except定义哪些分支和标签的git项目将不会被job执行

逐渐遗弃

只执行 issus 分支,通过正则匹配,其他分支排除

yaml 复制代码
job:
  # use regexp
  only:
    - /^issue-.*$/
  # use special keyword
  except:
    - branches
rules

构建规则,按顺序匹配,第一个不匹配往下,直到匹配

rules 不能与 only/except 组合使用

yaml 复制代码
if (通过条件匹配)
changes ( 检查文件内容是否被修改)
exists(检查文件是否存在)

如果 domain==example.com

执行 when: manual

否则往下执行,执行 on_success

if

yaml 复制代码
deploy:
  stage: deploy
  script:
    - echo "hello deploy"
    - sleep 2;
  when: manual
  rules:
    - if: '$DOMAIN == "example.com"'
      when: manual
    - when: on_success

changes

如果 test.txt 发生了变化,执行手动作业,如果没有发生变化,执行on_failure

yaml 复制代码
deploy:
  stage: deploy
  script:
    - echo "hello deploy"
    - sleep 2;
  when: manual
  rules:
    - changes: 
      - test.txt
      when: manual
    - when: on_failure

exists

如果 test1.txt 存在,执行 延迟 5 秒

yaml 复制代码
codescan:
  stage: codescan
  script:
    - echo "codescan"
    - sleep 5;
  when: on_success
  rules:
    - exists: 
      - test1.txt
      when: delayed
      start_in: 5s
workflow:rules

顶级workflow:关键字适用于整个管道,并将确定是否创建管道。when :可以设置为always或never . 如果未提供,则默认值always。

yaml 复制代码
variables:
  DOMAIN: 1example.com

workflow:
  rules:
    - if: '$DOMAIN == "example.com"'
    - when: always

pipeline 语法 4

cache

缓存,存储项目在编译时候产生的依赖,在项目空间中需要传递的文件或目录

yaml 复制代码
cache:paths(指定缓存文件或目录)
cache:key(缓存标记)
cache:police(策略)

paths

在job build中定义缓存,将会缓存target目录下的所有.jar文件。

yaml 复制代码
build:
  script: test
  cache:
    paths:
      - target/*.jar

key

由于缓存是在job之间共享的,如果不同的job使用不同的路径就出现了缓存覆盖的问题。如何让不同的job缓存不同的cache呢?设置不同的cache:key。

为不同的 job 定义了不同的 cache:key 时,会为每个 job 分配独立的 cache

cache:key 变量可以使用任何预定义变量,默认 default

yaml 复制代码
cache:
  paths:
    - my/files

build:
  script: echo "hello"
  cache:
    key: build
    paths:
      - target/

files,最多可以指定两个文件,这两个文件发生变化,重新产生缓存

prefix,略

yaml 复制代码
cache:
  key:
    files:
      - Gemfile.lock
      - package.json
  paths:
    - vendor/ruby
    - node_modules

police

缓存策略,默认:在执行开始时下载文件,并在结束时重新上传文件。称为" pull-push缓存策略

比如 job1 打包,job2 测试,job1 不需要缓存,它是产生缓存的,但它执行后给到 job2,job2 需要缓存测试,所以可使用 police 跳过下载步骤

policy: pull 跳过下载步骤

policy: push 跳过上传步骤

流水线第一次运行的结果会被下一次运行直接使用,如果出现构建失败的情况,可以在 runner 里去把缓存清掉,尝试重新构建/home/gitlab-runner/

yaml 复制代码
stages:
  - setup
  - test

prepare:
  stage: setup
  cache:
    key: gems
    paths:
      - vendor/bundle
  script:
    - bundle install --deployment

rspec:
  stage: test
  cache:
    key: gems
    paths:
      - vendor/bundle
    policy: pull
  script:
    - bundle exec rspec ...
aftifacts

制品,用于指定在作业成功或者失败时应附加到作业的文件或目录的列表。作业完成后,工件将被发送到GitLab,并可在GitLab UI中下载。

yaml 复制代码
aftifacts:paths(指定制品路径)
artifacts:expose_as(在合并请求UI中公开作业都工件)
artifacts:name(定义创建工件时候都名称,默认是artifacts)
artifacts:when(仅在作业失败时上传工件)
artifacts:expire_in(制品的有效期,从上传和存储到GitLab的时间开始算起。如果未定义过期时间,则默认为30天)
artifacts:reports(用于从作业中收集测试报告,代码质量报告和安全报告. 在GitLab的UI中显示这些报告)
artifacts:reports:junit()

artifacts:paths

路径是相对于项目目录的,不能直接链接到项目目录之外

将制品设置为target目录

yaml 复制代码
artifacts:
  paths:
    - target/

artifacts:expose_as

关键字expose_as可用于在合并请求 UI中公开作业工件。

  • 每个合并请求最多可以公开10个作业工件。
  • 如果指定了目录,那么如果目录中有多个文件,则该链接将指向指向作业工件浏览器。
  • 如果开启GitlabPages可以对.html .htm .txt .json .log扩展名单个文件工件渲染工件。
yaml 复制代码
test:
  script: 
    - echo 1
  artifacts:
    expose_as: 'artifact 1'
    paths: 
      - path/to/file.txt

artifacts:name

通过name指令定义所创建的工件存档的名称。可以为每个存档使用唯一的名称。 artifacts:name变量可以使用任何预定义变量。默认名称是artifacts,下载artifacts改为artifacts.zip

yaml 复制代码
job:
  artifacts:
    name: "$CI_JOB_NAME"
    paths:
      - binaries/

artifacts:when

用于在作业失败时或尽管失败而上传工件。on_success仅在作业成功时上载工件。这是默认值。on_failure仅在作业失败时上载工件。always 上载工件,无论作业状态如何。

要仅在作业失败时上传工件:

yaml 复制代码
job:
  artifacts:
    when: on_failure

artifacts:expire_in

制品的有效期,从上传和存储到GitLab的时间开始算起。如果未定义过期时间,则默认为30天。

expire_in的值以秒为单位的经过时间,除非提供了单位。可解析值的示例:

yaml 复制代码
job:
  artifacts:
    expire_in: 1 week

artifacts:reports

用于从作业中收集测试报告,代码质量报告和安全报告. 在GitLab的UI中显示这些报告。

注意:无论作业结果(成功或失败),都将收集测试报告。

artifacts:reports:junit

收集junit单元测试报告,收集的JUnit报告将作为工件上传到GitLab,并将自动显示在合并请求中

yaml 复制代码
build:
  stage: build
  tags:
    - build
  only:
    - master
  script:
    - mvn test
    - mvn cobertura:cobertura
    - ls target
  artifacts:
    name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
    when: on_success
    expose_as: 'artifact 1'
    paths:
      - target/*.jar
    reports:
      junit: target/surefire-reports/TEST-*.xml

pipeline 语法 5

needs

并行阶段,可无序执行作业,无需按照阶段顺序运行某些作业,可以让多个阶段同时运行。

needs: ["module-a-build"],在执行module-a-build 的时候执行当前 job

yaml 复制代码
stages:
  - build
  - test
  - deploy

module-a-build:
  stage: build
  script: 
    - echo "hello3a"
    - sleep 10
    
module-b-build:
  stage: build
  script: 
    - echo "hello3b"
    - sleep 10

module-a-test:
  stage: test
  script: 
    - echo "hello3a"
    - sleep 10
  needs: ["module-a-build"]
    
module-b-test:
  stage: test
  script: 
    - echo "hello3b"
    - sleep 10
  needs: ["module-b-build"]
    
制品下载

在使用needs,可通过artifacts: true或artifacts: false来控制工件下载。 默认不指定为true。

yaml 复制代码
module-a-test:
  stage: test
  script: 
    - echo "hello3a"
    - sleep 10
  needs: 
    - job: "module-a-build"
      artifacts: true
include

可以允许引入外部YAML文件,文件具有扩展名.yml或.yaml 。使用合并功能可以自定义和覆盖包含本地定义的CI / CD配置。相同的job会合并,参数值以源文件为准。

yaml 复制代码
include:local(引入本地文件)

引入同一存储库中的文件,使用相对于根目录的完整路径进行引用,与配置文件在同一分支上使用。

ci/localci.yml: 定义一个作业用于发布。

yaml 复制代码
stages:
  - deploy
  
deployjob:
  stage: deploy
  script:
    - echo 'deploy'

.gitlab-ci.yml 引入本地的CI文件'ci/localci.yml'。

1.yaml 的文件存放在项目根目录的 ci 下

yaml 复制代码
include:
  - local: "ci/1.yaml"

stages:
  - build
  - test
  - deploy

buildjob:
  stage: build
  script: ls

testjob:
  stage: test
  script: ls && id

一个简单项目

基础环境:

两台 ubuntu server 2404

  • 192.168.1.28 - Gitlab 服务器(已安装 Docker)
  • 192.168.1.27 - Gitlab Runner (已安装 Docker)

部署 Gitlab 容器

graphql 复制代码
#docker volume rm gitlab-etc
#docker volume rm gitlab-log
#docker volume rm gitlab-opt

docker volume create gitlab-etc
docker volume create gitlab-log
docker volume create gitlab-opt

docker run --name gitlab \
--hostname 192.168.1.28 \
--restart=always \
-p 80:80 \
-p 443:443 \
-v gitlab-etc:/etc/gitlab \
-v gitlab-log:/var/log/gitlab \
-v gitlab-opt:/var/opt/gitlab \
-d gitlab/gitlab-ce:latest


docker logs -f gitlab

sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

部署 Runner

安装 JDK21

graphql 复制代码
cd /usr/local
wget https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz -O openjdk-21.0.1_linux-x64_bin.tar.gz
tar -xzvf openjdk-21.0.1_linux-x64_bin.tar.gz

cat >> /etc/profile <<-'EOF'
export JAVA_HOME=/usr/local/jdk-21.0.1
export PATH=$PATH:$JAVA_HOME/bin
EOF

source /etc/profile
java -version

安装 Apache Maven

graphql 复制代码
cd /usr/local
wget --no-check-certificate wget  https://manongbiji.oss-cn-beijing.aliyuncs.com/ittailkshow/devops/download/apache-maven-3.8.6-bin.tar.gz
tar -xzvf apache-maven-3.8.6-bin.tar.gz

cat >> /etc/profile <<-'EOF'
export PATH=$PATH:/usr/local/apache-maven-3.8.6/bin
EOF

source /etc/profile
mvn -v

安装 Runner

graphql 复制代码
curl -L "https://mirrors.tuna.tsinghua.edu.cn/gitlab-runner/ubuntu/pool/noble/main/g/gitlab-runner/gitlab-runner_18.5.0-1_amd64.deb" -o /tmp/gitlab-runner.deb && sudo dpkg -i /tmp/gitlab-runner.deb && sudo apt -f install

注册 Runner

创建仓库

git clone my-project

推送代码

根据触发条件,打一个 tag,触发流水线

查看 pipelines 流水线

第一步 编译 jar,第二步打包成 image,第三步 push 到 dockerhub

相关推荐
谢尔登20 小时前
通用会话控制方案
前端·网络协议·tcp/ip·react.js·gitlab
行走的陀螺仪1 天前
前端CI/CD 流程
前端·ci/cd·工程化·自动化构建
地球没有花2 天前
gitlab cicd首次操作
运维·git·ci/cd·gitlab
一念一花一世界2 天前
Jenkins VS GitLab CI/CD VS Arbess,CI/CD工具选型指南
ci/cd·gitlab·jenkins·arbess
FreeBuf_2 天前
GitLab 曝多个安全漏洞,攻击者可注入恶意指令窃取敏感数据
gitlab
一念一花一世界3 天前
Arbess从初级到进阶(7) - 使用Arbess+GitLab实现PHP项目自动化部署
ci/cd·gitlab·php·arbess
一念一花一世界3 天前
Jenkins和Arbess,开源免费CI/CD工具选型指南
ci/cd·jenkins·arbess
风吹一夏v3 天前
Docker 部署 GitLab 和 GitLab Runner 指南
docker·容器·gitlab
EkihzniY3 天前
护照阅读器:为边检安全检查注入科技力量
gitlab