目录

配置 PHP 主动拉取 GitLab 提交

参考

环境变量

https://docs.gitlab.com/ce/ci/variables/predefined_variables.html

使用

CI/CD

php 自动拉取

  • 依赖

m4tthumphrey/php-gitlab-api

  • 代码
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

/**
 * config check
 */
// GitLab 服务器地址
if (!config('myflex.gitlab.origin')) {
    $this->info('gitlab origin is not set');
    return;
}
// 项目或用户访问令牌
if (!config('myflex.gitlab.token')) {
    $this->info('gitlab token is not set');
    return;
}
// 项目ID
if (!config('myflex.gitlab.fe_id')) {
    $this->info('gitlab project id is not set');
    return;
}

/**
 * 根据不同环境拉取不同的打包结果
 */
$jobName  = 'job_build_unknown';
switch (config('app.env')) {
    case 'production':
        $jobName = 'job_build_prod';
        break;
    case 'development':
    case 'local':
        $jobName = 'job_build_stage';
        break;
    default:
        break;
}

// GitLab 客户端
$client = new \Gitlab\Client();
$client->setUrl(config('myflex.gitlab.origin'));
$client->authenticate(config('myflex.gitlab.token'), \Gitlab\Client::AUTH_HTTP_TOKEN);

/**
 * @var \Gitlab\Api\Jobs
 */
$jobs = $client->jobs();
$job = collect($client->jobs()->all(config('myflex.gitlab.fe_id'), ['scope' => 'success']))
    ->where('name', $jobName)
    ->where('tag', true)
    ->filter(function ($item) use ($jobName) {
        if ($jobName == 'job_build_prod') {
            // 正式
            return preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?(-\d+)?$}i', strtolower($item['ref']));
        } else if ($jobName == 'job_build_stage') {
            // 测试
            return preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?(-stage\.\d+)$}i', strtolower($item['ref']));
        } else {
            return false;
        }
    })
    ->first();

if (!$job) {
    $this->info('gitlab job not exist');
    return;
}

$this->info("gitlab sync fe with {$jobName}:{$job['ref']}");

/**
 * 下载文件
 */
$artifacts = $jobs->artifactsByRefName(
    config('myflex.gitlab.fe_id'),
    $job['ref'],
    $jobName
);

$curRef = $job['ref'];
$refPath = implode(DIRECTORY_SEPARATOR, ['gitlab', '.ref',]);

// 定位目录,检查是否有必要拉取文件
/** @var \Illuminate\Filesystem\FilesystemAdapter */
$storage = static::getStorage();
if ($storage->exists($refPath)) {
    $prevRef = trim($storage->get($refPath));
    if ($prevRef == $curRef) {
        $this->info('gitlab remote ref not change');
        return;
    }
}

// 创建下载文件名
$file = implode(DIRECTORY_SEPARATOR, ['gitlab', $curRef . '.zip']);
if ($storage->exists($file)) {
    $storage->delete($file);
}
$storage->put($file, $artifacts);

/**
 * 解压文件
 */
$dest = implode(DIRECTORY_SEPARATOR, [
    dirname($file), $curRef
]);
$zip = new \ZipArchive();
$zip->open($storage->path($file));
$zip->extractTo($storage->path($dest));
$zip->close();
flush();

/**
 * 复制文件
 */
$prefix = implode(DIRECTORY_SEPARATOR, [
    'gitlab', $curRef, 'dist',
]) . DIRECTORY_SEPARATOR;
collect($storage->files($dest, true))
    ->each(function ($file) use ($storage, $prefix) {
        $file = str_replace('/', DIRECTORY_SEPARATOR, $file);
        /**
         * 跳过 php 和 favicon.con 文件
         */
        if (Str::endsWith($file, '.php') || Str::endsWith($file, 'favicon.ico')) {
            return;
        }
        /**
         * 根据环境选择文件
         */
        if (!Str::startsWith($file, $prefix)) {
            return;
        }
        $from = $storage->path($file);
        $to = public_path(str_replace($prefix, '', $file));
        if (!file_exists(dirname($to))) {
            mkdir(dirname($to), 0777, true);
        }
        copy($from, $to);
    });
$storage->put($refPath, $curRef);
$storage->deleteDirectory($dest);

js 自动构建

  • 配置
1
npm install -dev release-it
1
2
3
4
5
// file: package.json
"script": {
  "release:stage": "release-it --preRelease=stage",
  "release:prod": "release-it",
}
  • 代码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# file: .gitlab-ci.yml
image: node:14.15.3-buster

cache:
  untracked: true
  key: ${CI_JOB_NAME}
  paths:
    - .npm/
    - node_modules/

before_script:
  - if [ ! -d "${PWD}/.npm" ]; then mkdir -p "${PWD}/.npm"; fi
  - npm config set registry https://mirrors.cloud.tencent.com/npm/
  - node --version
  # - git reset --hard origin/$CI_BUILD_REF_NAME
  # - git config --global user.email "${GITLAB_USER_EMAIL}" && git config --global user.name "${GITLAB_USER_LOGIN}"
  - npm install

stages:
  - build_prod
  - build_stage

job_build_prod:
  stage: build_prod
  environment: prod
  script:
    - npm run build:prod
  artifacts:
    paths:
      - dist
    expire_in: 1 week
  tags:
    - docker
    - server
  only:
    - tags

job_build_stage:
  stage: build_stage
  environment: stage
  script:
    - npm run build:stage
  artifacts:
    paths:
      - dist
    expire_in: 1 week
  tags:
    - docker
    - server
  only:
    - tags

Release

https://docs.gitlab.com/ee/api/releases/

查看

1
curl --header "PRIVATE-TOKEN: XXXXXXXXXXXXX" http://gitlab.local/api/v4/projects/工程id/releases

创建

1
curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: XXXXXXXXXXXXX" --data '{ "name": "'release名称'", "tag_name": "'标签名'", "ref":"'标签名'" ,"description": "'描述信息'" }' --request POST http://gitlab.local/api/v4/projects/工程id/releases

修改

1
curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: XXXXXXXXXXXXX" "http://gitlab.local/api/v4/projects/工程id/releases/v0.0.1

删除

1
curl --request DELETE --header "PRIVATE-TOKEN: XXXXXXXXXXXXX" "http://gitlab.local/api/v4/projects/工程id/releases/v0.0.1"

脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env bash  

GITLAB_URL="http://gitlab.local"

echo -n "0.请输入Gitlab Access Token:"  
read token  
echo -n "1.请输入项目的id:"  
read id  
echo -n "2.请输入项目release的名称:"  
read name  
echo -n "3.请输入即将创建release版本的tag:"  
read tag_name  
echo -n "4.请输入release的描述:"  
read description
echo -n "5.请输入release二进制文件名称:"  
read release_file_name
echo -n "6.请输入release二进制文件发布路径:"  
read release_path

#创建发布版本  
curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: $token" --data '{ "name": "'$name'", "tag_name": "'$tag_name'", "ref":"'$tag_name'" ,"description": "'$description'" }' --request POST http://$GITLAB_URL/api/v4/projects/$id/releases

#创建二进制文件链接
curl --request POST --header "PRIVATE-TOKEN: $token" --data name="$release_file_name" --data url="$release_path" "$GITLAB_URL/api/v4/projects/$id/releases/$tag_name/assets/links"