使用 Cookiecutter 创建脚手架资源库
本示例演示了如何使用Cookiecutter Template 通过 Port Actions 快速搭建 Gitlab 仓库。
此外,由于 cookiecutter 是一个开源项目,您可以制作自己的项目模板,了解更多信息请访问here 。
示例 - python 模板脚手架
请按照以下步骤开始使用 Python 模板:
- 创建以下变量作为Gitlab Variables :
- GITLAB_ACCESS_TOKEN
-[Personal Access Token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) ,作用域 如下:
api,
read_api,
read_repository,
write_repository`. PORT_CLIENT_ID
- Port客户端 IDlearn more 。PORT_CLIENT_SECRET
- Port客户端secretlearn more.
- GITLAB_ACCESS_TOKEN
2.在 Gitlab 组中创建名为 python_scaffolder
的 Gitlab 项目,并配置Pipeline Trigger Token 。
您可以被用于任何您喜欢的名称,只要确保在 Port Action 中正确配置即可。
3.按照我们的指南here 安装 Port 的 Gitlab 代理。
确保在安装 Port 的 Gitlab 代理时被用于 Pipeline 触发令牌。
4.使用以下 JSON 定义创建 Port 蓝图:
请记住,这可以是你想要的任何蓝图,这只是一个例子。
Port Microservice Blueprint
{
"identifier": "microservice",
"title": "Microservice",
"icon": "Microservice",
"schema": {
"properties": {
"description": {
"title": "Description",
"type": "string"
},
"url": {
"title": "URL",
"format": "url",
"type": "string"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}
5.使用以下 JSON 定义创建 Port 操作:
确保替换
python_scaffolder
中 PROJECT_NAME 和 GROUP_NAME 的占位符。Port Action
[
{
"identifier": "scaffold_gitlab",
"title": "Scaffold Gitlab Microservice",
"userInputs": {
"properties": {
"description": {
"title": "Description",
"type": "string",
"description": "Short description of your service"
},
"service_name": {
"icon": "DefaultProperty",
"title": "Service Name",
"type": "string",
"description": "Gitlab Project Name"
},
"gitlab_username": {
"title": "Gitlab Username",
"type": "string",
"description": "Gitlab username which should match your GITLAB_ACCESS_TOKEN configured in the Gitlab Project Variables"
},
"gitlab_group": {
"title": "Gitlab Group",
"description": "Gitlab Group to create the project in",
"type": "string"
}
},
"required": ["service_name", "gitlab_username", "gitlab_group"],
"order": [
"service_name",
"description",
"gitlab_username",
"gitlab_group"
]
},
"invocationMethod": {
"type": "GITLAB",
"omitPayload": false,
"omitUserInputs": false,
"projectName": "<PROJECT_NAME>",
"groupName": "<GROUP_NAME>",
"defaultRef": "main",
"agent": true
},
"trigger": "CREATE",
"requiredApproval": false
}
]
6.在你的 python_scaffolder
Gitlab 项目中,在主分支的 .gitlab-ci.yml
下创建一个 Gitlab CI 文件,内容如下:
Gitlab CI Script
image: python:3.10.0-alpine
variables:
COOKIECUTTER_TEMPLATE_URL: "https://gitlab.com/AdriaanRol/cookiecutter-pypackage-gitlab"
GITLAB_API_URL: "https://gitlab.com/api/v4"
# GITLAB_ACCESS_TOKEN: """ # This should be set in GitLab's CI/CD environment variables for security
stages: # List of stages for jobs, and their order of execution
- fetch-port-access-token
- scaffold
- create-entity
- update-run-status
fetch-port-access-token: # Example - get the Port API access token and RunId
stage: fetch-port-access-token
except:
- pushes
before_script:
- apk update
- apk add jq curl -q
script:
- |
accessToken=$(curl -X POST \
-H 'Content-Type: application/json' \
-d '{"clientId": "'"$PORT_CLIENT_ID"'", "clientSecret": "'"$PORT_CLIENT_SECRET"'"}' \
-s 'https://api.getport.io/v1/auth/access_token' | jq -r '.accessToken')
echo "ACCESS_TOKEN=$accessToken" >> data.env
runId=$(cat $TRIGGER_PAYLOAD | jq -r '.port_payload.context.runId')
echo "RUN_ID=$runId" >> data.env
artifacts:
reports:
dotenv: data.env
scaffold:
before_script: |
apk update
apk add jq curl git -q
pip3 install cookiecutter==2.3.0 -q
stage: scaffold
except:
- pushes
script:
- |
if [[ -z "$gitlab_group" ]]; then
echo "Gitlab group name must be provided"
exit 1
fi
# Create new repository on GitLab
NAMESPACE_ID=$(curl -s --header "Private-Token: $GITLAB_ACCESS_TOKEN" "$GITLAB_API_URL/groups/$gitlab_group" | jq -r .id)
CREATE_REPO_RESPONSE=$(curl -X POST -s "$GITLAB_API_URL/projects" --header "Private-Token: $GITLAB_ACCESS_TOKEN" --form "name=$service_name" --form "namespace_id=$NAMESPACE_ID")
PROJECT_URL=$(echo $CREATE_REPO_RESPONSE | jq -r .http_url_to_repo)
# Check if the repository creation was successful
if [[ -z "$PROJECT_URL" ]]; then
echo "Failed to create GitLab repository."
exit 1
fi
FIRST_NAME=$(cat $TRIGGER_PAYLOAD | jq -r '.trigger.by.user.firstName')
LAST_NAME=$(cat $TRIGGER_PAYLOAD | jq -r '.trigger.by.user.lastName')
EMAIL=$(cat $TRIGGER_PAYLOAD | jq -r '.trigger.by.user.email')
BLUEPRINT_ID=$(cat $TRIGGER_PAYLOAD | jq -r '.port_payload.context.blueprint')
echo "PROJECT_URL=$PROJECT_URL" >> data.env
echo "BLUEPRINT_ID=$BLUEPRINT_ID" >> data.env
# Generate cookiecutter.yaml file
cat <<EOF > cookiecutter.yaml
default_context:
full_name: "${FIRST_NAME} ${LAST_NAME}"
email: "${EMAIL}"
project_short_description: "${description}"
gitlab_username: "${gitlab_username}"
project_name: "${service_name}"
EOF
cookiecutter $COOKIECUTTER_TEMPLATE_URL --no-input --config-file cookiecutter.yaml --output-dir scaffold_out
echo "Initializing new repository..."
git config --global user.email "[email protected]"
git config --global user.name "Mighty Scaffolder"
git config --global init.defaultBranch "main"
cd scaffold_out/$service_name
git init
git add .
git commit -m "Initial commit"
GITLAB_HOSTNAME=$(echo "$GITLAB_API_URL" | cut -d'/' -f3)
git remote add origin https://$gitlab_username:$GITLAB_ACCESS_TOKEN@$GITLAB_HOSTNAME/${gitlab_group}/${service_name}.git
git push -u origin main
artifacts:
reports:
dotenv: data.env
create-entity:
stage: create-entity
except:
- pushes
before_script:
- apk update
- apk add jq curl -q
script:
- |
curl --location --request POST "https://api.getport.io/v1/blueprints/$BLUEPRINT_ID/entities?upsert=true&run_id=$RUN_ID&create_missing_related_entities=true" \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header "Content-Type: application/json" \
-d '{"identifier": "'"$service_name"'","title": "'"$service_name"'","properties": {"description": "'"$description"'","url": "'"$PROJECT_URL"'"}, "relations": {}}'
update-run-status:
stage: update-run-status
except:
- pushes
image: curlimages/curl:latest
script:
- |
curl -X PATCH \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{"status":"SUCCESS", "message": {"run_status": "Scaffold '"$service_name"' finished successfully!\n Project URL: '"$PROJECT_URL"'"}}' \
"https://api.getport.io/v1/actions/runs/$RUN_ID"
7.从 Port 应用程序的Self-service 标签触发操作。