Compare commits

...

43 Commits

Author SHA1 Message Date
徐晓伟 9a00cb52ed 项目:列出所有项目:当前用户明确拥有的项目 2024-03-09 17:54:38 +08:00
徐晓伟 f2454e84f6 🐛 根据项目路径/ID、流水线IID范围删除作业产物和作业日志(混合命令,多接口命令,立即删除):允许失败 2024-01-22 13:14:47 +08:00
徐晓伟 02d1e0e4f4 保护仓库分支:保护所有仓库分支 2024-01-16 14:55:14 +08:00
徐晓伟 2143aa297a 受保护的分支 API:保护仓库分支 2024-01-16 14:29:02 +08:00
徐晓伟 6720210458 受保护的分支 API:列出受保护的分支 2024-01-16 13:49:51 +08:00
徐晓伟 6cff8dc2fa 👷 发布 framagit 2024-01-16 13:21:26 +08:00
徐晓伟 6f82a92961 📝 增加命令文档 2024-01-16 11:10:39 +08:00
徐晓伟 bfa8b974ea 创建项目级别 CI/CD 变量:所有项目创建新变量 2024-01-16 11:05:19 +08:00
徐晓伟 7ee5c0ade9 🐛 修正参数名 2024-01-16 11:03:52 +08:00
徐晓伟 741e281185 🐛 修正参数 2024-01-16 11:02:37 +08:00
徐晓伟 c63941d072 🐛 修正参数名 2024-01-16 11:00:17 +08:00
徐晓伟 25860b000e 项目级别 CI/CD 变量 API:创建变量 2024-01-16 10:21:14 +08:00
徐晓伟 0260f9bb39 项目级别 CI/CD 变量 API:列出项目变量 2024-01-16 09:32:49 +08:00
徐晓伟 026a48c896 🐛 Name、Aliases 2024-01-16 09:16:47 +08:00
徐晓伟 d2f80a1ee7 📝 调整顺序 2024-01-16 09:11:27 +08:00
徐晓伟 0fc7e38d58 增加 Aliases 2024-01-16 09:11:02 +08:00
徐晓伟 904ed2cf6a 📝 鸣谢 2024-01-16 08:46:23 +08:00
徐晓伟 54d084af8b 创建新环境:所有项目创建新环境 2024-01-15 17:44:11 +08:00
徐晓伟 6caebc97c5 环境 API:创建新环境 2024-01-15 17:10:20 +08:00
徐晓伟 032b7fe150 🐛 修正 Usage 2024-01-15 16:55:31 +08:00
徐晓伟 377f1cd8cc 📝 GOPROXY 2024-01-15 16:47:21 +08:00
徐晓伟 a1f455d095 👷 修正 rules 2024-01-15 14:46:22 +08:00
徐晓伟 918f947fb3 环境 API 2024-01-15 14:17:34 +08:00
徐晓伟 8b6d4afe2b 👷 framagit.org 不构建 docker 镜像 2024-01-15 13:59:49 +08:00
徐晓伟 d279e372d3 ⬆️ github.com/urfave/cli/v2 from v2.26.0 to v2.27.1 2024-01-15 13:10:50 +08:00
徐晓伟 e68768df6c 👷 framagit.org 不同步到自己 2024-01-15 13:09:13 +08:00
徐晓伟 dc57cef306 ⬆️ github.com/xuxiaowei-com-cn/git-go 2023-12-20 23:20:49 +08:00
徐晓伟 d65d213758 ⬆️ github.com/xanzy/go-gitlab from v0.95.1 to v0.95.2 2023-12-20 23:04:52 +08:00
徐晓伟 8b69e6a111 导出: 允许失败 2023-12-17 21:58:25 +08:00
徐晓伟 a81e49d159 导出: 自动跳过已存在的文件夹 2023-12-17 21:48:28 +08:00
徐晓伟 f99152312e 👷 sync framagit 2023-12-12 21:18:48 +08:00
徐晓伟 4e312242f4 ⬆️ github.com/xanzy/go-gitlab from v0.94.0 to v0.95.1 2023-12-12 21:04:49 +08:00
徐晓伟 46cccd3bb4 ⬆️ github.com/urfave/cli/v2 from v2.25.7 to v2.26.0 2023-12-12 21:03:54 +08:00
徐晓伟 6a6799ec53 Merge remote-tracking branch 'origin/main' 2023-12-07 23:52:58 +08:00
徐晓伟 2b77ad7abb 🐛 修正错别字 2023-12-06 17:15:54 +08:00
徐晓伟 381f8e85f5 🐛 补充日志 2023-12-04 21:01:47 +08:00
徐晓伟 704f7aaa64 🐛 修正过滤判断 2023-12-04 20:24:39 +08:00
徐晓伟 29741792e7 取消归档 2023-12-04 20:08:38 +08:00
徐晓伟 5977392c40 Project 导出完成后再导出 wiki 2023-12-04 18:58:13 +08:00
徐晓伟 71f8df1dcf 🐛 删除无用参数 2023-12-04 18:49:23 +08:00
徐晓伟 e69f06f87d 🐛 修正路径判断 2023-12-04 17:56:34 +08:00
徐晓伟 8aad801071 转移(混合命令,多接口命令) 2023-12-04 17:47:38 +08:00
徐晓伟 c6ca0877b3 🐛 修正变量、方法说明 2023-12-04 17:00:54 +08:00
39 changed files with 2117 additions and 150 deletions

View File

