提交 75028990 编写于 作者: 徐晓伟's avatar 徐晓伟

删除(混合命令): 根据项目路径/ID、流水线IID范围删除产物(混合命令,立即删除)

上级 cef6c565
......@@ -167,6 +167,7 @@ COMMANDS:
job, jobs, j 作业 API,中文文档:https://docs.gitlab.cn/jh/api/jobs.html
pipeline, pipelines, pl 流水线 API,中文文档:https://docs.gitlab.cn/jh/api/pipelines.html
project, projects, p 项目 API,中文文档:https://docs.gitlab.cn/jh/api/projects.html
mix-delete, mix-rm 删除(混合命令)
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
......@@ -349,7 +350,7 @@ COPYRIGHT:
get 获取(下载)作业产物
download, dl 下载产物归档文件(未完成)
delete, rm 删除作业产物
delete-project, delete-projects, rm-p 删除项目产物
delete-project, delete-projects, rm-p 删除项目产物(计划删除,如需立即删除请使用混合命令)
help, h Shows a list of commands or help for one command
OPTIONS:
......@@ -444,6 +445,35 @@ COPYRIGHT:
--help, -h show help
```
- 删除(混合命令)
```shell
$ go run main.go mix-delete --help
NAME:
gitlab-go mix-delete - 删除(混合命令)
USAGE:
gitlab-go mix-delete command [command options] [arguments...]
COMMANDS:
artifacts, artifact 根据项目路径/ID、流水线IID范围删除产物(混合命令,立即删除)
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
--sort value 按照 asc 或者 desc 排序 (default: "desc")
--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)
--id value 项目 ID 或 URL 编码的路径
--iid-range value [ --iid-range value ] 流水线ID的范围,支持范围如下:
单数:1
多个数字(使用英文逗号隔开):1,2,3,7,8,15
支持范围:5-10,
支持范围方向选择:-10(小于等于10,即:从 0 到 10),214-(大于等于214,即:从 214 到 214 + 10000,数据范围不超过 10000)
--help, -h show help
```
### test
```shell
......
......@@ -5,6 +5,7 @@ const (
BaseUrl = "base-url"
BaseUrlDefault = "https://gitlab.com/api/v4"
Id = "id"
IIdRange = "iid-range"
Repository = "repository"
TagName = "tag-name"
JobId = "job-id"
......
......@@ -73,6 +73,18 @@ func Id(required bool) cli.Flag {
}
}
func IIdRange(required bool) cli.Flag {
return &cli.StringSliceFlag{
Name: constant.IIdRange,
Usage: "流水线ID的范围,支持范围如下:\n\t" +
"单数:1\n\t" +
"多个数字(使用英文逗号隔开):1,2,3,7,8,15\n\t" +
"支持范围:5-10,\n\t" +
fmt.Sprintf("支持范围方向选择:-10(小于等于10,即:从 0 到 10),214-(大于等于214,即:从 214 到 214 + %d,数据范围不超过 %d)", RangeMaxInterval, RangeMaxInterval),
Required: required,
}
}
func Repository(required bool) cli.Flag {
return &cli.StringFlag{
Name: constant.Repository,
......
......@@ -13,7 +13,7 @@ func DeleteProject() *cli.Command {
return &cli.Command{
Name: "delete-project",
Aliases: []string{"delete-projects", "rm-p"},
Usage: "删除项目产物",
Usage: "删除项目产物(计划删除,如需立即删除请使用混合命令)",
Flags: append(flag.Common(), flag.Id(true)),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
......
......@@ -10,6 +10,7 @@ import (
"github.com/xuxiaowei-com-cn/gitlab-go/issues"
"github.com/xuxiaowei-com-cn/gitlab-go/job_artifacts"
"github.com/xuxiaowei-com-cn/gitlab-go/jobs"
"github.com/xuxiaowei-com-cn/gitlab-go/mix"
"github.com/xuxiaowei-com-cn/gitlab-go/pipelines"
"github.com/xuxiaowei-com-cn/gitlab-go/projects"
"gopkg.in/yaml.v3"
......@@ -74,6 +75,7 @@ func main() {
jobs.Jobs(),
pipelines.Pipelines(),
projects.Projects(),
mix.Delete(),
},
}
......
package mix
import (
"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"
"github.com/xuxiaowei-com-cn/gitlab-go/pipelines"
"github.com/xuxiaowei-com-cn/gitlab-go/utils"
"log"
"sort"
)
// DeleteArtifacts 删除产物
func DeleteArtifacts() *cli.Command {
return &cli.Command{
Name: "artifacts",
Aliases: []string{"artifact"},
Usage: "根据项目路径/ID、流水线IID范围删除产物(混合命令,立即删除)",
Flags: append(flag.CommonTokenRequired(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(true), flag.IIdRange(true)),
Action: func(context *cli.Context) error {
var baseUrl = context.String(constant.BaseUrl)
var token = context.String(constant.Token)
var sortStr = context.String(constant.Sort)
var id = context.String(constant.Id)
var page = context.Int(constant.Page)
var perPage = context.Int(constant.PerPage)
var iidRanges = context.StringSlice(constant.IIdRange)
fmt.Println(iidRanges)
gitClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseUrl))
if err != nil {
return err
}
iids := utils.Unique(utils.RangeInt(iidRanges))
sort.Ints(iids)
fmt.Printf("%d\n", iids)
iidsLen := len(iids)
if iidsLen == 0 {
// 输入数字为空,结束程序
return nil
}
err = DeleteArtifactsRecursion(gitClient, id, page, perPage, sortStr, iids)
if err != nil {
return err
}
return nil
},
}
}
func DeleteArtifactsRecursion(gitClient *gitlab.Client, id interface{}, page int, perPage int, sort string, iids []int) error {
pipelineInfos, response, err := pipelines.ListProjectPipelines(gitClient, id, page, perPage, sort)
if err != nil {
return err
}
log.Printf("Page %d, PerPage: %d, Response StatusCode: %d\n", page, perPage, response.Response.StatusCode)
for _, pipelineInfo := range pipelineInfos {
fmt.Printf("%d\n", pipelineInfo.IID)
// 数字在上方已排序
// 最小值
iidsMin := iids[0]
// 最大值
iidsMax := iids[len(iids)-1]
if iidsMin == pipelineInfo.IID {
// 等于最小值,删除最小值
iids = iids[1:]
err = ExecuteDeleteArtifacts(gitClient, id, pipelineInfo.ID, 1, 100)
if err != nil {
return err
}
} else if pipelineInfo.IID == iidsMax {
// 等于最大值
iids = iids[:len(iids)-1]
err = ExecuteDeleteArtifacts(gitClient, id, pipelineInfo.ID, 1, 100)
if err != nil {
return err
}
} else if iidsMin < pipelineInfo.IID {
// 大于最小值
err = forExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID)
if err != nil {
return err
}
} else if pipelineInfo.IID < iidsMax {
// 小于最大值
err = forExecute(&iids, pipelineInfo.IID, gitClient, id, pipelineInfo.ID)
if err != nil {
return err
}
} else {
// 不在合法范围内
return nil
}
iidsLen := len(iids)
if iidsLen == 0 {
// 输入数字已处理完成,跳出循环
return nil
}
}
if len(pipelineInfos) > 0 {
err := DeleteArtifactsRecursion(gitClient, id, page+1, perPage, sort, iids)
if err != nil {
return err
}
}
return nil
}
func forExecute(iids *[]int, pipelineInfoIId int, gitClient *gitlab.Client, id interface{}, pipelineInfoId int) error {
for i := 0; i < len(*iids); i++ {
if (*iids)[i] == pipelineInfoIId {
fmt.Printf("数组中包含%d\n", pipelineInfoIId)
*iids = append((*iids)[:i], (*iids)[i+1:]...)
err := ExecuteDeleteArtifacts(gitClient, id, pipelineInfoId, 1, 100)
if err != nil {
return err
}
break
}
}
return nil
}
func ExecuteDeleteArtifacts(gitClient *gitlab.Client, id interface{}, pipelineInfoId int, page int, perPage int) error {
fmt.Printf("执行删除 %d \n", pipelineInfoId)
opt := &gitlab.ListJobsOptions{
ListOptions: gitlab.ListOptions{
Page: page,
PerPage: perPage,
},
}
jobs, response, err := gitClient.Jobs.ListPipelineJobs(id, pipelineInfoId, opt)
if err != nil {
return err
}
log.Printf("List Project %s Pipeline %d Jobs Response StatusCode: %d\n", id, pipelineInfoId, response.Response.StatusCode)
for _, job := range jobs {
response, err = gitClient.Jobs.DeleteArtifacts(id, job.ID)
if err != nil {
return err
}
log.Printf("Delete Project %s Job %d Response StatusCode: %d\n", id, job.ID, response.Response.StatusCode)
}
if len(jobs) == perPage {
err = ExecuteDeleteArtifacts(gitClient, id, pipelineInfoId, page+1, perPage)
if err != nil {
return err
}
}
return nil
}
package mix
import (
"github.com/urfave/cli/v2"
"github.com/xuxiaowei-com-cn/gitlab-go/flag"
)
// Delete 删除(混合命令)
func Delete() *cli.Command {
return &cli.Command{
Name: "mix-delete",
Aliases: []string{"mix-rm"},
Usage: "删除(混合命令)",
Flags: append(flag.Common(), flag.Sort(), flag.Page(), flag.PerPage(), flag.Id(false), flag.IIdRange(false)),
Subcommands: []*cli.Command{
DeleteArtifacts(),
},
}
}
......@@ -23,6 +23,24 @@ func ParseID(id interface{}) (string, error) {
}
}
func Unique(nums []int) []int {
// 使用 map 来存储不重复的元素
uniqueMap := make(map[int]bool)
// 遍历数组,将元素作为键存入 map
for _, num := range nums {
uniqueMap[num] = true
}
// 从 map 中提取不重复的元素到新的切片
var result []int
for num := range uniqueMap {
result = append(result, num)
}
return result
}
func RangeInt(stringSlices []string) []int {
allowMin := 1
var rangeInt []int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册