Gitlab CI_JOB_TOKEN
cliedeman opened this issue · 6 comments
Get go-semantic-release to work with a gitlab ci job token.
The token has much less permissions than a PAT but only has access to limited endpoints.
The motivation is ease of maintance. The ci tokens are automatically created and deleted after builds so are ideal for publishing
The variables we currently source from the project api are available during the build
https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
- CI_DEFAULT_BRANCH
- CI_PROJECT_VISIBILITY
Its not clear to me if the token can even access the commits
- https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html
- https://forum.gitlab.com/t/project-access-token-and-include/56008/3
Will investigate...
Created a little test project
package main
import (
"fmt"
"log"
"os"
"github.com/xanzy/go-gitlab"
)
func main() {
fmt.Printf("Default Branch: %s\n", os.Getenv("CI_DEFAULT_BRANCH"))
fmt.Printf("Project Visibility: %s\n", os.Getenv("CI_PROJECT_VISIBILITY"))
projectId := os.Getenv("CI_PROJECT_ID")
fmt.Printf("Project Id: %s\n", projectId)
token := os.Getenv("CI_JOB_TOKEN")
err := run(token, projectId)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
}
func run(token string, projectId string) error {
git, err := gitlab.NewJobClient(token)
if err != nil {
return err
}
project, _, err := git.Projects.GetProject(projectId, nil)
if err != nil {
log.Printf("Project Err: %s", err)
} else {
log.Printf("Project: %v", project)
}
commits, _, err := git.Commits.ListCommits(projectId, &gitlab.ListCommitsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 10,
},
})
if err != nil {
log.Printf("Commits Err: %s", err)
} else {
log.Printf("Commits: %v", commits)
}
tags, _, err := git.Tags.ListTags(projectId, &gitlab.ListTagsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 100,
},
})
if err != nil {
log.Printf("Tags Err: %s", err)
} else {
log.Printf("Tags: %v", tags)
}
_, _, err = git.Releases.CreateRelease(projectId, &gitlab.CreateReleaseOptions{
// TagName: &tag,
// Ref: &release.SHA,
Description: gitlab.String("Test"),
})
if err != nil {
log.Printf("Create Release Err: %s", err)
} else {
log.Printf("Create Release: %v", tags)
}
return nil
}
switching the client type is key
git, err := gitlab.NewJobClient(token)
Output
Default Branch: main
Project Visibility: private
Project Id: ******
2022/05/31 10:25:55 Project Err: GET https://gitlab.com/api/v4/projects/******: 404 {message: 404 Project Not Found}
2022/05/31 10:25:56 Commits Err: GET https://gitlab.com/api/v4/projects/******/repository/commits: 404 {message: 404 Project Not Found}
2022/05/31 10:25:56 Tags Err: GET https://gitlab.com/api/v4/projects/******/repository/tags: 404 {message: 404 Project Not Found}
2022/05/31 10:25:56 Create Release Err: POST https://gitlab.com/api/v4/projects/******/releases: 422 {message: Ref is not specified}
None of the calls work except for create release.
There is away to clone a repo:
git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/<namespace>/<project>
So with only being able to create a release and clone a repo we could actually implement this but it would be a reasonable amount of effort. Also this may not be viable for large repos
A clone shouldn't be needed, as long GIT_STRATEGY
is not overwritten by an user.
CI_JOB_TOKEN permission documentation for reference. https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html
I would like to see this feature too, this would be the killer feature which would make me migrate.
If I have time, I will give it a shot.
Hi @secustor
We can probably detect GIT_STRATEGY
and fail the build. The clone could be used in caes where the pipeline is not cloned by default but I dont need this use case either.
@christophwitzko Do you think this should be a new alpha provider or switches on the existing gitlab provider?
Thank you @secustor and @cliedeman for looking into this.
I think we can add this to the current provider, so it will work for everyone out of the box.
If GIT_STRATEGY is clone
we can use the existing git provider as a library to read the commits and releases (https://github.com/go-semantic-release/provider-git/blob/master/pkg/provider/git.go).
And the release is than created with the CI_JOB_TOKEN.
Hi @christophwitzko,
do you have any update on this issue? For me it seems like you have a plan, that could work.
We are currently migrating from github to gitlab and stumbled upon this issue.
Thanks in advance
Thanks to @superewald a new version of the GitLab provider was just released that supports now the CI_JOB_TOKEN
.