@ -210,7 +210,14 @@ jobs:
- name: Release GitLab - name: Release GitLab
run: | run: |
./cicd-release-linux-amd64 pre-release gitlab --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitlab-repository=$GITHUB_REPOSITORY --gitlab-username=$GITHUB_ACTOR --gitlab-token=${{ secrets.PRIVATE_GITLAB_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --package-name=cicd-release --artifacts=gitlab-go-windows-amd64.exe --artifacts=gitlab-go-windows-arm64.exe --artifacts=gitlab-go-linux-amd64 --artifacts=gitlab-go-linux-arm64 --artifacts=gitlab-go-darwin-amd64 --artifacts=gitlab-go-darwin-arm64 --artifacts=gitlab-go-loong64 ./cicd-release-linux-amd64 pre-release gitlab --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitlab-repository=$GITHUB_REPOSITORY --gitlab-username=$GITHUB_ACTOR --gitlab-token=${{ secrets.PRIVATE_GITLAB_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --package-name=cicd-release --artifacts=gitlab-go-windows-amd64.exe --artifacts=gitlab-go-windows-arm64.exe --artifacts=gitlab-go-linux-amd64 --artifacts=gitlab-go-linux-arm64 --artifacts=gitlab-go-darwin-amd64 --artifacts=gitlab-go-darwin-arm64 --artifacts=gitlab-go-loong64 --gitlab-export-assets-file-name=gitlab-release-assets.json
- name: Upload Artifactsgitlab-release-assets.json
uses: actions/upload-artifact@v3
with:
name: gitlab-release-assets
path: |
gitlab-release-assets.json
release-gitlink: release-gitlink:
needs: build needs: build
@ -246,14 +253,58 @@ jobs:
- name: Release GitLink - name: Release GitLink
run: | run: |
./cicd-release-linux-amd64 pre-release gitlink --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitlink-repository=$GITHUB_REPOSITORY --gitlink-username=${{ secrets.PRIVATE_GITLINK_USERNAME }} --gitlink-token=${{ secrets.PRIVATE_GITLINK_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --artifacts=gitlab-go-windows-amd64.exe --artifacts=gitlab-go-windows-arm64.exe --artifacts=gitlab-go-linux-amd64 --artifacts=gitlab-go-linux-arm64 --artifacts=gitlab-go-darwin-amd64 --artifacts=gitlab-go-darwin-arm64 --artifacts=gitlab-go-loong64 --gitlink-cookie=${{ secrets.PRIVATE_GITLINK_COOKIE }} --gitlink-export-assets-file-name=cicd-release-assets.json ./cicd-release-linux-amd64 pre-release gitlink --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitlink-repository=$GITHUB_REPOSITORY --gitlink-username=${{ secrets.PRIVATE_GITLINK_USERNAME }} --gitlink-token=${{ secrets.PRIVATE_GITLINK_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --artifacts=gitlab-go-windows-amd64.exe --artifacts=gitlab-go-windows-arm64.exe --artifacts=gitlab-go-linux-amd64 --artifacts=gitlab-go-linux-arm64 --artifacts=gitlab-go-darwin-amd64 --artifacts=gitlab-go-darwin-arm64 --artifacts=gitlab-go-loong64 --gitlink-cookie=${{ secrets.PRIVATE_GITLINK_COOKIE }} --gitlink-export-assets-file-name=gitlink-release-assets.json
- name: Upload Artifactscicd-release-assets.json - name: Upload Artifactsgitlink-release-assets.json
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: cicd-release-assets name: gitlink-release-assets
path: | path: |
cicd-release-assets.json gitlink-release-assets.json
release-framagit:
needs:
- build
- release-gitlab
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
# 获取所有的代码历史记录,包括分支和标签
fetch-depth: 0
- name: Download Artifactsxuxiaowei-com-cn/cicd-release
uses: actions/download-artifact@v3
with:
name: cicd-release
path: .
- name: Download Artifacts
uses: actions/download-artifact@v3
with:
name: gitlab-go
path: .
- name: ls -l
run: ls -l
- name: chmod +x cicd-release-linux-amd64
run: chmod +x cicd-release-linux-amd64
- name: ls -l
run: ls -l
- name: Download Artifactsgitlab-release-assets.json
uses: actions/download-artifact@v3
with:
name: gitlab-release-assets
path: .
- name: Release FramaGit
run: |
./cicd-release-linux-amd64 pre-release gitlab --gitlab-instance=https://framagit.org --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitlab-repository=$GITHUB_REPOSITORY --gitlab-username=xuxiaowei --gitlab-token=${{ secrets.PRIVATE_FRAMAGIT_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --gitlab-import-assets-file-name=gitlab-release-assets.json
release-gitee: release-gitee:
needs: needs:
@ -289,12 +340,12 @@ jobs:
- name: ls -l - name: ls -l
run: ls -l run: ls -l
- name: Download Artifactscicd-release-assets.json - name: Download Artifactsgitlink-release-assets.json
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
name: cicd-release-assets name: gitlink-release-assets
path: . path: .
- name: Release Gitee - name: Release Gitee
run: | run: |
./cicd-release-linux-amd64 pre-release gitee --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitee-repository=$GITHUB_REPOSITORY --gitee-username=$GITHUB_ACTOR --gitee-token=${{ secrets.PRIVATE_GITEE_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --gitlink-export-assets-file-name=cicd-release-assets.json ./cicd-release-linux-amd64 pre-release gitee --release-name=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --tag=v0.0.0-${{ needs.build.outputs.YEAR_MONTH_DAY_HOUR_MINUTE }} --auto-create-tag --gitee-repository=$GITHUB_REPOSITORY --gitee-username=$GITHUB_ACTOR --gitee-token=${{ secrets.PRIVATE_GITEE_TOKEN }} --release-body=${{ needs.build.outputs.RELEASE_BODY }} --gitlink-export-assets-file-name=gitlink-release-assets.json

View File

@ -99,6 +99,10 @@ build:docker:
expire_in: 3 day expire_in: 3 day
paths: paths:
- docker/debian/*.tar - docker/debian/*.tar
rules:
# framagit.org 不构建 docker 镜像
- if: $CI_SERVER_HOST == 'framagit.org'
when: never
build:golang:1.21-alpine3.18: build:golang:1.21-alpine3.18:
stage: build stage: build
@ -191,6 +195,10 @@ build:docker:alpine3.18:
expire_in: 3 day expire_in: 3 day
paths: paths:
- docker/alpine/*.tar - docker/alpine/*.tar
rules:
# framagit.org 不构建 docker 镜像
- if: $CI_SERVER_HOST == 'framagit.org'
when: never
# 嵌入 # 嵌入
include: include:

384
README.md
View File

@ -129,8 +129,8 @@
1. 一键发布到 github可包含产物上传 1. 一键发布到 github可包含产物上传
2. 一键发布到 gitlab可包含产物上传可自定义域名支持自建 gitlab支持将产物文件名、链接导出为 map可供 gitee 使用 2. 一键发布到 gitlab可包含产物上传可自定义域名支持自建 gitlab支持将产物文件名、链接导出为 map可供 gitee 使用
3. 一键发布到 gitee由于 gitee 暂不支持提供上传产物的 API 接口, 3. 一键发布到 gitee由于 gitee 暂不支持提供上传产物的 API 接口,
本工具支持提供 json 文件map 形式,键:代表文件名,值:代表下载链接)作为产物,本项目使用 [GitLink](https://www.gitlink.org.cn) 作为 本工具支持提供 json 文件map 形式,键:代表文件名,值:代表下载链接)作为产物,
gitee 产物链接 本项目使用 [GitLink](https://www.gitlink.org.cn) 作为 gitee 产物链接
4. 一键发布到 gitlink可包含产物上传需要等到官方开放 token 功能,或者联系官方人员申请 token 才能使用), 4. 一键发布到 gitlink可包含产物上传需要等到官方开放 token 功能,或者联系官方人员申请 token 才能使用),
本工具支持提供 json 文件map 形式,键:代表文件名,值:代表下载链接)作为产物 本工具支持提供 json 文件map 形式,键:代表文件名,值:代表下载链接)作为产物
@ -140,7 +140,10 @@
```shell ```shell
go env -w GOPROXY=https://goproxy.cn,direct go env -w GOPROXY=https://goproxy.cn,direct
# go env -w GOPROXY=https://proxy.golang.org,direct
# go env -w GOPROXY=https://goproxy.io,direct
# go env -w GOPROXY=https://mirrors.aliyun.com/goproxy,direct # go env -w GOPROXY=https://mirrors.aliyun.com/goproxy,direct
# go env -w GOPROXY=https://mirrors.cloud.tencent.com/go,direct
go get -u github.com/urfave/cli/v2 go get -u github.com/urfave/cli/v2
go get -u github.com/xanzy/go-gitlab go get -u github.com/xanzy/go-gitlab
go get -u github.com/xuxiaowei-com-cn/git-go@main go get -u github.com/xuxiaowei-com-cn/git-go@main
@ -178,7 +181,7 @@ NAME:
gitlab-go - 基于 Go 语言开发的 GitLab 命令行工具 gitlab-go - 基于 Go 语言开发的 GitLab 命令行工具
USAGE: USAGE:
gitlab-go [global options] command [command options] [arguments...] gitlab-go [global options] command [command options]
VERSION: VERSION:
dev dev
@ -187,19 +190,27 @@ AUTHOR:
徐晓伟 <xuxiaowei@xuxiaowei.com.cn> 徐晓伟 <xuxiaowei@xuxiaowei.com.cn>
COMMANDS: COMMANDS:
access-request, access-requests, ar 群组和项目访问请求 API中文文档https://docs.gitlab.cn/jh/api/access_requests.html access-request, access-requests, ar 群组和项目访问请求 API中文文档https://docs.gitlab.cn/jh/api/access_requests.html
board, boards 项目议题板 API中文文档https://docs.gitlab.cn/jh/api/boards.html board, boards 项目议题板 API中文文档https://docs.gitlab.cn/jh/api/boards.html
container-registry, cr 容器仓库 API中文文档https://docs.gitlab.cn/jh/api/container_registry.html container-registry, cr 容器仓库 API中文文档https://docs.gitlab.cn/jh/api/container_registry.html
instance-level-ci-variable, instance-level-ci-variables, ilcv 实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html environments, environment, env 环境 API中文文档https://docs.gitlab.cn/jh/api/environments.html
issue, issues 议题 API中文文档https://docs.gitlab.cn/jh/api/issues.html instance-level-ci-variables, instance-level-ci-variable, ilcv 实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html
job-artifact, job-artifacts, ja 作业产物 API中文文档https://docs.gitlab.cn/jh/api/job_artifacts.html issue, issues 议题 API中文文档https://docs.gitlab.cn/jh/api/issues.html
job, jobs, j 作业 API中文文档https://docs.gitlab.cn/jh/api/jobs.html job-artifact, job-artifacts, ja 作业产物 API中文文档https://docs.gitlab.cn/jh/api/job_artifacts.html
pipeline, pipelines, pl 流水线 API中文文档https://docs.gitlab.cn/jh/api/pipelines.html job, jobs, j 作业 API中文文档https://docs.gitlab.cn/jh/api/jobs.html
project, projects, p 项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html pipeline, pipelines, pl 流水线 API中文文档https://docs.gitlab.cn/jh/api/pipelines.html
mix-delete, mix-rm 删除(混合命令,多接口命令) project-level-variables, project-level-variable, plv 项目级别 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/project_level_variables.html
mix-archive 归档(混合命令,多接口命令) project, projects, p 项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html
mix-export 导出(混合命令,多接口命令) protected-branches, pb 受保护的分支 API中文文档https://docs.gitlab.cn/jh/api/protected_branches.html
help, h Shows a list of commands or help for one command mix-archive 归档(混合命令,多接口命令)
mix-create-project-level-variables 创建项目级别 CI/CD 变量(混合命令,多接口命令)
mix-delete, mix-rm 删除(混合命令,多接口命令)
mix-create-environments, mix-create-environment, mix-create-env 创建新环境(混合命令,多接口命令)
mix-export 导出(混合命令,多接口命令)
mix-protect-branches 保护仓库分支(混合命令,多接口命令)
mix-transfer 转移(混合命令,多接口命令)
mix-unarchive 取消归档(混合命令,多接口命令)
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS: GLOBAL OPTIONS:
--help, -h show help --help, -h show help
@ -217,7 +228,7 @@ COPYRIGHT:
gitlab-go access-request - 群组和项目访问请求 API中文文档https://docs.gitlab.cn/jh/api/access_requests.html gitlab-go access-request - 群组和项目访问请求 API中文文档https://docs.gitlab.cn/jh/api/access_requests.html
USAGE: USAGE:
gitlab-go access-request command [command options] [arguments...] gitlab-go access-request command [command options]
COMMANDS: COMMANDS:
group, groups 为群组列出访问请求 group, groups 为群组列出访问请求
@ -243,7 +254,7 @@ COPYRIGHT:
gitlab-go board - 项目议题板 API中文文档https://docs.gitlab.cn/jh/api/boards.html gitlab-go board - 项目议题板 API中文文档https://docs.gitlab.cn/jh/api/boards.html
USAGE: USAGE:
gitlab-go board command [command options] [arguments...] gitlab-go board command [command options]
COMMANDS: COMMANDS:
list 列出项目议题板 list 列出项目议题板
@ -268,7 +279,7 @@ COPYRIGHT:
gitlab-go container-registry - 容器仓库 API中文文档https://docs.gitlab.cn/jh/api/container_registry.html gitlab-go container-registry - 容器仓库 API中文文档https://docs.gitlab.cn/jh/api/container_registry.html
USAGE: USAGE:
gitlab-go container-registry command [command options] [arguments...] gitlab-go container-registry command [command options]
COMMANDS: COMMANDS:
list 列出仓库内存储库 list 列出仓库内存储库
@ -290,15 +301,44 @@ COPYRIGHT:
--help, -h show help --help, -h show help
``` ```
- [instance-level-ci-variable - 实例级 CI/CD 变量 API](https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html) - [environments 环境 API](https://docs.gitlab.cn/jh/api/environments.html)
```shell ```shell
$ go run main.go instance-level-ci-variable --help $ go run main.go environments --help
NAME: NAME:
gitlab-go instance-level-ci-variable - 实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html gitlab-go environments - 环境 API中文文档https://docs.gitlab.cn/jh/api/environments.html
USAGE: USAGE:
gitlab-go instance-level-ci-variable command [command options] [arguments...] gitlab-go environments command [command options]
COMMANDS:
list 列举环境
create 创建新环境
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--id value 项目 ID 或 URL 编码的路径
--name value 环境名称
--external-url value 该环境的链接位置
--tier value 新环境的层级。允许设置的值为 production staging testing development 和 other
--page value 页码默认1中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 1)
--per-page value 每页列出的项目数默认20最大100中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 20)
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
```
- [instance-level-ci-variables - 实例级 CI/CD 变量 API](https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html)
```shell
$ go run main.go instance-level-ci-variables --help
NAME:
gitlab-go instance-level-ci-variables - 实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html
USAGE:
gitlab-go instance-level-ci-variables command [command options]
COMMANDS: COMMANDS:
list 列出所有实例变量 list 列出所有实例变量
@ -322,7 +362,7 @@ COPYRIGHT:
gitlab-go issue - 议题 API中文文档https://docs.gitlab.cn/jh/api/issues.html gitlab-go issue - 议题 API中文文档https://docs.gitlab.cn/jh/api/issues.html
USAGE: USAGE:
gitlab-go issue command [command options] [arguments...] gitlab-go issue command [command options]
COMMANDS: COMMANDS:
list 列出议题 list 列出议题
@ -375,7 +415,7 @@ COPYRIGHT:
gitlab-go job-artifact - 作业产物 API中文文档https://docs.gitlab.cn/jh/api/job_artifacts.html gitlab-go job-artifact - 作业产物 API中文文档https://docs.gitlab.cn/jh/api/job_artifacts.html
USAGE: USAGE:
gitlab-go job-artifact command [command options] [arguments...] gitlab-go job-artifact command [command options]
COMMANDS: COMMANDS:
get 获取(下载)作业产物 get 获取(下载)作业产物
@ -401,7 +441,7 @@ COPYRIGHT:
gitlab-go job - 作业 API中文文档https://docs.gitlab.cn/jh/api/jobs.html gitlab-go job - 作业 API中文文档https://docs.gitlab.cn/jh/api/jobs.html
USAGE: USAGE:
gitlab-go job command [command options] [arguments...] gitlab-go job command [command options]
COMMANDS: COMMANDS:
list 列出项目作业 list 列出项目作业
@ -435,7 +475,7 @@ COPYRIGHT:
gitlab-go pipeline - 流水线 API中文文档https://docs.gitlab.cn/jh/api/pipelines.html gitlab-go pipeline - 流水线 API中文文档https://docs.gitlab.cn/jh/api/pipelines.html
USAGE: USAGE:
gitlab-go pipeline command [command options] [arguments...] gitlab-go pipeline command [command options]
COMMANDS: COMMANDS:
list 列出项目流水线 list 列出项目流水线
@ -454,6 +494,39 @@ COPYRIGHT:
--help, -h show help --help, -h show help
``` ```
- [project-level-variables 项目级别 CI/CD 变量 API](https://docs.gitlab.cn/jh/api/project_level_variables.html)
```shell
$ go run main.go project-level-variables --help
NAME:
gitlab-go project-level-variables - 项目级别 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/project_level_variables.html
USAGE:
gitlab-go project-level-variables command [command options]
COMMANDS:
list 列出项目变量
create 创建变量
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--id value 项目 ID 或 URL 编码的路径
--key value 变量的 key。不能超过 255 个字符。仅支持 A-Z、a-z、0-9 和 _
--value value 变量的 value
--variable-type value 变量类型。可用类型为env_var 和 file (default: "env_var")
--protected 变量是否受保护。 (default: false)
--masked 变量是否隐藏。 (default: false)
--raw 变量是否被视为原始字符串。当为 true 时,值中的变量不会扩展 (default: false)
--environment-scope value 变量的 environment_scope。 (default: "*")
--page value 页码默认1中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 1)
--per-page value 每页列出的项目数默认20最大100中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 20)
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
```
- [project - 项目 API](https://docs.gitlab.cn/jh/api/projects.html) - [project - 项目 API](https://docs.gitlab.cn/jh/api/projects.html)
```shell ```shell
@ -462,7 +535,7 @@ COPYRIGHT:
gitlab-go project - 项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html gitlab-go project - 项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html
USAGE: USAGE:
gitlab-go project command [command options] [arguments...] gitlab-go project command [command options]
COMMANDS: COMMANDS:
list 列出所有项目 list 列出所有项目
@ -471,6 +544,7 @@ COPYRIGHT:
OPTIONS: OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%] --base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token --token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false)
--sort value 按照 asc 或者 desc 排序 (default: "desc") --sort value 按照 asc 或者 desc 排序 (default: "desc")
--page value 页码默认1中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 1) --page value 页码默认1中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 1)
--per-page value 每页列出的项目数默认20最大100中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 20) --per-page value 每页列出的项目数默认20最大100中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 20)
@ -482,7 +556,117 @@ COPYRIGHT:
--help, -h show help --help, -h show help
``` ```
- 删除(混合命令,多接口命令) - [protected-branches 受保护的分支 API](https://docs.gitlab.cn/jh/api/protected_branches.html)
```shell
$ go run main.go protected-branches --help
NAME:
gitlab-go protected-branches - 受保护的分支 API中文文档https://docs.gitlab.cn/jh/api/protected_branches.html
USAGE:
gitlab-go protected-branches command [command options]
COMMANDS:
list 列出受保护的分支
protect 保护仓库分支
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--id value 项目 ID 或 URL 编码的路径
--search value 要搜索的受保护分支的名称或部分名称
--name value 分支或通配符的名称
--push-access-level value 允许推送的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--merge-access-level value 允许合并的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--unprotect-access-level value 允许取消保护的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--allow-force-push 启用后,可以推送到该分支的成员也可以强制推送 (default: false)
--code-owner-approval-required 如果分支在 CODEOWNERS https://docs.gitlab.cn/jh/user/project/codeowners/index.html 文件中则阻止推送到此分支。默认值false (default: false)
--page value 页码默认1中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 1)
--per-page value 每页列出的项目数默认20最大100中文文档 https://docs.gitlab.cn/jh/api/rest/index.html#pagination (default: 20)
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
```
- mix-archive 归档(混合命令,多接口命令)
```shell
$ go run main.go mix-archive --help
NAME:
gitlab-go mix-archive - 归档(混合命令,多接口命令)
USAGE:
gitlab-go mix-archive command [command options]
COMMANDS:
all 归档所有项目(混合命令,多接口命令)
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false)
--help, -h show help
```
- mix-create-project-level-variables 创建项目级别 CI/CD 变量(混合命令,多接口命令)
```shell
$ go run main.go mix-create-project-level-variables --help
NAME:
gitlab-go mix-create-project-level-variables - 创建项目级别 CI/CD 变量(混合命令,多接口命令)
USAGE:
gitlab-go mix-create-project-level-variables command [command options]
COMMANDS:
all, a 所有项目创建新变量
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--key value 变量的 key。不能超过 255 个字符。仅支持 A-Z、a-z、0-9 和 _
--value value 变量的 value
--variable-type value 变量类型。可用类型为env_var 和 file (default: "env_var")
--protected 变量是否受保护。 (default: false)
--masked 变量是否隐藏。 (default: false)
--raw 变量是否被视为原始字符串。当为 true 时,值中的变量不会扩展 (default: false)
--environment-scope value 变量的 environment_scope。 (default: "*")
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
```
- mix-delete 删除(混合命令,多接口命令)
```shell ```shell
$ go run main.go mix-delete --help $ go run main.go mix-delete --help
@ -490,7 +674,7 @@ COPYRIGHT:
gitlab-go mix-delete - 删除(混合命令,多接口命令) gitlab-go mix-delete - 删除(混合命令,多接口命令)
USAGE: USAGE:
gitlab-go mix-delete command [command options] [arguments...] gitlab-go mix-delete command [command options]
COMMANDS: COMMANDS:
artifact, artifacts 根据项目路径/ID、流水线IID范围删除产物混合命令多接口命令立即删除 artifact, artifacts 根据项目路径/ID、流水线IID范围删除产物混合命令多接口命令立即删除
@ -511,28 +695,35 @@ COPYRIGHT:
多个数字使用英文逗号隔开1,2,3,7,8,15 多个数字使用英文逗号隔开1,2,3,7,8,15
支持范围5-10, 支持范围5-10,
支持范围方向选择:-10小于等于10从 0 到 10214-大于等于214从 214 到 214 + 10000数据范围不超过 10000 支持范围方向选择:-10小于等于10从 0 到 10214-大于等于214从 214 到 214 + 10000数据范围不超过 10000
--allow-failure 允许失败 (default: false)
--help, -h show help --help, -h show help
``` ```
- 归档(混合命令,多接口命令) - mix-create-environments 创建新环境(混合命令,多接口命令)
```shell ```shell
$ go run main.go mix-archive --help $ go run main.go mix-create-environments --help
NAME: NAME:
gitlab-go mix-archive - 归档(混合命令,多接口命令) gitlab-go mix-create-environments - 创建新环境(混合命令,多接口命令)
USAGE: USAGE:
gitlab-go mix-archive command [command options] [arguments...] gitlab-go mix-create-environments command [command options]
COMMANDS: COMMANDS:
all 归档所有项目(混合命令,多接口命令) all, a 所有项目创建新环境
help, h Shows a list of commands or help for one command help, h Shows a list of commands or help for one command
OPTIONS: OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%] --base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token --token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false) --owned 当前用户明确拥有的项目。 (default: false)
--help, -h show help --name value 环境名称
--external-url value 该环境的链接位置
--tier value 新环境的层级。允许设置的值为 production staging testing development 和 other
--allow-failure 允许失败 (default: false)
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
``` ```
- 导出(混合命令,多接口命令) - 导出(混合命令,多接口命令)
@ -543,7 +734,7 @@ COPYRIGHT:
gitlab-go mix-export - 导出(混合命令,多接口命令) gitlab-go mix-export - 导出(混合命令,多接口命令)
USAGE: USAGE:
gitlab-go mix-export command [command options] [arguments...] gitlab-go mix-export command [command options]
COMMANDS: COMMANDS:
all, a 导出所有(混合命令,多接口命令) all, a 导出所有(混合命令,多接口命令)
@ -555,14 +746,116 @@ COPYRIGHT:
OPTIONS: OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%] --base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token --token value your_access_token
--username value 用户名
--owned 当前用户明确拥有的项目。 (default: false) --owned 当前用户明确拥有的项目。 (default: false)
--export-folder value 导出文件夹 --export-folder value 导出文件夹
--skip-project-path value [ --skip-project-path value ] 跳过项目路径 --skip-project-path value [ --skip-project-path value ] 跳过项目路径
--skip-project-wiki-path value [ --skip-project-wiki-path value ] 跳过项目wiki路径 --skip-project-wiki-path value [ --skip-project-wiki-path value ] 跳过项目wiki路径
--auto-skip-exist-folder 自动跳过已存在的文件夹 (default: false)
--allow-failure 允许失败 (default: false)
--help, -h show help --help, -h show help
``` ```
- 保护仓库分支(混合命令,多接口命令)
```shell
$ go run main.go mix-protect-branches --help
NAME:
gitlab-go mix-protect-branches - 保护仓库分支(混合命令,多接口命令)
USAGE:
gitlab-go mix-protect-branches command [command options]
COMMANDS:
all, a 保护所有仓库分支
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false)
--name value 分支或通配符的名称
--push-access-level value 允许推送的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--merge-access-level value 允许合并的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--unprotect-access-level value 允许取消保护的访问级别默认值40维护者角色合法值
0NoPermissions
5MinimalAccessPermissions
10GuestPermissions
20ReporterPermissions
30DeveloperPermissions
40MaintainerPermissions
50OwnerPermissions
60AdminPermissions
(default: 40)
--allow-force-push 启用后,可以推送到该分支的成员也可以强制推送 (default: false)
--code-owner-approval-required 如果分支在 CODEOWNERS https://docs.gitlab.cn/jh/user/project/codeowners/index.html 文件中则阻止推送到此分支。默认值false (default: false)
--print-json 打印 JSON (default: false)
--print-time 打印时间 (default: false)
--help, -h show help
```
- 转移(混合命令,多接口命令)
```shell
$ go run main.go mix-transfer --help
NAME:
gitlab-go mix-transfer - 转移(混合命令,多接口命令)
USAGE:
gitlab-go mix-transfer command [command options]
COMMANDS:
all, a 将一个命令空间的项目转移到新的命名空间
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false)
--namespace-source value 源命名空间。如:用户名、群组名
--namespace-target value 目标命名空间。如:用户名、群组名
--skip-project-path value [ --skip-project-path value ] 跳过项目路径
--help, -h show help
```
- 取消归档(混合命令,多接口命令)
```shell
$ go run main.go mix-unarchive --help
NAME:
gitlab-go mix-unarchive - 取消归档(混合命令,多接口命令)
USAGE:
gitlab-go mix-unarchive command [command options]
COMMANDS:
all 取消归档所有项目(混合命令,多接口命令)
help, h Shows a list of commands or help for one command
OPTIONS:
--base-url value 实例地址例如https://gitlab.xuxiaowei.com.cn/api/v4 (default: "https://gitlab.com/api/v4") [%CI_API_V4_URL%]
--token value your_access_token
--owned 当前用户明确拥有的项目。 (default: false)
--help, -h show help
```
### test ### test
```shell ```shell
@ -627,3 +920,12 @@ go build
go build -o buildinfo/buildinfo buildinfo/buildinfo.go go build -o buildinfo/buildinfo buildinfo/buildinfo.go
GOOS=darwin GOARCH=arm64 go build -v -ldflags "-s -w -buildid= -X main.BuildDate=$(buildinfo/buildinfo now) -X main.Compiler= -X main.GitCommitBranch=$(buildinfo/buildinfo commitBranch) -X main.GitCommitSha=$(buildinfo/buildinfo commitSha) -X main.GitCommitShortSha=$(buildinfo/buildinfo commitShortSha) -X main.GitCommitTag=$(buildinfo/buildinfo commitTag) -X main.GitCommitTimestamp=$(buildinfo/buildinfo commitTimestamp) -X main.GitTreeState=$(buildinfo/buildinfo git-tree-state) -X main.GitVersion=$(buildinfo/buildinfo commitTag) -X main.GoVersion=$(buildinfo/buildinfo goShortVersion) -X main.Major= -X main.Minor= -X main.Revision= -X main.Platform=darwin/arm64 -X main.CiPipelineId= -X main.CiJobId=" -trimpath -o gitlab-go-darwin-arm64 . GOOS=darwin GOARCH=arm64 go build -v -ldflags "-s -w -buildid= -X main.BuildDate=$(buildinfo/buildinfo now) -X main.Compiler= -X main.GitCommitBranch=$(buildinfo/buildinfo commitBranch) -X main.GitCommitSha=$(buildinfo/buildinfo commitSha) -X main.GitCommitShortSha=$(buildinfo/buildinfo commitShortSha) -X main.GitCommitTag=$(buildinfo/buildinfo commitTag) -X main.GitCommitTimestamp=$(buildinfo/buildinfo commitTimestamp) -X main.GitTreeState=$(buildinfo/buildinfo git-tree-state) -X main.GitVersion=$(buildinfo/buildinfo commitTag) -X main.GoVersion=$(buildinfo/buildinfo goShortVersion) -X main.Major= -X main.Minor= -X main.Revision= -X main.Platform=darwin/arm64 -X main.CiPipelineId= -X main.CiJobId=" -trimpath -o gitlab-go-darwin-arm64 .
``` ```
## 鸣谢
1. 感谢 [![jetbrains](./static/jb_beam.svg)](https://www.jetbrains.com/)
提供开发工具 [![IDEA](./static/IntelliJ_IDEA_icon.svg)](https://www.jetbrains.com/idea) 的免费授权
## Stargazers over time
[![Stargazers over time](https://starchart.cc/xuxiaowei-com-cn/gitlab-go.svg)](https://starchart.cc/xuxiaowei-com-cn/gitlab-go)

View File

@ -4,7 +4,9 @@
```shell ```shell
go env -w GOPROXY=https://goproxy.cn,direct go env -w GOPROXY=https://goproxy.cn,direct
# go env -w GOPROXY=https://goproxy.io,direct
# go env -w GOPROXY=https://mirrors.aliyun.com/goproxy,direct # go env -w GOPROXY=https://mirrors.aliyun.com/goproxy,direct
# go env -w GOPROXY=https://mirrors.cloud.tencent.com/go,direct
go get -u github.com/xuxiaowei-com-cn/git-go@main go get -u github.com/xuxiaowei-com-cn/git-go@main
``` ```

View File

@ -2,11 +2,11 @@ module github.com/xuxiaowei-com-cn/gitlab-go/buildinfo
go 1.21 go 1.21
require github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc require github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/urfave/cli/v2 v2.25.7 // indirect github.com/urfave/cli/v2 v2.26.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
) )

View File

@ -2,11 +2,11 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0q
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc h1:2D2D/n8SYY91dl3NAX4NtGhxdgx8Tgl5Bd6y8KLYzDo= github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9 h1:UqYDttjuhqDiDPdkWLsNiw2YYERM0rCggCgBGayLdEU=
github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc/go.mod h1:1EL7YDsw6C+ctxYYqfBHz2Q0CTK6qjZmq//DYFp4kmo= github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9/go.mod h1:MWrvJioKWJjO24bPY9DXa7BSIzjGkEFarny0xiG1irs=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -1,31 +1,51 @@
package constant package constant
const ( const (
Username = "username" Token = "token"
Token = "token" BaseUrl = "base-url"
BaseUrl = "base-url" BaseUrlDefault = "https://gitlab.com/api/v4"
BaseUrlDefault = "https://gitlab.com/api/v4" Id = "id"
Id = "id" JobIdRange = "job-id-range"
JobIdRange = "job-id-range" IIdRange = "iid-range"
IIdRange = "iid-range" Repository = "repository"
Repository = "repository" TagName = "tag-name"
TagName = "tag-name" JobId = "job-id"
JobId = "job-id" ArtifactsName = "artifacts-name"
ArtifactsName = "artifacts-name" Sort = "sort"
Sort = "sort" SortDefault = "desc"
SortDefault = "desc" Page = "page"
Page = "page" PerPage = "per-page"
PerPage = "per-page" PrintJson = "print-json"
PrintJson = "print-json" PrintJsonDefault = false
PrintJsonDefault = false PrintTime = "print-time"
PrintTime = "print-time" PrintTimeDefault = false
PrintTimeDefault = false Scope = "scope"
Scope = "scope" IssueId = "issue-id"
IssueId = "issue-id" IssueIdRange = "issue-id-range"
IssueIdRange = "issue-id-range" Recursion = "recursion"
Recursion = "recursion" Owned = "owned"
Owned = "owned" NamespaceSource = "namespace-source"
ExportFolder = "export-folder" NamespaceTarget = "namespace-target"
SkipProjectPath = "skip-project-path" ExportFolder = "export-folder"
SkipProjectWikiPath = "skip-project-wiki-path" SkipProjectPath = "skip-project-path"
SkipProjectWikiPath = "skip-project-wiki-path"
AutoSkipExistFolder = "auto-skip-exist-folder"
AllowFailure = "allow-failure"
EnvName = "name"
EnvExternalUrl = "external-url"
EnvTier = "tier"
VariableKey = "key"
VariableValue = "value"
VariableType = "variable-type"
VariableProtected = "protected"
VariableMasked = "masked"
VariableRaw = "raw"
VariableEnvironmentScope = "environment-scope"
ProtectedBranchesSearch = "search"
BranchName = "name"
PushAccessLevel = "push-access-level"
MergeAccessLevel = "merge-access-level"
UnprotectAccessLevel = "unprotect-access-level"
AllowForcePush = "allow-force-push"
CodeOwnerApprovalRequired = "code-owner-approval-required"
) )

108
environments/create.go Normal file
View File

@ -0,0 +1,108 @@
package environments
import (
"encoding/json"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// Create 创建新环境 https://docs.gitlab.cn/jh/api/environments.html#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%8E%AF%E5%A2%83
func Create() *cli.Command {
return &cli.Command{
Name: "create",
Usage: "创建新环境",
Flags: append(flag.CommonTokenRequired(), flag.Id(true), flag.EnvName(true), flag.EnvExternalUrl(), flag.EnvTier(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var name = context.String(constant.EnvName)
var externalURL = context.String(constant.EnvExternalUrl)
var tier = context.String(constant.EnvTier)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
return CreateEnvironment(baseUrl, token, id, name, externalURL, tier, printJson, printTime, false)
},
}
}
func CreateEnvironment(baseUrl string, token string, id interface{}, name string, externalURL string, tier string, printJson bool, printTime bool, allowFailure bool) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.CreateEnvironmentOptions{
Name: &name,
ExternalURL: &externalURL,
}
if tier != "" {
opt.Tier = &tier
}
environment, response, err := gitClient.Environments.CreateEnvironment(id, opt)
if err != nil {
if allowFailure {
return nil
}
return err
}
log.Printf("Response StatusCode: %d\n", response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
jsonData, err := json.Marshal(environment)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
} else {
jsonData, err := json.Marshal(environment)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
} else {
if printTime {
log.Printf("ID: %d\n", environment.ID)
log.Printf("Name: %s\n", environment.Name)
log.Printf("Slug: %s\n", environment.Slug)
log.Printf("State: %s\n", environment.State)
log.Printf("Tier: %s\n", environment.Tier)
log.Printf("ExternalURL: %s\n", environment.ExternalURL)
log.Printf("CreatedAt: %s\n", environment.CreatedAt)
log.Printf("UpdatedAt: %s\n", environment.UpdatedAt)
fmt.Println("")
} else {
fmt.Printf("ID: %d\n", environment.ID)
fmt.Printf("Name: %s\n", environment.Name)
fmt.Printf("Slug: %s\n", environment.Slug)
fmt.Printf("State: %s\n", environment.State)
fmt.Printf("Tier: %s\n", environment.Tier)
fmt.Printf("ExternalURL: %s\n", environment.ExternalURL)
fmt.Printf("CreatedAt: %s\n", environment.CreatedAt)
fmt.Printf("UpdatedAt: %s\n", environment.UpdatedAt)
fmt.Println("")
}
}
return nil
}

View File

@ -0,0 +1,21 @@
package environments
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// Environments 环境 API https://docs.gitlab.cn/jh/api/environments.html
func Environments() *cli.Command {
return &cli.Command{
Name: "environments",
Aliases: []string{"environment", "env"},
Usage: "环境 API中文文档https://docs.gitlab.cn/jh/api/environments.html",
Flags: append(flag.Common(), flag.Id(false), flag.EnvName(false), flag.EnvExternalUrl(), flag.EnvTier(),
flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
List(),
Create(),
},
}
}

102
environments/list.go Normal file
View File

@ -0,0 +1,102 @@
package environments
import (
"encoding/json"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// List 列举环境 https://docs.gitlab.cn/jh/api/environments.html#%E5%88%97%E4%B8%BE%E7%8E%AF%E5%A2%83
func List() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "列举环境",
Flags: append(flag.CommonTokenRequired(), flag.Id(true), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.ListEnvironmentsOptions{
ListOptions: gitlab.ListOptions{
Page: page,
PerPage: perPage,
},
}
environments, response, err := gitClient.Environments.ListEnvironments(id, opt)
if err != nil {
return err
}
log.Printf("Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
for _, environment := range environments {
jsonData, err := json.Marshal(environment)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
}
} else {
for _, environment := range environments {
jsonData, err := json.Marshal(environment)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
}
} else {
if printTime {
for _, environment := range environments {
log.Printf("ID: %d\n", environment.ID)
log.Printf("Name: %s\n", environment.Name)
log.Printf("Slug: %s\n", environment.Slug)
log.Printf("State: %s\n", environment.State)
log.Printf("Tier: %s\n", environment.Tier)
log.Printf("ExternalURL: %s\n", environment.ExternalURL)
log.Printf("CreatedAt: %s\n", environment.CreatedAt)
log.Printf("UpdatedAt: %s\n", environment.UpdatedAt)
fmt.Println("")
}
} else {
for _, environment := range environments {
fmt.Printf("ID: %d\n", environment.ID)
fmt.Printf("Name: %s\n", environment.Name)
fmt.Printf("Slug: %s\n", environment.Slug)
fmt.Printf("State: %s\n", environment.State)
fmt.Printf("Tier: %s\n", environment.Tier)
fmt.Printf("ExternalURL: %s\n", environment.ExternalURL)
fmt.Printf("CreatedAt: %s\n", environment.CreatedAt)
fmt.Printf("UpdatedAt: %s\n", environment.UpdatedAt)
fmt.Println("")
}
}
}
return nil
},
}
}

View File

@ -49,14 +49,6 @@ func BaseUrl() cli.Flag {
} }
} }
func Username(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.Username,
Usage: "用户名",
Required: required,
}
}
func Token(required bool) cli.Flag { func Token(required bool) cli.Flag {
return &cli.StringFlag{ return &cli.StringFlag{
Name: constant.Token, Name: constant.Token,
@ -192,6 +184,22 @@ func Owned(required bool) cli.Flag {
} }
} }
func NamespaceSource(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.NamespaceSource,
Usage: "源命名空间。如:用户名、群组名",
Required: required,
}
}
func NamespaceTargetFlag(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.NamespaceTarget,
Usage: "目标命名空间。如:用户名、群组名",
Required: required,
}
}
func IssueIdRange(required bool) cli.Flag { func IssueIdRange(required bool) cli.Flag {
return &cli.StringSliceFlag{ return &cli.StringSliceFlag{
Name: constant.IssueIdRange, Name: constant.IssueIdRange,
@ -225,3 +233,176 @@ func SkipProjectWikiPath() cli.Flag {
Usage: "跳过项目wiki路径", Usage: "跳过项目wiki路径",
} }
} }
func AutoSkipExistFolder() cli.Flag {
return &cli.BoolFlag{
Name: constant.AutoSkipExistFolder,
Usage: "自动跳过已存在的文件夹",
Value: false,
}
}
func AllowFailure() cli.Flag {
return &cli.BoolFlag{
Name: constant.AllowFailure,
Usage: "允许失败",
Value: false,
}
}
func EnvName(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.EnvName,
Usage: "环境名称",
Required: required,
}
}
func EnvExternalUrl() cli.Flag {
return &cli.StringFlag{
Name: constant.EnvExternalUrl,
Usage: "该环境的链接位置",
}
}
func EnvTier() cli.Flag {
return &cli.StringFlag{
Name: constant.EnvTier,
Usage: "新环境的层级。允许设置的值为 production staging testing development 和 other",
}
}
func VariableKey(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.VariableKey,
Usage: "变量的 key。不能超过 255 个字符。仅支持 A-Z、a-z、0-9 和 _",
Required: required,
}
}
func VariableValue(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.VariableValue,
Usage: "变量的 value",
Required: required,
}
}
func VariableType() cli.Flag {
return &cli.StringFlag{
Name: constant.VariableType,
Usage: "变量类型。可用类型为env_var 和 file",
Value: "env_var",
}
}
func VariableProtected() cli.Flag {
return &cli.BoolFlag{
Name: constant.VariableProtected,
Usage: "变量是否受保护。",
Value: false,
}
}
func VariableMasked() cli.Flag {
return &cli.BoolFlag{
Name: constant.VariableMasked,
Usage: "变量是否隐藏。",
Value: false,
}
}
func VariableRaw() cli.Flag {
return &cli.BoolFlag{
Name: constant.VariableRaw,
Usage: "变量是否被视为原始字符串。当为 true 时,值中的变量不会扩展",
Value: false,
}
}
func VariableEnvironmentScope() cli.Flag {
return &cli.StringFlag{
Name: constant.VariableEnvironmentScope,
Usage: "变量的 environment_scope。",
Value: "*",
}
}
func ProtectedBranchesSearch() cli.Flag {
return &cli.StringFlag{
Name: constant.ProtectedBranchesSearch,
Usage: "要搜索的受保护分支的名称或部分名称",
}
}
func BranchName(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.BranchName,
Usage: "分支或通配符的名称",
Required: required,
}
}
func PushAccessLevel() cli.Flag {
return &cli.IntFlag{
Name: constant.PushAccessLevel,
Usage: "允许推送的访问级别默认值40维护者角色合法值\n\t" +
"0NoPermissions\n\t" +
"5MinimalAccessPermissions\n\t" +
"10GuestPermissions\n\t" +
"20ReporterPermissions\n\t" +
"30DeveloperPermissions\n\t" +
"40MaintainerPermissions\n\t" +
"50OwnerPermissions\n\t" +
"60AdminPermissions\n\t",
Value: 40,
}
}
func MergeAccessLevel() cli.Flag {
return &cli.IntFlag{
Name: constant.MergeAccessLevel,
Usage: "允许合并的访问级别默认值40维护者角色合法值\n\t" +
"0NoPermissions\n\t" +
"5MinimalAccessPermissions\n\t" +
"10GuestPermissions\n\t" +
"20ReporterPermissions\n\t" +
"30DeveloperPermissions\n\t" +
"40MaintainerPermissions\n\t" +
"50OwnerPermissions\n\t" +
"60AdminPermissions\n\t",
Value: 40,
}
}
func UnprotectAccessLevel() cli.Flag {
return &cli.IntFlag{
Name: constant.UnprotectAccessLevel,
Usage: "允许取消保护的访问级别默认值40维护者角色合法值\n\t" +
"0NoPermissions\n\t" +
"5MinimalAccessPermissions\n\t" +
"10GuestPermissions\n\t" +
"20ReporterPermissions\n\t" +
"30DeveloperPermissions\n\t" +
"40MaintainerPermissions\n\t" +
"50OwnerPermissions\n\t" +
"60AdminPermissions\n\t",
Value: 40,
}
}
func AllowForcePush() cli.Flag {
return &cli.BoolFlag{
Name: constant.AllowForcePush,
Usage: "启用后,可以推送到该分支的成员也可以强制推送",
Value: false,
}
}
func CodeOwnerApprovalRequired() cli.Flag {
return &cli.BoolFlag{
Name: constant.CodeOwnerApprovalRequired,
Usage: "如果分支在 CODEOWNERS https://docs.gitlab.cn/jh/user/project/codeowners/index.html 文件中则阻止推送到此分支。默认值false",
Value: false,
}
}

14
go.mod
View File

@ -3,9 +3,9 @@ module github.com/xuxiaowei-com-cn/gitlab-go
go 1.21 go 1.21
require ( require (
github.com/urfave/cli/v2 v2.25.7 github.com/urfave/cli/v2 v2.27.1
github.com/xanzy/go-gitlab v0.94.0 github.com/xanzy/go-gitlab v0.95.2
github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@ -16,9 +16,9 @@ require (
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
golang.org/x/oauth2 v0.14.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/time v0.4.0 // indirect golang.org/x/time v0.5.0 // indirect
google.golang.org/appengine v1.6.8 // indirect google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect google.golang.org/protobuf v1.32.0 // indirect
) )

28
go.sum
View File

@ -25,14 +25,14 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xanzy/go-gitlab v0.94.0 h1:GmBl2T5zqUHqyjkxFSvsT7CbelGdAH/dmBqUBqS+4BE= github.com/xanzy/go-gitlab v0.95.2 h1:4p0IirHqEp5f0baK/aQqr4TR57IsD+8e4fuyAA1yi88=
github.com/xanzy/go-gitlab v0.94.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/go-gitlab v0.95.2/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc h1:2D2D/n8SYY91dl3NAX4NtGhxdgx8Tgl5Bd6y8KLYzDo= github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9 h1:UqYDttjuhqDiDPdkWLsNiw2YYERM0rCggCgBGayLdEU=
github.com/xuxiaowei-com-cn/git-go v0.0.0-20231127015559-635f5e3143dc/go.mod h1:1EL7YDsw6C+ctxYYqfBHz2Q0CTK6qjZmq//DYFp4kmo= github.com/xuxiaowei-com-cn/git-go v0.0.0-20231220150841-0d99ea39e1f9/go.mod h1:MWrvJioKWJjO24bPY9DXa7BSIzjGkEFarny0xiG1irs=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@ -40,8 +40,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -55,8 +55,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@ -66,8 +66,8 @@ google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAs
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -8,8 +8,8 @@ import (
// InstanceLevelCiVariables 实例级 CI/CD 变量 API https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html // InstanceLevelCiVariables 实例级 CI/CD 变量 API https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html
func InstanceLevelCiVariables() *cli.Command { func InstanceLevelCiVariables() *cli.Command {
return &cli.Command{ return &cli.Command{
Name: "instance-level-ci-variable", Name: "instance-level-ci-variables",
Aliases: []string{"instance-level-ci-variables", "ilcv"}, Aliases: []string{"instance-level-ci-variable", "ilcv"},
Usage: "实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html", Usage: "实例级 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/instance_level_ci_variables.html",
Flags: append(flag.Common(), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()), Flags: append(flag.Common(), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{

13
main.go
View File

@ -6,13 +6,16 @@ import (
"github.com/xuxiaowei-com-cn/gitlab-go/access_requests" "github.com/xuxiaowei-com-cn/gitlab-go/access_requests"
"github.com/xuxiaowei-com-cn/gitlab-go/boards" "github.com/xuxiaowei-com-cn/gitlab-go/boards"
"github.com/xuxiaowei-com-cn/gitlab-go/container_registry" "github.com/xuxiaowei-com-cn/gitlab-go/container_registry"
"github.com/xuxiaowei-com-cn/gitlab-go/environments"
"github.com/xuxiaowei-com-cn/gitlab-go/instance_level_ci_variables" "github.com/xuxiaowei-com-cn/gitlab-go/instance_level_ci_variables"
"github.com/xuxiaowei-com-cn/gitlab-go/issues" "github.com/xuxiaowei-com-cn/gitlab-go/issues"
"github.com/xuxiaowei-com-cn/gitlab-go/job_artifacts" "github.com/xuxiaowei-com-cn/gitlab-go/job_artifacts"
"github.com/xuxiaowei-com-cn/gitlab-go/jobs" "github.com/xuxiaowei-com-cn/gitlab-go/jobs"
"github.com/xuxiaowei-com-cn/gitlab-go/mix" "github.com/xuxiaowei-com-cn/gitlab-go/mix"
"github.com/xuxiaowei-com-cn/gitlab-go/pipelines" "github.com/xuxiaowei-com-cn/gitlab-go/pipelines"
"github.com/xuxiaowei-com-cn/gitlab-go/project_level_variables"
"github.com/xuxiaowei-com-cn/gitlab-go/projects" "github.com/xuxiaowei-com-cn/gitlab-go/projects"
"github.com/xuxiaowei-com-cn/gitlab-go/protected_branches"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"log" "log"
"os" "os"
@ -70,15 +73,23 @@ func main() {
access_requests.AccessRequests(), access_requests.AccessRequests(),
boards.Boards(), boards.Boards(),
container_registry.ContainerRegistry(), container_registry.ContainerRegistry(),
environments.Environments(),
instance_level_ci_variables.InstanceLevelCiVariables(), instance_level_ci_variables.InstanceLevelCiVariables(),
issues.Issues(), issues.Issues(),
job_artifacts.JobsArtifacts(), job_artifacts.JobsArtifacts(),
jobs.Jobs(), jobs.Jobs(),
pipelines.Pipelines(), pipelines.Pipelines(),
project_level_variables.ProjectLevelVariables(),
projects.Projects(), projects.Projects(),
mix.Delete(), protected_branches.ProtectedBranches(),
mix.Archive(), mix.Archive(),
mix.CreateProjectLevelVariables(),
mix.Delete(),
mix.Environments(),
mix.Export(), mix.Export(),
mix.ProtectBranches(),
mix.Transfer(),
mix.Unarchive(),
}, },
} }

View File

@ -19,7 +19,7 @@ func ArchiveAll() *cli.Command {
var token = context.String(constant.Token) var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned) var owned = context.Bool(constant.Owned)
projectList, err := projects.ListProjects(&owned, token, baseUrl, 1, 100) projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil { if err != nil {
return err return err
} }

View File

@ -18,7 +18,8 @@ func DeleteJobs() *cli.Command {
Name: "job", Name: "job",
Aliases: []string{"jobs"}, Aliases: []string{"jobs"},
Usage: "根据项目路径/ID、流水线IID范围删除作业产物和作业日志混合命令多接口命令立即删除", Usage: "根据项目路径/ID、流水线IID范围删除作业产物和作业日志混合命令多接口命令立即删除",
Flags: append(flag.CommonTokenRequired(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(true), flag.IIdRange(true)), Flags: append(flag.CommonTokenRequired(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(true),
flag.IIdRange(true), flag.AllowFailure()),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl) var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token) var token = context.String(constant.Token)
@ -27,6 +28,7 @@ func DeleteJobs() *cli.Command {
var page = context.Int(constant.Page) var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage) var perPage = context.Int(constant.PerPage)
var iidRanges = context.StringSlice(constant.IIdRange) var iidRanges = context.StringSlice(constant.IIdRange)
var allowFailure = context.Bool(constant.AllowFailure)
fmt.Println(iidRanges) fmt.Println(iidRanges)
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl)) gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
@ -45,7 +47,7 @@ func DeleteJobs() *cli.Command {
return nil return nil
} }
err = DeleteJobsRecursion(gitClient, id, page, perPage, sortStr, iids) err = DeleteJobsRecursion(gitClient, id, page, perPage, sortStr, iids, allowFailure)
if err != nil { if err != nil {
return err return err
} }
@ -55,7 +57,7 @@ func DeleteJobs() *cli.Command {
} }
} }
func DeleteJobsRecursion(gitClient *gitlab.Client, id interface{}, page int, perPage int, sort string, iids []int) error { func DeleteJobsRecursion(gitClient *gitlab.Client, id interface{}, page int, perPage int, sort string, iids []int, allowFailure bool) error {
pipelineInfos, response, err := pipelines.ListProjectPipelines(gitClient, id, page, perPage, sort) pipelineInfos, response, err := pipelines.ListProjectPipelines(gitClient, id, page, perPage, sort)
@ -78,26 +80,26 @@ func DeleteJobsRecursion(gitClient *gitlab.Client, id interface{}, page int, per
if iidsMin == pipelineInfo.IID { if iidsMin == pipelineInfo.IID {
// 等于最小值,删除最小值 // 等于最小值,删除最小值
iids = iids[1:] iids = iids[1:]
err = ExecuteDeleteJobs(gitClient, id, pipelineInfo.ID, 1, 100) err = ExecuteDeleteJobs(gitClient, id, pipelineInfo.ID, 1, 100, allowFailure)
if err != nil { if err != nil {
return err return err
} }
} else if pipelineInfo.IID == iidsMax { } else if pipelineInfo.IID == iidsMax {
// 等于最大值 // 等于最大值
iids = iids[:len(iids)-1] iids = iids[:len(iids)-1]
err = ExecuteDeleteJobs(gitClient, id, pipelineInfo.ID, 1, 100) err = ExecuteDeleteJobs(gitClient, id, pipelineInfo.ID, 1, 100, allowFailure)
if err != nil { if err != nil {
return err return err
} }
} else if iidsMin < pipelineInfo.IID { } else if iidsMin < pipelineInfo.IID {
// 大于最小值 // 大于最小值
err = jobsForExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID) err = jobsForExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID, allowFailure)
if err != nil { if err != nil {
return err return err
} }
} else if pipelineInfo.IID < iidsMax { } else if pipelineInfo.IID < iidsMax {
// 小于最大值 // 小于最大值
err = jobsForExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID) err = jobsForExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID, allowFailure)
if err != nil { if err != nil {
return err return err
} }
@ -115,7 +117,7 @@ func DeleteJobsRecursion(gitClient *gitlab.Client, id interface{}, page int, per
} }
if len(pipelineInfos) > 0 { if len(pipelineInfos) > 0 {
err := DeleteJobsRecursion(gitClient, id, page+1, perPage, sort, iids) err := DeleteJobsRecursion(gitClient, id, page+1, perPage, sort, iids, allowFailure)
if err != nil { if err != nil {
return err return err
} }
@ -124,13 +126,16 @@ func DeleteJobsRecursion(gitClient *gitlab.Client, id interface{}, page int, per
return nil return nil
} }
func jobsForExecute(iids *[]int, pipelineInfoIId int, gitClient *gitlab.Client, id interface{}, pipelineInfoId int) error { func jobsForExecute(iids *[]int, pipelineInfoIId int, gitClient *gitlab.Client, id interface{}, pipelineInfoId int, allowFailure bool) error {
for i := 0; i < len(*iids); i++ { for i := 0; i < len(*iids); i++ {
if (*iids)[i] == pipelineInfoIId { if (*iids)[i] == pipelineInfoIId {
fmt.Printf("数组中包含%d\n", pipelineInfoIId) fmt.Printf("数组中包含%d\n", pipelineInfoIId)
*iids = append((*iids)[:i], (*iids)[i+1:]...) *iids = append((*iids)[:i], (*iids)[i+1:]...)
err := ExecuteDeleteJobs(gitClient, id, pipelineInfoId, 1, 100) err := ExecuteDeleteJobs(gitClient, id, pipelineInfoId, 1, 100, allowFailure)
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }
break break
@ -139,7 +144,7 @@ func jobsForExecute(iids *[]int, pipelineInfoIId int, gitClient *gitlab.Client,
return nil return nil
} }
func ExecuteDeleteJobs(gitClient *gitlab.Client, id interface{}, pipelineInfoId int, page int, perPage int) error { func ExecuteDeleteJobs(gitClient *gitlab.Client, id interface{}, pipelineInfoId int, page int, perPage int, allowFailure bool) error {
fmt.Printf("执行删除 %d \n", pipelineInfoId) fmt.Printf("执行删除 %d \n", pipelineInfoId)
opt := &gitlab.ListJobsOptions{ opt := &gitlab.ListJobsOptions{
@ -160,13 +165,16 @@ func ExecuteDeleteJobs(gitClient *gitlab.Client, id interface{}, pipelineInfoId
_, response, err = gitClient.Jobs.EraseJob(id, job.ID) _, response, err = gitClient.Jobs.EraseJob(id, job.ID)
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }
log.Printf("Delete Project %s Job %d Response StatusCode: %d\n", id, job.ID, response.Response.StatusCode) log.Printf("Delete Project %s Job %d Response StatusCode: %d\n", id, job.ID, response.Response.StatusCode)
} }
if len(jobs) == perPage { if len(jobs) == perPage {
err = ExecuteDeleteJobs(gitClient, id, pipelineInfoId, page+1, perPage) err = ExecuteDeleteJobs(gitClient, id, pipelineInfoId, page+1, perPage, allowFailure)
if err != nil { if err != nil {
return err return err
} }

View File

@ -0,0 +1,49 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/environments"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"log"
)
// EnvironmentsCreateAll 所有项目创建新环境
func EnvironmentsCreateAll() *cli.Command {
return &cli.Command{
Name: "all",
Aliases: []string{"a"},
Usage: "所有项目创建新环境",
Flags: append(flag.CommonTokenRequired(), flag.Owned(true),
flag.EnvName(false), flag.EnvExternalUrl(), flag.EnvTier(), flag.AllowFailure(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
var name = context.String(constant.EnvName)
var externalURL = context.String(constant.EnvExternalUrl)
var tier = context.String(constant.EnvTier)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
var allowFailure = context.Bool(constant.AllowFailure)
projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = environments.CreateEnvironment(baseUrl, token, project.ID, name, externalURL, tier, printJson, printTime, allowFailure)
if err != nil {
return err
}
}
return nil
},
}
}

View File

@ -23,17 +23,19 @@ func ExportAll() *cli.Command {
"已包含:\n" + "已包含:\n" +
"1. git 仓库\n" + "1. git 仓库\n" +
"2. wiki 仓库", "2. wiki 仓库",
Flags: append(flag.CommonTokenRequired(), flag.Username(true), flag.Owned(true), Flags: append(flag.CommonTokenRequired(), flag.Owned(true),
flag.ExportFolder(true), flag.SkipProjectPath(), flag.SkipProjectWikiPath()), flag.ExportFolder(true), flag.SkipProjectPath(), flag.SkipProjectWikiPath(),
flag.AutoSkipExistFolder(), flag.AllowFailure()),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl) var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token) var token = context.String(constant.Token)
var username = context.String(constant.Username)
var owned = context.Bool(constant.Owned) var owned = context.Bool(constant.Owned)
var exportFolder = context.String(constant.ExportFolder) var exportFolder = context.String(constant.ExportFolder)
var skipProjectPaths = context.StringSlice(constant.SkipProjectPath) var skipProjectPaths = context.StringSlice(constant.SkipProjectPath)
var skipProjectWikiPaths = context.StringSlice(constant.SkipProjectWikiPath) var skipProjectWikiPaths = context.StringSlice(constant.SkipProjectWikiPath)
var autoSkipExistFolder = context.Bool(constant.AutoSkipExistFolder)
var allowFailure = context.Bool(constant.AllowFailure)
baseURL, err := url.Parse(baseUrl) baseURL, err := url.Parse(baseUrl)
if err != nil { if err != nil {
@ -54,7 +56,7 @@ func ExportAll() *cli.Command {
skipProjectWikiPaths[index] = skipProjectWikiPath skipProjectWikiPaths[index] = skipProjectWikiPath
} }
projectList, err := projects.ListProjects(&owned, token, baseUrl, 1, 100) projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil { if err != nil {
return err return err
} }
@ -62,12 +64,16 @@ func ExportAll() *cli.Command {
for index, project := range projectList { for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL) log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = Repository(exportFolder, host, username, token, project, skipProjectPaths) err = Repository(allowFailure, autoSkipExistFolder, exportFolder, host, token, project, skipProjectPaths)
if err != nil { if err != nil {
return err return err
} }
}
err = Wiki(exportFolder, host, username, token, project, skipProjectWikiPaths) for index, project := range projectList {
log.Printf("Project wiki Index: %d, WebURL: %s", index, project.WebURL)
err = Wiki(allowFailure, autoSkipExistFolder, exportFolder, host, token, project, skipProjectWikiPaths)
if err != nil { if err != nil {
return err return err
} }
@ -80,7 +86,7 @@ func ExportAll() *cli.Command {
} }
} }
func Repository(exportFolder string, host string, username string, token string, project *gitlab.Project, skipProjectPaths []string) error { func Repository(allowFailure bool, autoSkipExistFolder bool, exportFolder string, host string, token string, project *gitlab.Project, skipProjectPaths []string) error {
c := contains(skipProjectPaths, project.PathWithNamespace) c := contains(skipProjectPaths, project.PathWithNamespace)
if c { if c {
@ -89,6 +95,16 @@ func Repository(exportFolder string, host string, username string, token string,
} }
gitPath := filepath.Join(exportFolder, "repository", host, project.PathWithNamespace) gitPath := filepath.Join(exportFolder, "repository", host, project.PathWithNamespace)
if autoSkipExistFolder {
_, err := os.Stat(gitPath)
if os.IsNotExist(err) {
} else {
log.Printf("已启用自动跳过已存在的文件夹:%s\n", gitPath)
return nil
}
}
err := os.MkdirAll(gitPath, os.ModePerm) err := os.MkdirAll(gitPath, os.ModePerm)
if err != nil { if err != nil {
return err return err
@ -100,7 +116,7 @@ func Repository(exportFolder string, host string, username string, token string,
return err return err
} }
userinfo := url.UserPassword(username, token) userinfo := url.UserPassword("", token)
repoUrl.User = userinfo repoUrl.User = userinfo
cmd := exec.Command("git", "clone", repoUrl.String(), gitPath) cmd := exec.Command("git", "clone", repoUrl.String(), gitPath)
@ -109,18 +125,24 @@ func Repository(exportFolder string, host string, username string, token string,
err = cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }
err = GitRemoteSetUrl(gitPath, HTTPURLToRepo) err = GitRemoteSetUrl(gitPath, HTTPURLToRepo)
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }
return nil return nil
} }
func Wiki(exportFolder string, host string, username string, token string, project *gitlab.Project, skipProjectWikiPaths []string) error { func Wiki(allowFailure bool, autoSkipExistFolder bool, exportFolder string, host string, token string, project *gitlab.Project, skipProjectWikiPaths []string) error {
c := contains(skipProjectWikiPaths, project.PathWithNamespace) c := contains(skipProjectWikiPaths, project.PathWithNamespace)
if c { if c {
@ -129,6 +151,16 @@ func Wiki(exportFolder string, host string, username string, token string, proje
} }
wikiPath := filepath.Join(exportFolder, "wiki", host, project.PathWithNamespace+".wiki") wikiPath := filepath.Join(exportFolder, "wiki", host, project.PathWithNamespace+".wiki")
if autoSkipExistFolder {
_, err := os.Stat(wikiPath)
if os.IsNotExist(err) {
} else {
log.Printf("已启用自动跳过已存在的文件夹:%s\n", wikiPath)
return nil
}
}
err := os.MkdirAll(wikiPath, os.ModePerm) err := os.MkdirAll(wikiPath, os.ModePerm)
if err != nil { if err != nil {
return err return err
@ -146,7 +178,7 @@ func Wiki(exportFolder string, host string, username string, token string, proje
return err return err
} }
userinfo := url.UserPassword(username, token) userinfo := url.UserPassword("", token)
repoUrl.User = userinfo repoUrl.User = userinfo
cmd := exec.Command("git", "clone", repoUrl.String(), wikiPath) cmd := exec.Command("git", "clone", repoUrl.String(), wikiPath)
@ -155,11 +187,17 @@ func Wiki(exportFolder string, host string, username string, token string, proje
err = cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }
err = GitRemoteSetUrl(wikiPath, HTTPURLToRepo) err = GitRemoteSetUrl(wikiPath, HTTPURLToRepo)
if err != nil { if err != nil {
if allowFailure {
return nil
}
return err return err
} }

View File

@ -11,7 +11,8 @@ func Delete() *cli.Command {
Name: "mix-delete", Name: "mix-delete",
Aliases: []string{"mix-rm"}, Aliases: []string{"mix-rm"},
Usage: "删除(混合命令,多接口命令)", Usage: "删除(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(false), flag.IIdRange(false)), Flags: append(flag.Common(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(false),
flag.IIdRange(false), flag.AllowFailure()),
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
DeleteArtifacts(), DeleteArtifacts(),
DeleteAllArtifacts(), DeleteAllArtifacts(),

20
mix/mix_environments.go Normal file
View File

@ -0,0 +1,20 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
func Environments() *cli.Command {
return &cli.Command{
Name: "mix-create-environments",
Aliases: []string{"mix-create-environment", "mix-create-env"},
Usage: "创建新环境(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Owned(false),
flag.EnvName(false), flag.EnvExternalUrl(), flag.EnvTier(), flag.AllowFailure(),
flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
EnvironmentsCreateAll(),
},
}
}

View File

@ -10,8 +10,9 @@ func Export() *cli.Command {
return &cli.Command{ return &cli.Command{
Name: "mix-export", Name: "mix-export",
Usage: "导出(混合命令,多接口命令)", Usage: "导出(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Username(false), flag.Owned(false), Flags: append(flag.Common(), flag.Owned(false),
flag.ExportFolder(false), flag.SkipProjectPath(), flag.SkipProjectWikiPath()), flag.ExportFolder(false), flag.SkipProjectPath(), flag.SkipProjectWikiPath(),
flag.AutoSkipExistFolder(), flag.AllowFailure()),
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
ExportAll(), ExportAll(),
}, },

View File

@ -0,0 +1,21 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// CreateProjectLevelVariables 创建项目级别 CI/CD 变量
func CreateProjectLevelVariables() *cli.Command {
return &cli.Command{
Name: "mix-create-project-level-variables",
Usage: "创建项目级别 CI/CD 变量(混合命令,多接口命令)",
Flags: append(flag.Common(),
flag.VariableKey(false), flag.VariableValue(false), flag.VariableType(), flag.VariableProtected(),
flag.VariableMasked(), flag.VariableRaw(), flag.VariableEnvironmentScope(),
flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
ProjectLevelVariablesCreateAll(),
},
}
}

View File

@ -0,0 +1,21 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// ProtectBranches 保护仓库分支
func ProtectBranches() *cli.Command {
return &cli.Command{
Name: "mix-protect-branches",
Usage: "保护仓库分支(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Owned(false),
flag.BranchName(false), flag.PushAccessLevel(), flag.MergeAccessLevel(),
flag.UnprotectAccessLevel(), flag.AllowForcePush(), flag.CodeOwnerApprovalRequired(),
flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
ProtectBranchesAll(),
},
}
}

19
mix/mix_transfer.go Normal file
View File

@ -0,0 +1,19 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// Transfer 转移
func Transfer() *cli.Command {
return &cli.Command{
Name: "mix-transfer",
Usage: "转移(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Owned(false),
flag.NamespaceSource(false), flag.NamespaceTargetFlag(false), flag.SkipProjectPath()),
Subcommands: []*cli.Command{
TransferAll(),
},
}
}

18
mix/mix_unarchive.go Normal file
View File

@ -0,0 +1,18 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// Unarchive 取消归档
func Unarchive() *cli.Command {
return &cli.Command{
Name: "mix-unarchive",
Usage: "取消归档(混合命令,多接口命令)",
Flags: append(flag.Common(), flag.Owned(false)),
Subcommands: []*cli.Command{
UnarchiveAll(),
},
}
}

View File

@ -0,0 +1,57 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/project_level_variables"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"log"
)
// ProjectLevelVariablesCreateAll 所有项目创建新变量
func ProjectLevelVariablesCreateAll() *cli.Command {
return &cli.Command{
Name: "all",
Aliases: []string{"a"},
Usage: "所有项目创建新变量",
Flags: append(flag.CommonTokenRequired(), flag.Owned(true),
flag.VariableKey(true), flag.VariableValue(true), flag.VariableType(), flag.VariableProtected(),
flag.VariableMasked(), flag.VariableRaw(), flag.VariableEnvironmentScope(), flag.AllowFailure(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
var key = context.String(constant.VariableKey)
var value = context.String(constant.VariableValue)
var variableType = context.String(constant.VariableType)
var protected = context.Bool(constant.VariableProtected)
var masked = context.Bool(constant.VariableMasked)
var raw = context.Bool(constant.VariableRaw)
var environmentScope = context.String(constant.VariableEnvironmentScope)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
var allowFailure = context.Bool(constant.AllowFailure)
projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = project_level_variables.CreateVariable(baseUrl, token, project.ID, key, value, protected, masked, raw, environmentScope, variableType,
printJson, printTime, allowFailure)
if err != nil {
return err
}
}
return nil
},
}
}

View File

@ -0,0 +1,58 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"github.com/xuxiaowei-com-cn/gitlab-go/protected_branches"
"log"
)
// ProtectBranchesAll 保护所有仓库分支
func ProtectBranchesAll() *cli.Command {
return &cli.Command{
Name: "all",
Aliases: []string{"a"},
Usage: "保护所有仓库分支",
Flags: append(flag.CommonTokenRequired(), flag.Owned(true),
flag.BranchName(true), flag.PushAccessLevel(), flag.MergeAccessLevel(),
flag.UnprotectAccessLevel(), flag.AllowForcePush(), flag.CodeOwnerApprovalRequired(),
flag.AllowFailure(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
var name = context.String(constant.BranchName)
var pushAccessLevel = context.Int(constant.PushAccessLevel)
var mergeAccessLevel = context.Int(constant.MergeAccessLevel)
var unprotectAccessLevel = context.Int(constant.UnprotectAccessLevel)
var allowForcePush = context.Bool(constant.AllowForcePush)
var codeOwnerApprovalRequired = context.Bool(constant.CodeOwnerApprovalRequired)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
var allowFailure = context.Bool(constant.AllowFailure)
projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = protected_branches.ProtectRepositoryBranches(baseUrl, token, project.ID, name,
pushAccessLevel, mergeAccessLevel, unprotectAccessLevel, allowForcePush, codeOwnerApprovalRequired,
printJson, printTime, allowFailure)
if err != nil {
return err
}
}
return nil
},
}
}

73
mix/transfer_all.go Normal file
View File

@ -0,0 +1,73 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"log"
"strings"
)
func TransferAll() *cli.Command {
return &cli.Command{
Name: "all",
Aliases: []string{"a"},
Usage: "将一个命令空间的项目转移到新的命名空间",
Flags: append(flag.CommonTokenRequired(), flag.Owned(true), flag.NamespaceSource(true),
flag.NamespaceTargetFlag(true), flag.SkipProjectPath()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
var namespaceSource = context.String(constant.NamespaceSource)
var namespaceTarget = context.String(constant.NamespaceTarget)
var skipProjectPaths = context.StringSlice(constant.SkipProjectPath)
for index, skipProjectPath := range skipProjectPaths {
skipProjectPath = strings.TrimPrefix(skipProjectPath, "/")
skipProjectPath = strings.TrimSuffix(skipProjectPath, "/")
skipProjectPaths[index] = skipProjectPath
}
projectList, err := projects.ListNamespaceProjects(owned, token, baseUrl, 1, 100, namespaceSource, skipProjectPaths)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = TransferProject(baseUrl, token, project.PathWithNamespace, namespaceTarget)
if err != nil {
return err
}
}
return nil
},
}
}
// TransferProject 将项目转移到新的命名空间 https://docs.gitlab.cn/jh/api/projects.html#%E5%B0%86%E9%A1%B9%E7%9B%AE%E8%BD%AC%E7%A7%BB%E5%88%B0%E6%96%B0%E7%9A%84%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4
func TransferProject(baseUrl string, token string, id string, namespace string) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.TransferProjectOptions{
Namespace: namespace,
}
project, response, err := gitClient.Projects.TransferProject(id, opt)
if err != nil {
return err
}
log.Printf("项目: %s 转移到: %s 结果: %s", id, project.WebURL, response.Status)
return nil
}

40
mix/unarchive_all.go Normal file
View File

@ -0,0 +1,40 @@
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"log"
)
// UnarchiveAll 取消归档所有项目
func UnarchiveAll() *cli.Command {
return &cli.Command{
Name: "all",
Usage: "取消归档所有项目(混合命令,多接口命令)",
Flags: append(flag.CommonTokenRequired(), flag.Owned(true)),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
projectList, err := projects.ListProjects(owned, token, baseUrl, 1, 100)
if err != nil {
return err
}
for index, project := range projectList {
log.Printf("Project Index: %d, WebURL: %s", index, project.WebURL)
err = projects.UnarchiveProject(token, baseUrl, project.PathWithNamespace)
if err != nil {
return err
}
}
return nil
},
}
}

View File

@ -0,0 +1,123 @@
package project_level_variables
import (
"encoding/json"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// Create 创建变量 https://docs.gitlab.cn/jh/api/project_level_variables.html#%E5%88%9B%E5%BB%BA%E5%8F%98%E9%87%8F
func Create() *cli.Command {
return &cli.Command{
Name: "create",
Usage: "创建变量",
Flags: append(flag.CommonTokenRequired(), flag.Id(true),
flag.VariableKey(true), flag.VariableValue(true), flag.VariableType(), flag.VariableProtected(),
flag.VariableMasked(), flag.VariableRaw(), flag.VariableEnvironmentScope(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var key = context.String(constant.VariableKey)
var value = context.String(constant.VariableValue)
var variableType = context.String(constant.VariableType)
var protected = context.Bool(constant.VariableProtected)
var masked = context.Bool(constant.VariableMasked)
var raw = context.Bool(constant.VariableRaw)
var environmentScope = context.String(constant.VariableEnvironmentScope)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
return CreateVariable(baseUrl, token, id, key, value, protected, masked, raw, environmentScope, variableType,
printJson, printTime, false)
},
}
}
func CreateVariable(baseUrl string, token string, id interface{}, key string, value string, protected bool, masked bool, raw bool, environmentScope string, variableType string,
printJson bool, printTime bool, allowFailure bool) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.CreateProjectVariableOptions{
Key: &key,
Value: &value,
Protected: &protected,
Masked: &masked,
Raw: &raw,
EnvironmentScope: &environmentScope,
}
if variableType == "env_var" {
opt.VariableType = gitlab.Ptr(gitlab.EnvVariableType)
} else if variableType == "file" {
opt.VariableType = gitlab.Ptr(gitlab.FileVariableType)
}
projectVariable, response, err := gitClient.ProjectVariables.CreateVariable(id, opt)
if err != nil {
if allowFailure {
return nil
}
return err
}
log.Printf("Response StatusCode: %d\n", response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
jsonData, err := json.Marshal(projectVariable)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
} else {
jsonData, err := json.Marshal(projectVariable)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
} else {
if printTime {
log.Printf("Key: %s\n", projectVariable.Key)
log.Printf("Value: %s\n", projectVariable.Value)
log.Printf("VariableType: %s\n", projectVariable.VariableType)
log.Printf("Protected: %t\n", projectVariable.Protected)
log.Printf("Masked: %t\n", projectVariable.Masked)
log.Printf("Raw: %t\n", projectVariable.Raw)
log.Printf("EnvironmentScope: %s\n", projectVariable.EnvironmentScope)
fmt.Println("")
} else {
fmt.Printf("Key: %s\n", projectVariable.Key)
fmt.Printf("Value: %s\n", projectVariable.Value)
fmt.Printf("VariableType: %s\n", projectVariable.VariableType)
fmt.Printf("Protected: %t\n", projectVariable.Protected)
fmt.Printf("Masked: %t\n", projectVariable.Masked)
fmt.Printf("Raw: %t\n", projectVariable.Raw)
fmt.Printf("EnvironmentScope: %s\n", projectVariable.EnvironmentScope)
fmt.Println("")
}
}
return nil
}

View File

@ -0,0 +1,98 @@
package project_level_variables
import (
"encoding/json"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// List 列出项目变量 https://docs.gitlab.cn/jh/api/project_level_variables.html#%E5%88%97%E5%87%BA%E9%A1%B9%E7%9B%AE%E5%8F%98%E9%87%8F
func List() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "列出项目变量",
Flags: append(flag.CommonTokenRequired(), flag.Id(true), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.ListProjectVariablesOptions{
Page: page,
PerPage: perPage,
}
projectVariables, response, err := gitClient.ProjectVariables.ListVariables(id, opt)
if err != nil {
return err
}
log.Printf("Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
for _, projectVariable := range projectVariables {
jsonData, err := json.Marshal(projectVariable)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
}
} else {
for _, projectVariable := range projectVariables {
jsonData, err := json.Marshal(projectVariable)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
}
} else {
if printTime {
for _, projectVariable := range projectVariables {
log.Printf("Key: %s\n", projectVariable.Key)
log.Printf("Value: %s\n", projectVariable.Value)
log.Printf("VariableType: %s\n", projectVariable.VariableType)
log.Printf("Protected: %t\n", projectVariable.Protected)
log.Printf("Masked: %t\n", projectVariable.Masked)
log.Printf("Raw: %t\n", projectVariable.Raw)
log.Printf("EnvironmentScope: %s\n", projectVariable.EnvironmentScope)
fmt.Println("")
}
} else {
for _, projectVariable := range projectVariables {
fmt.Printf("Key: %s\n", projectVariable.Key)
fmt.Printf("Value: %s\n", projectVariable.Value)
fmt.Printf("VariableType: %s\n", projectVariable.VariableType)
fmt.Printf("Protected: %t\n", projectVariable.Protected)
fmt.Printf("Masked: %t\n", projectVariable.Masked)
fmt.Printf("Raw: %t\n", projectVariable.Raw)
fmt.Printf("EnvironmentScope: %s\n", projectVariable.EnvironmentScope)
fmt.Println("")
}
}
}
return nil
},
}
}

View File

@ -0,0 +1,23 @@
package project_level_variables
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// ProjectLevelVariables 项目级别 CI/CD 变量 API https://docs.gitlab.cn/jh/api/project_level_variables.html
func ProjectLevelVariables() *cli.Command {
return &cli.Command{
Name: "project-level-variables",
Aliases: []string{"project-level-variable", "plv"},
Usage: "项目级别 CI/CD 变量 API中文文档https://docs.gitlab.cn/jh/api/project_level_variables.html",
Flags: append(flag.Common(), flag.Id(false),
flag.VariableKey(false), flag.VariableValue(false), flag.VariableType(), flag.VariableProtected(),
flag.VariableMasked(), flag.VariableRaw(), flag.VariableEnvironmentScope(),
flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
List(),
Create(),
},
}
}

View File

@ -15,12 +15,13 @@ func List() *cli.Command {
return &cli.Command{ return &cli.Command{
Name: "list", Name: "list",
Usage: "列出所有项目", Usage: "列出所有项目",
Flags: append(flag.Common(), flag.Sort(), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime(), Flags: append(flag.Common(), flag.Owned(true), flag.Sort(), flag.Page(), flag.PerPage(),
flag.Search(), flag.SearchNamespaces(), flag.PrintJson(), flag.PrintTime(), flag.Search(), flag.SearchNamespaces(),
flag.OrderBy(OrderByUsage)), flag.OrderBy(OrderByUsage)),
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl) var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token) var token = context.String(constant.Token)
var owned = context.Bool(constant.Owned)
var sort = context.String(constant.Sort) var sort = context.String(constant.Sort)
var page = context.Int(constant.Page) var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage) var perPage = context.Int(constant.PerPage)
@ -43,6 +44,7 @@ func List() *cli.Command {
Sort: &sort, Sort: &sort,
Search: &search, Search: &search,
SearchNamespaces: &searchNamespaces, SearchNamespaces: &searchNamespaces,
Owned: &owned,
OrderBy: &orderBy, OrderBy: &orderBy,
} }
projects, response, err := gitClient.Projects.ListProjects(opt) projects, response, err := gitClient.Projects.ListProjects(opt)

View File

@ -5,6 +5,7 @@ import (
"github.com/xanzy/go-gitlab" "github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/flag" "github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log" "log"
"strings"
) )
const ( const (
@ -17,8 +18,8 @@ func Projects() *cli.Command {
Name: "project", Name: "project",
Aliases: []string{"projects", "p"}, Aliases: []string{"projects", "p"},
Usage: "项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html", Usage: "项目 API中文文档https://docs.gitlab.cn/jh/api/projects.html",
Flags: append(flag.Common(), flag.Sort(), flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime(), Flags: append(flag.Common(), flag.Owned(false), flag.Sort(), flag.Page(), flag.PerPage(),
flag.Search(), flag.SearchNamespaces(), flag.PrintJson(), flag.PrintTime(), flag.Search(), flag.SearchNamespaces(),
flag.OrderBy(OrderByUsage)), flag.OrderBy(OrderByUsage)),
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
List(), List(),
@ -26,8 +27,8 @@ func Projects() *cli.Command {
} }
} }
// ListProjects 列出群组 https://docs.gitlab.cn/jh/api/projects.html#%E5%88%97%E5%87%BA%E6%89%80%E6%9C%89%E9%A1%B9%E7%9B%AE // ListProjects 列出所有项目 https://docs.gitlab.cn/jh/api/projects.html#%E5%88%97%E5%87%BA%E6%89%80%E6%9C%89%E9%A1%B9%E7%9B%AE
func ListProjects(owned *bool, token string, baseUrl string, page int, perPage int) ([]*gitlab.Project, error) { func ListProjects(owned bool, token string, baseUrl string, page int, perPage int) ([]*gitlab.Project, error) {
var results []*gitlab.Project var results []*gitlab.Project
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl)) gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
@ -40,7 +41,7 @@ func ListProjects(owned *bool, token string, baseUrl string, page int, perPage i
Page: page, Page: page,
PerPage: perPage, PerPage: perPage,
}, },
Owned: owned, Owned: &owned,
} }
projects, response, err := gitClient.Projects.ListProjects(opt) projects, response, err := gitClient.Projects.ListProjects(opt)
@ -64,6 +65,70 @@ func ListProjects(owned *bool, token string, baseUrl string, page int, perPage i
return results, err return results, err
} }
// ListNamespaceProjects 列出命名空间所有项目
func ListNamespaceProjects(owned bool, token string, baseUrl string, page int, perPage int, namespace string, skipProjectPaths []string) ([]*gitlab.Project, error) {
var results []*gitlab.Project
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return nil, err
}
opt := &gitlab.ListProjectsOptions{
ListOptions: gitlab.ListOptions{
Page: page,
PerPage: perPage,
},
Owned: &owned,
}
projects, response, err := gitClient.Projects.ListProjects(opt)
if err != nil {
return nil, err
}
log.Printf("ListProjects Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
results = Namespace(results, projects, namespace, skipProjectPaths)
if len(projects) != 0 {
projects, err = ListNamespaceProjects(owned, token, baseUrl, page+1, perPage, namespace, skipProjectPaths)
if err != nil {
return nil, err
}
results = Namespace(results, projects, namespace, skipProjectPaths)
}
return results, err
}
func Namespace(results []*gitlab.Project, projects []*gitlab.Project, namespace string, skipProjectPaths []string) []*gitlab.Project {
if namespace == "" {
results = append(results, projects...)
} else {
for _, project := range projects {
var c bool
for _, skipProjectPath := range skipProjectPaths {
if project.PathWithNamespace == skipProjectPath {
c = true
break
}
}
if c {
continue
}
if strings.HasPrefix(project.PathWithNamespace, namespace+"/") {
// 将 project 添加到 results 中
results = append(results, project)
}
}
}
return results
}
func ArchiveProject(token string, baseUrl string, pathWithNamespace string) error { func ArchiveProject(token string, baseUrl string, pathWithNamespace string) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl)) gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
@ -80,3 +145,20 @@ func ArchiveProject(token string, baseUrl string, pathWithNamespace string) erro
return nil return nil
} }
func UnarchiveProject(token string, baseUrl string, pathWithNamespace string) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
_, response, err := gitClient.Projects.UnarchiveProject(pathWithNamespace)
if err != nil {
return err
}
log.Printf("ArchiveProject PathWithNamespace: %s, Response StatusCode: %d\n", pathWithNamespace, response.Response.StatusCode)
return nil
}

151
protected_branches/list.go Normal file
View File

@ -0,0 +1,151 @@
package protected_branches
import (
"encoding/json"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// List 列出受保护的分支 https://docs.gitlab.cn/jh/api/protected_branches.html#%E5%88%97%E5%87%BA%E5%8F%97%E4%BF%9D%E6%8A%A4%E7%9A%84%E5%88%86%E6%94%AF
func List() *cli.Command {
return &cli.Command{
Name: "list",
Usage: "列出受保护的分支",
Flags: append(flag.CommonTokenRequired(), flag.Id(true), flag.ProtectedBranchesSearch(),
flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var search = context.String(constant.Search)
var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
opt := &gitlab.ListProtectedBranchesOptions{
Search: &search,
ListOptions: gitlab.ListOptions{
Page: page,
PerPage: perPage,
},
}
protectedBranchs, response, err := gitClient.ProtectedBranches.ListProtectedBranches(id, opt)
if err != nil {
return err
}
log.Printf("Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
for _, protectedBranch := range protectedBranchs {
jsonData, err := json.Marshal(protectedBranch)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
}
} else {
for _, protectedBranch := range protectedBranchs {
jsonData, err := json.Marshal(protectedBranch)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
}
} else {
if printTime {
for _, protectedBranch := range protectedBranchs {
log.Printf("ID: %d\n", protectedBranch.ID)
log.Printf("Name: %s\n", protectedBranch.Name)
log.Printf("AllowForcePush: %t\n", protectedBranch.AllowForcePush)
log.Printf("CodeOwnerApprovalRequired: %t\n", protectedBranch.CodeOwnerApprovalRequired)
log.Printf("PushAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.PushAccessLevels {
log.Printf("PushAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("PushAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("PushAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("PushAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("PushAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
log.Printf("MergeAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.MergeAccessLevels {
log.Printf("MergeAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("MergeAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("MergeAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("MergeAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("MergeAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
log.Printf("UnprotectAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.UnprotectAccessLevels {
log.Printf("UnprotectAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("UnprotectAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("UnprotectAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("UnprotectAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("UnprotectAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Println("")
}
} else {
for _, protectedBranch := range protectedBranchs {
fmt.Printf("ID: %d\n", protectedBranch.ID)
fmt.Printf("Name: %s\n", protectedBranch.Name)
fmt.Printf("AllowForcePush: %t\n", protectedBranch.AllowForcePush)
fmt.Printf("CodeOwnerApprovalRequired: %t\n", protectedBranch.CodeOwnerApprovalRequired)
fmt.Printf("PushAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.PushAccessLevels {
fmt.Printf("PushAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("PushAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("PushAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("PushAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("PushAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Printf("MergeAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.MergeAccessLevels {
fmt.Printf("MergeAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("MergeAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("MergeAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("MergeAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("MergeAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Printf("UnprotectAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.UnprotectAccessLevels {
fmt.Printf("UnprotectAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("UnprotectAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("UnprotectAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("UnprotectAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("UnprotectAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Println("")
}
}
}
return nil
},
}
}

View File

@ -0,0 +1,195 @@
package protected_branches
import (
"encoding/json"
"errors"
"fmt"
"github.com/urfave/cli/v2"
"github.com/xanzy/go-gitlab"
"github.com/xuxiaowei-com-cn/gitlab-go/constant"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
"log"
)
// Protect 保护仓库分支 https://docs.gitlab.cn/jh/api/protected_branches.html#%E4%BF%9D%E6%8A%A4%E4%BB%93%E5%BA%93%E5%88%86%E6%94%AF
func Protect() *cli.Command {
return &cli.Command{
Name: "protect",
Usage: "保护仓库分支",
Flags: append(flag.CommonTokenRequired(), flag.Id(true),
flag.BranchName(true), flag.PushAccessLevel(), flag.MergeAccessLevel(),
flag.UnprotectAccessLevel(), flag.AllowForcePush(), flag.CodeOwnerApprovalRequired(),
flag.PrintJson(), flag.PrintTime()),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var id = context.String(constant.Id)
var name = context.String(constant.BranchName)
var pushAccessLevel = context.Int(constant.PushAccessLevel)
var mergeAccessLevel = context.Int(constant.MergeAccessLevel)
var unprotectAccessLevel = context.Int(constant.UnprotectAccessLevel)
var allowForcePush = context.Bool(constant.AllowForcePush)
var codeOwnerApprovalRequired = context.Bool(constant.CodeOwnerApprovalRequired)
var printJson = context.Bool(constant.PrintJson)
var printTime = context.Bool(constant.PrintTime)
return ProtectRepositoryBranches(baseUrl, token, id, name,
pushAccessLevel, mergeAccessLevel, unprotectAccessLevel, allowForcePush, codeOwnerApprovalRequired,
printJson, printTime, false)
},
}
}
func ProtectRepositoryBranches(baseUrl string, token string, id interface{}, name string,
pushAccessLevel int, mergeAccessLevel int, unprotectAccessLevel int, allowForcePush bool, codeOwnerApprovalRequired bool,
printJson bool, printTime bool, allowFailure bool) error {
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
var pushAccessLevelValue gitlab.AccessLevelValue
switch pushAccessLevel {
case 0, 5, 10, 20, 30, 40, 50, 60:
pushAccessLevelValue = gitlab.AccessLevelValue(pushAccessLevel)
default:
return errors.New(fmt.Sprintf("pushAccessLevel%d 不合法", pushAccessLevel))
}
var mergeAccessLevelValue gitlab.AccessLevelValue
switch mergeAccessLevel {
case 0, 5, 10, 20, 30, 40, 50, 60:
mergeAccessLevelValue = gitlab.AccessLevelValue(mergeAccessLevel)
default:
return errors.New(fmt.Sprintf("mergeAccessLevel%d 不合法", mergeAccessLevel))
}
var unprotectAccessLevelValue gitlab.AccessLevelValue
switch unprotectAccessLevel {
case 0, 5, 10, 20, 30, 40, 50, 60:
unprotectAccessLevelValue = gitlab.AccessLevelValue(unprotectAccessLevel)
default:
return errors.New(fmt.Sprintf("unprotectAccessLevel%d 不合法", unprotectAccessLevel))
}
opt := &gitlab.ProtectRepositoryBranchesOptions{
Name: &name,
PushAccessLevel: &pushAccessLevelValue,
MergeAccessLevel: &mergeAccessLevelValue,
UnprotectAccessLevel: &unprotectAccessLevelValue,
AllowForcePush: &allowForcePush,
//AllowedToPush: &allowedToPush,
//AllowedToMerge: &allowedToMerge,
//AllowedToUnprotect: &allowedToUnprotect,
CodeOwnerApprovalRequired: &codeOwnerApprovalRequired,
}
protectedBranch, response, err := gitClient.ProtectedBranches.ProtectRepositoryBranches(id, opt)
if err != nil {
if allowFailure {
return nil
}
return err
}
log.Printf("Response StatusCode: %d\n", response.Response.StatusCode)
fmt.Println("")
if printJson {
if printTime {
jsonData, err := json.Marshal(protectedBranch)
if err != nil {
panic(err)
}
log.Printf("\n%s\n", string(jsonData))
fmt.Println("")
} else {
jsonData, err := json.Marshal(protectedBranch)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", string(jsonData))
fmt.Println("")
}
} else {
if printTime {
log.Printf("ID: %d\n", protectedBranch.ID)
log.Printf("Name: %s\n", protectedBranch.Name)
log.Printf("AllowForcePush: %t\n", protectedBranch.AllowForcePush)
log.Printf("CodeOwnerApprovalRequired: %t\n", protectedBranch.CodeOwnerApprovalRequired)
log.Printf("PushAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.PushAccessLevels {
log.Printf("PushAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("PushAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("PushAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("PushAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("PushAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
log.Printf("MergeAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.MergeAccessLevels {
log.Printf("MergeAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("MergeAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("MergeAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("MergeAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("MergeAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
log.Printf("UnprotectAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.UnprotectAccessLevels {
log.Printf("UnprotectAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
log.Printf("UnprotectAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
log.Printf("UnprotectAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
log.Printf("UnprotectAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
log.Printf("UnprotectAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Println("")
} else {
fmt.Printf("ID: %d\n", protectedBranch.ID)
fmt.Printf("Name: %s\n", protectedBranch.Name)
fmt.Printf("AllowForcePush: %t\n", protectedBranch.AllowForcePush)
fmt.Printf("CodeOwnerApprovalRequired: %t\n", protectedBranch.CodeOwnerApprovalRequired)
fmt.Printf("PushAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.PushAccessLevels {
fmt.Printf("PushAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("PushAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("PushAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("PushAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("PushAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Printf("MergeAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.MergeAccessLevels {
fmt.Printf("MergeAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("MergeAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("MergeAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("MergeAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("MergeAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Printf("UnprotectAccessLevels: \n")
for index, branchAccessDescription := range protectedBranch.UnprotectAccessLevels {
fmt.Printf("UnprotectAccessLevels[%d] ID: %d\n", index, branchAccessDescription.ID)
fmt.Printf("UnprotectAccessLevels[%d] AccessLevel: %d\n", index, branchAccessDescription.AccessLevel)
fmt.Printf("UnprotectAccessLevels[%d] AccessLevelDescription: %s\n", index, branchAccessDescription.AccessLevelDescription)
fmt.Printf("UnprotectAccessLevels[%d] UserID: %d\n", index, branchAccessDescription.UserID)
fmt.Printf("UnprotectAccessLevels[%d] GroupID: %d\n", index, branchAccessDescription.GroupID)
}
fmt.Println("")
}
}
return nil
}

View File

@ -0,0 +1,23 @@
package protected_branches
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// ProtectedBranches 受保护的分支 API https://docs.gitlab.cn/jh/api/protected_branches.html
func ProtectedBranches() *cli.Command {
return &cli.Command{
Name: "protected-branches",
Aliases: []string{"pb"},
Usage: "受保护的分支 API中文文档https://docs.gitlab.cn/jh/api/protected_branches.html",
Flags: append(flag.Common(), flag.Id(false), flag.ProtectedBranchesSearch(),
flag.BranchName(false), flag.PushAccessLevel(), flag.MergeAccessLevel(),
flag.UnprotectAccessLevel(), flag.AllowForcePush(), flag.CodeOwnerApprovalRequired(),
flag.Page(), flag.PerPage(), flag.PrintJson(), flag.PrintTime()),
Subcommands: []*cli.Command{
List(),
Protect(),
},
}
}

View File

@ -191,3 +191,43 @@ sync-github:
retry: 2 retry: 2
# 允许失败 # 允许失败
allow_failure: true allow_failure: true
sync-framagit:
stage: sync
variables:
GIT_DEPTH: 0 # 取消浅层克隆
image: bitnami/git:2.40.1
script:
- git config --global user.email $GITLAB_USER_EMAIL
- git config --global user.name $GITLAB_USER_NAME
- git config --global user.email
- git config --global user.name
- git remote add framagit https://xuxiaowei:$FRAMAGIT_PRIVATE_TOKEN@framagit.org/$CI_PROJECT_PATH.git
- echo 当前分支:$CI_COMMIT_BRANCH
- echo 当前标签:$CI_COMMIT_TAG
- if [ "$CI_COMMIT_BRANCH" ]; then
git checkout -b $CI_COMMIT_BRANCH;
git pull --progress -v --no-rebase framagit $CI_COMMIT_BRANCH || echo 远端不存在$CI_COMMIT_BRANCH分支;
git push -u framagit $CI_COMMIT_BRANCH;
fi
- if [ "$CI_COMMIT_TAG" ]; then
git push -u framagit $CI_COMMIT_TAG;
fi
rules:
# GitCode 实例不执行
- if: $CI_SERVER_HOST == 'gitcode.net'
# 不执行
when: never
# framagit.org 不同步到自己
- if: $CI_SERVER_HOST == 'framagit.org'
# 不执行
when: never
# 匹配以 dependabot 开头的分支
- if: $CI_SERVER_HOST == 'gitlab.helm.xuxiaowei.cn' && $CI_COMMIT_BRANCH =~ /^dependabot*/
# 不执行
when: never
# 非 PR 时触发
- if: $CI_SERVER_HOST == 'gitlab.helm.xuxiaowei.cn' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == null
retry: 2
# 允许失败
allow_failure: true