install.fairie/.config/taskfiles/git/Taskfile-gitlab.yml
Brian Zalewski f42899b107 Latest
2022-12-24 15:04:59 -05:00

477 lines
21 KiB
YAML

---
version: '3'
vars:
REPOSITORY_LIST: .cache/repository-list.txt
tasks:
access-token:
deps:
- :install:software:glab
- :install:software:jq
- create
vars:
REPO_ID:
sh: glab api projects/:fullpath | jq '.id'
REQUEST_DATA: '{ "name":"PROJECT_CI_ACCESS_TOKEN", "scopes":["write_repository", "read_repository"] }'
TOKEN_STATUS:
sh: type glab > /dev/null && glab api projects/:fullpath/access_tokens | jq -r '.[] | select(.name=="PROJECT_CI_ACCESS_TOKENX") | .id' || true
run: once
log:
error: Failed to configure project-specific access token
start: Configuring project-specific access token
success: Configured project-specific access token
cmds:
- |
curl -sSL --request POST --header "PRIVATE-TOKEN: $GITLAB_TOKEN" --header \
'Content-Type:application/json' --data '{{.REQUEST_DATA}}' \
'https://gitlab.com/api/v4/projects/{{.REPO_ID}}/access_tokens' > /dev/null
status:
- '[ -n "{{.TOKEN_STATUS}}" ] || ! glab api projects/:fullpath/access_tokens'
branches:
deps:
- :install:software:glab
- create
vars:
REPO_ID:
sh: glab api projects/:fullpath | jq '.id'
run: once
log:
error: Error encountered while setting up protected branches
start: Setting up protected branches
success: Set up protected branches
cmds:
- |
glab api projects/:fullpath/protected_branches -X POST -f name=master -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=main -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=main -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=next -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=next -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=alpha -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=alpha -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=beta -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=beta -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=protected/* -f code_owner_approval_required=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=synchronize -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=synchronize -f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
if [[ '{{.REPOSITORY_TYPE}}' == 'ansible' ]]; then
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=test/linux -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=test/linux \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=test/darwin -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=test/darwin \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=test/windows -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=test/windows \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
fi
if [[ '{{.REPOSITORY_TYPE}}' == 'packer' ]]; then
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=hyperv -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=hyperv \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=kvm -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=kvm \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=parallels -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=parallels \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=virtualbox -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=virtualbox \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
glab api projects/:fullpath/repository/branches -X POST -f id={{.REPO_ID}} -f branch=vmware -f ref=master &> /dev/null &
glab api projects/:fullpath/protected_branches -X POST -f name=vmware \
-f code_owner_approval_required=true -f allow_force_push=true &> /dev/null &
fi
wait
create:
deps:
- :install:software:glab
- :install:software:jq
- :git:remotes
vars:
DESCRIPTION:
sh: jq -r '.description' package.json
GITLAB_GROUP:
sh: jq -r '.blueprint.repository.gitlab' package.json | sed 's/https:\/\/gitlab.com\///' | sed 's!/[^/]*$!!'
GITLAB_PATH:
sh: jq -r '.blueprint.repository.gitlab' package.json | sed 's/https:\/\/gitlab.com\///'
NAME:
sh: jq -r '.blueprint.name' package.json
PROJECT_TYPE:
sh: if [[ $(jq -r '.private' package.json) == 'true' ]]; then echo '--private'; else echo '--public'; fi
TMP:
sh: mktemp
run: once
log:
error: Encountered error while creating GitLab repository
start: Ensuring GitLab repository has been created
success: Ensured GitLab repository exists
cmds:
- cmd: |
NO_PROMPT=1 glab repo create '{{.GITLAB_PATH}}' --group '{{.GITLAB_GROUP}}' \
--description '{{.EMOJI_START}}{{.DESCRIPTION}}{{.EMOJI_END}}' --name '{{.NAME}}' \
{{.PROJECT_TYPE}} --tag "$(jq -r '.keywords | tostring' package.json | sed 's/\[//' | sed 's/\]//')"
task --list > /dev/null || (echo "ERROR: Invalid Taskfiles!" && exit 1)
git add --all
HUSKY=0 git commit --quiet -m "🎂 Birth" -n || true
git push gitlab master
ignore_error: true
status:
- '[ -z "$GITLAB_TOKEN" ] || (test -d .git && glab repo view "{{.GITLAB_PATH}}" > /dev/null)'
preconditions:
- sh: '[ "{{.DESCRIPTION}}" != "null" ]'
msg: The `.description` in `package.json` must be set.
- sh: '[ "{{.NAME}}" != "null" ]'
msg: The `.blueprint.name` variable in `package.json` must be set.
group:exec:
cmds:
- task: group:exec:{{if .CLI_ARGS}}cli{{else}}prompt{{end}}
group:exec:cli:
log:
error: Failed to run group:exec logic
start: Running group:exec logic
success: Successfully ran group:exec logic
cmds:
- task git:gitlab:group:repositories -- {{index (splitList " ---- " .CLI_ARGS) 0}}
- |
BASE_PWD="$PWD"
function execRepo() {
REPO_DETAILS="$1"
REPO_URL="$(echo "$REPO_DETAILS" | sed 's/ .*$//')"
REPO_PATH="$(echo "$REPO_DETAILS" | sed 's/^.* //')"
DIR_NAME="$(dirname "$REPO_PATH")"
mkdir -p "$DIR_NAME"
if [ -d "$REPO_PATH" ]; then
cd "$REPO_PATH"
git pull origin master || continue
cd "$BASE_PWD"
else
git clone "$REPO_URL" "$REPO_PATH"
fi
.config/log info "Running bash command on $REPO_PATH"
(
cd "$REPO_PATH"
{{trimPrefix "'" (trimSuffix "'" (index (splitList " ---- " .CLI_ARGS) 1))}}
cd "$BASE_PWD"
)
.config/log success "Finished running bash command on $REPO_PATH"
}
cat {{.REPOSITORY_LIST}} | (while IFS= read -r REPO_DETAILS; do
.config/log info "Executing logic on $REPO_DETAILS"
execRepo "$REPO_DETAILS"{{if eq .GROUP_EXEC_ASYNC "true"}} &{{end}}
done{{if eq .GROUP_EXEC_ASYNC "true"}}
wait){{else}}){{end}}
group:exec:prompt:
deps:
- :install:software:glab
- :install:software:jq
interactive: true
cmds:
- |
GITLAB_GROUPS="$(glab api --paginate groups | jq -r '.[].full_path')"
GROUP_OPTION="$(gum choose "$ENVIRONMENT_OPTIONS")"
GUM_CONFIRM_MSG="Would you like to use the previously run script (i.e. .cache/gitlab-group.sh)?"
if [ -f .cache/gitlab-group.sh ] && gum confirm "$GUM_CONFIRM_MSG"; then
bash .cache/gitlab-group.sh
else
TMP="$(mktemp)"
gum write --placeholder "Enter the script you would like to run including the hashbang (CTRL+D to finish)" --show-cursor-line --show-line-numbers > "$TMP"
bash "$TMP"
mkdir -p .cache
mv "$TMP" > .cache/gitlab-group.sh
fi
group:repositories:
deps:
- :install:software:glab
- :install:software:jq
summary: |
# Return repositories belonging to group and sub-groups
Given a GitLab group path (which can include subgroups as well), this task will cycle through
the group and its' subgroups and generate a list of repositories. The repositories are
saved to a file located at `{{.REPOSITORY_LIST}}`.
**Example specifying a group and subgroup:**
`task {{.TASK}} -- megabyte-labs/ansible-roles`
log:
error: Encountered error while generating a list of repositories
start: Generating list of repositories
success: List of repositories generated
cmds:
- mkdir -p .cache
- rm -f {{.REPOSITORY_LIST}}
- task: group:repositories:loop
group:repositories:loop:
cmds:
- glab api "groups/{{urlquery .CLI_ARGS}}" | jq -r '.projects[] | .ssh_url_to_repo + " " + .path_with_namespace' >> {{.REPOSITORY_LIST}}
- |
.config/log info 'Recursively acquiring repository details from subgroups'
SUBGROUPS="$(glab api groups/{{urlquery .CLI_ARGS}}/subgroups | jq -r '.[] | .full_path')"
if [ -n "$SUBGROUPS" ]; then
echo "$SUBGROUPS" | (while IFS= read -r SUBGROUP; do
task {{.TASK}} -- "$SUBGROUP" &
done
wait)
fi
ids:
deps:
- :install:software:glab
- :install:software:jq
- create
log:
error: Error acquiring GitLab project and group IDs
start: Acquiring GitLab project and group IDs
success: Saved GitLab project and group IDs to package.json
cmds:
- |
API_RES="$(glab api projects/:fullpath)"
PROJECT_ID="$(echo "$API_RES" | jq '.id')"
TMP="$(mktemp)" && jq --arg projectId "$PROJECT_ID" '.blueprint.gitlab_project_id = $projectId' package.json > "$TMP"
mv "$TMP" package.json
GROUP_ID="$(echo "$API_RES" | jq '.namespace.id')"
TMP_GROUP="$(mktemp)" && jq --arg groupId "$GROUP_ID" '.blueprint.gitlab_group_id = $groupId' package.json > "$TMP_GROUP"
mv "$TMP_GROUP" package.json
integrations:
deps:
- create
run: once
cmds:
- task: integrations:github
integrations:github:
deps:
- :install:software:glab
- :install:software:jq
log:
error: Error enabling GitLab's GitHub integration
start: Ensuring GitLab's GitHub integration is enabled
success: GitLab's GitHub integration is enabled
cmds:
- glab api projects/:fullpath/integrations/github -X PUT -f token="$GITHUB_TOKEN"
-f repository_url="$(jq -r '.blueprint.repository.github' package.json)" --silent
status:
- '[ -z "$GITLAB_TOKEN" ] || [ -z $GITHUB_TOKEN ]'
mirror:
deps:
- :install:software:glab
- :install:software:jq
- :git:github:create
- create
vars:
GITHUB_SLUG:
sh: jq -r '.blueprint.repository.github' package.json | sed 's/.*\///'
GITLAB_REPO_ID:
sh: glab api projects/:fullpath | jq -r '.id'
PUSH_MIRROR_COUNT:
sh: glab api projects/:fullpath/remote_mirrors | jq '. | length'
log:
error: Error ensuring push/pull mirroring is enabled between GitLab and GitHub
start: Ensuring push/pull mirroring from GitLab to GitHub is set up
success: Push and pull mirroring from GitLab to GitHub are enabled
cmds:
- |
if [[ "{{.PUSH_MIRROR_COUNT}}" == '0' ]]; then
glab api projects/:fullpath/remote_mirrors --method POST --header "Content-Type: application/json" \
-f "url=https://{{.GITHUB_USER}}:$GITHUB_TOKEN@github.com/{{.GITHUB_ORG}}/{{.GITHUB_SLUG}}.git" \
-f 'enabled=true' > /dev/null
.config/log success 'Successfully set up push mirroring from GitLab to GitHub'
fi
- >
curl -s -H 'Content-Type: application/json' -H "Authorization: Bearer $GITLAB_TOKEN" -X PUT --data
"{\"mirror\": true, \"import_url\": \"https://{{.GITHUB_USER}}:$GITHUB_TOKEN@github.com/{{.GITHUB_ORG}}/{{.GITHUB_SLUG}}.git\"}"
'https://gitlab.com/api/v4/projects/{{.GITLAB_REPO_ID}}' > /dev/null
status:
- '[ -z "$GITLAB_TOKEN ] || [ -z "GITHUB_TOKEN ]'
pipelines:
deps:
- :install:software:glab
- :install:software:jq
- create
vars:
PIPELINE_COUNT:
sh: jq -r '.gitlab_pipelines | length' .variables.json
log:
error: Error setting up GitLab pipelines
start: Ensuring GitLab pipelines are set up according to the configuration
success: GitLab pipelines are set up
cmds:
- |
PIPELINES="$(jq -r '.gitlab_pipelines' .variables.json)"
PIPELINE_RES="$(glab api projects/:fullpath/pipeline_schedules)"
for INDEX in {1..{{.PIPELINE_COUNT}}}; do
PIPELINE_INDEX="$((INDEX - 1))"
ACTIVE="$(echo "$PIPELINES" | jq -r --arg i "$PIPELINE_INDEX" '.[$i | tonumber].active')"
CRON="$(echo "$PIPELINES" | jq -r --arg i "$PIPELINE_INDEX" '.[$i | tonumber].cron' | sed 's/"//g')"
DESC="$(echo "$PIPELINES" | jq -r --arg i "$PIPELINE_INDEX" '.[$i | tonumber].description')"
REF="$(echo "$PIPELINES" | jq -r --arg i "$PIPELINE_INDEX" '.[$i | tonumber].ref')"
if (! echo "$PIPELINE_RES" | grep "$DESC") > /dev/null; then
glab api projects/:fullpath/pipeline_schedules -X POST -f active="$ACTIVE" -f description="$DESC" -f ref="$REF" \
-f cron="$CRON" -f cron_timezone='{{.TIMEZONE}}' --silent
if [ "$DESC" != 'null' ]; then .config/log success "Pipeline with description of '${DESC}' successfully added"; fi
else
if [ "$DESC" != 'null' ]; then .config/log info "Pipeline with description of '${DESC}' already added"; fi
fi
done
status:
- '[ -z "$GITLAB_TOKEN" ]'
pipelines:clear:
deps:
- create
log:
error: Error clearing GitLab pipelines
start: Clearing GitLab pipelines
success: Cleared GitLab pipelines
cmds:
- |
TMP="$(mktemp)"
glab api projects/:id/pipeline_schedules -X GET > "$TMP"
for PIPELINE_ID in $(jq -r '.[].id' "$TMP"); do
glab api projects/:fullpath/pipeline_schedules/"$PIPELINE_ID" -X DELETE
done
preconditions:
- sh: '[ ! -z "$GITLAB_TOKEN" ]'
msg: The `GITLAB_TOKEN` environment variable must be set to run this task
protected:off:
deps:
- :install:software:glab
vars:
BRANCH: '{{if .BRANCH}}{{.BRANCH}}{{else}}{{.CLI_ARGS}}{{end}}'
todo: figure out how to do it without deleteing the protection first
cmds:
- glab api projects/:fullpath/protected_branches/{{.BRANCH}} -X DELETE
- glab api projects/:fullpath/protected_branches -X POST -f name={{.BRANCH}} -f allow_force_push=true > /dev/null
status:
- '[ -z "$GITLAB_TOKEN" ]'
protected:on:
deps:
- :install:software:glab
vars:
BRANCH: '{{if .BRANCH}}{{.BRANCH}}{{else}}{{.CLI_ARGS}}{{end}}'
todo: figure out how to do it without deleteing the protection first
cmds:
- glab api projects/:fullpath/protected_branches/{{.BRANCH}} -X DELETE
- glab api projects/:fullpath/protected_branches -X POST -f name={{.BRANCH}} -f allow_force_push=false > /dev/null
status:
- '[ -z "$GITLAB_TOKEN" ]'
ssh-keys:
deps:
- :install:software:glab
- :install:software:jq
cmds:
- .config/log info 'Clearing GitLab SSH keys'
- |
KEY_URL='https://gitlab.com/api/v4/user/keys'
KEYIDS="$(curl -sSL --header "PRIVATE-TOKEN: $GITLAB_TOKEN" "$KEY_URL" | jq '.[].id')"
for KEYID in $KEYIDS; do
curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" -X DELETE "$KEY_URL/$KEYID"
done
- .config/log start 'Syncing SSH keys with GitLab'
- |
for KEY in `ls $HOME/.ssh/*.pub`; do
TITLE="$(cat $KEY | sed 's/\(.*\=\) \(.*\)$/\2/')"
glab ssh-key add $KEY -t "$TITLE"
done
- .config/log success 'Finished syncing SSH keys with GitLab'
preconditions:
- sh: '[ -n "$GITLAB_TOKEN" ]'
msg: The GITLAB_TOKEN must be set to a personal access token.
update:
run: once
cmds:
- task: update:deps
status:
- '[ -z "$GITLAB_TOKEN" ] || ! type glab &> /dev/null'
update:deps:
deps:
- access-token
- branches
- mirror
- integrations
- ids
- pipelines
- update:meta
- wiki
update:meta:
deps:
- :install:software:glab
- :install:software:jq
- create
vars:
DESCRIPTION:
sh: jq -r '.description' package.json
ISSUES_TEMPLATE: '## Summary\r\n\r\n(Summarize the bug encountered concisely)\r\n\r\n##
Steps to reproduce\r\n\r\n(How one can reproduce the issue - this is very important)\r\n\r\n##
Example Project\r\n\r\n(If possible, please create an example project here on GitLab.com that
exhibits the problematic\r\nbehavior, and link to it here in the bug report.\r\nIf you are using
an older version of GitLab, this will also determine whether the bug has been fixed\r\nin a more
recent version)\r\n\r\n## What is the current bug behavior?\r\n\r\n(What actually happens)\r\n\r\n##
What is the expected correct behavior?\r\n\r\n(What you should see instead)\r\n\r\n## Relevant
logs and/or screenshots\r\n\r\n(Paste any relevant logs - please use code blocks (```) to format
console output, logs, and code, as\r\nit is very hard to read otherwise.)\r\n\r\n## Possible
fixes\r\n\r\n(If you can, link to the line of code that might be responsible for the problem)'
NAME:
sh: jq -r '.blueprint.name' package.json
PROJECT_TYPE:
sh: if [[ $(jq -r '.private' package.json) == 'true' ]]; then echo 'private'; else echo 'public'; fi
TEST_COVERAGE_REGEX:
sh: jq -r '.build_coverage_regex' .variables.json | sed 's/^null$//'
log:
error: Error ensuring GitLab metadata is up-to-date
start: Ensuring GitLab metadata is up-to-date
success: GitLab metadata is up-to-date
cmds:
- |
KEYWORDS="$(jq -r '.keywords | tostring' package.json | sed 's/\[//' | sed 's/\]//' | sed 's/"//g')"
PROJECT_ID="$(glab api projects/:fullpath -X PUT -f build_coverage_regex="{{.TEST_COVERAGE_REGEX}}" \
-f wiki_enabled={{.GITLAB_WIKI}} -f visibility="{{.PROJECT_TYPE}}" -f topics="$KEYWORDS" | jq '.id')"
curl -s -H 'Content-Type: application/json' -H "Authorization: Bearer $GITLAB_TOKEN" -X PUT --data \
'{"description": "{{.EMOJI_START}}{{.DESCRIPTION}}{{.EMOJI_END}}", "issues_template": "{{.ISSUES_TEMPLATE}}", "name": "{{.NAME}}"}' \
"https://gitlab.com/api/v4/projects/$PROJECT_ID" > /dev/null
status:
- '[ -z "$GITLAB_TOKEN" ]'
preconditions:
- sh: '[ "{{.DESCRIPTION}}" != "null" ]'
msg: The `.description` in `package.json` must be set.
- sh: '[ "{{.NAME}}" != "null" ]'
msg: The `.blueprint.name` variable in `package.json` must be set.
wiki:
deps:
- :common:update:variables
- :install:software:glab
- :install:software:jq
- create
vars:
DOCS_URL:
sh: jq -r '.docs.link' .variables.json
log:
error: Failed to update GitLab wiki settings
start: Setting GitLab wiki settings
success: GitLab wiki settings are up-to-date
cmds:
- glab api projects/:fullpath/services/external-wiki -X PUT -f external_wiki_url="{{.DOCS_URL}}" --silent
status:
- '[ -z "$GITLAB_TOKEN" ]'
preconditions:
- sh: '[ "{{.DOCS_URL}}" != "null" ]'
msg: The `.docs.link` variable in `.variables.json` must be set.
- sh: '[ "{{.GROUP}}" != "null" ]'
msg: The `.group` variable in `.variables.json` must be set.