Created
October 13, 2022 20:55
-
-
Save padupe/fb68b39d11fe893b5d5315e4b613a4ee to your computer and use it in GitHub Desktop.
[Backstage] Catalog Software Integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
## Running this script will do following for all passed repos: | |
## - Create a branch `backstage-integration` | |
## - Add catalog-info.yaml | |
## - Creates a PullRequest | |
## | |
## Inspired at: https://gist.github.com/axdotl/8231abd46793ea23160662c3d81f4ba9 | |
## - User: @axdotl | |
## | |
## Requirements: | |
## - GitHub Personal Access Token with owner privilege; | |
## - Organization Indication on GitHub; | |
## - Default branch indicated; | |
## - Repository must have at least one team with Admin privileges; | |
## - List of repositories in .txt format; | |
## - File catalog-info.yaml with variables that will be used. | |
## | |
## This script expects following files | |
## - repos.txt: a file with repository names (one per li (deixar última linha em branco)ne) | |
## - catalog-info.yaml: A minimal manifest template with content like | |
## | |
## #catalog-info.yaml | |
## apiVersion: backstage.io/v1alpha1 | |
## kind: <KIND> | |
## metadata: | |
## name: <NAME> | |
## annotations: | |
## github.com/project-slug: <ORG>/<NAME> | |
## tags: | |
## - <LANGUAGE> | |
## spec: | |
## type: <SPEC_TYPE> | |
## lifecycle: production | |
## owner: <TEAM_OWNER> | |
## <DEFINITION> | |
GH_TOKEN=ghp_**** | |
ORG=your-org | |
branchDefault=production | |
while read -r repo; do | |
echo "" | |
if [[ $repo == \#* ]] | |
then | |
echo "Ignore $repo" | |
continue | |
fi | |
echo "Repo: $repo" | |
api="api" | |
front="front" | |
iac="iac" | |
kind= | |
specType= | |
# Exclusive for kind: API | |
definition= | |
# Validate Kind and spec.type at catalog-info.yaml | |
if [[ $repo == $iac* ]] | |
then | |
kind=Resource | |
specType=iac | |
echo 'Kind is "Resource" ✅' | |
elif [[ $repo == *"$front"* ]] | |
then | |
kind=Component | |
specType=website | |
echo 'Kind is "Component", spec.type is "website" ✅' | |
elif [[ $repo == *"$api"* ]] | |
then | |
kind=API | |
specType=openapi | |
definition='definition: "openapi: 3.0.0"' | |
echo 'Kind is "API" ✅' | |
else | |
kind=Component | |
specType=service | |
echo 'Kind is "Component", spec.type is "service" ✅' | |
fi | |
# Validate if catalog-info.yaml exists | |
rc=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$ORG/$repo/contents/catalog-info.yaml) | |
if [[ $rc == '200' ]] | |
then | |
echo "catalog-info.yaml found, no more actions required." | |
continue | |
elif [[ $rc == '404' ]] | |
then | |
echo "No catalog-info.yaml found" | |
else | |
echo "Failed to check for catalog-info.yaml, status $rc" | |
echo "Will continue with next item..." | |
continue | |
fi | |
# Validate branch default at GitHub | |
hasMain=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$ORG/$repo/git/refs/heads/$branchDefault) | |
mainName=$branchDefault | |
if [[ $hasMain == '200' ]] | |
then | |
echo "has main branch" | |
elif [[ $hasMain == '404' ]] | |
then | |
echo "has master branch" | |
mainName=$branchDefault | |
else | |
echo "Failed to check for main" | |
fi | |
headsRef=$(curl -s -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$ORG/$repo/git/refs/heads/$mainName) | |
headsSha=$(echo "$headsRef" | jq '.object.sha' -r) | |
headsUrl=$(echo "$headsRef" | jq '.object.url' -r) | |
# Get Admin Team | |
verifyTeams=$(curl -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$ORG/$repo/teams) | |
## Get first position at array | |
getTeamAdmin=$(echo "$verifyTeams" | jq -r '.[0] | select(.permissions.admin==true)') | |
if ! [[ $getTeamAdmin ]] | |
then | |
echo 'Without Admin Team' | |
printf "${repo}\n" >> repos-without-admin.team.txt | |
continue | |
fi | |
## Format adim team value | |
echo "Admin Team: $getTeamAdmin" | |
teamAdmin=$(echo "$getTeamAdmin" | jq -r '.name') | |
echo "Team Slug: $teamAdmin" #Squad-core-api-admin | |
slugString=${teamAdmin,,} #squad-core-api-admin | |
adminInfo="admin" | |
teamAdminSlug= | |
if [[ $slugString == *"$adminInfo"* ]] | |
then | |
teamAdminSlug="${slugString}" | |
echo 'Slug already has the suffix "admin" ✅' | |
else | |
teamAdminSlug="${slugString}-admin" | |
echo 'Slug was given the suffix "-admin" ✅' | |
fi | |
echo "Team Slug After Validation: $teamAdminSlug" | |
# Get top language at Repository | |
language=$(curl -s -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$ORG/$repo/languages | jq 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' -r | awk '{split($0,a,"="); print tolower(a[1])}' | head -1) | |
echo "Language: $language" | |
if [[ $language == '' ]] | |
then | |
language=poc | |
echo "Could not find a highlighted language" | |
fi | |
# Create Branch "backstage-integration" | |
createBranch=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" -X POST https://api.github.com/repos/$ORG/$repo/git/refs -d "{\"ref\":\"refs/heads/backstage-integration\", \"sha\":\"$headsSha\"}") | |
if [[ $createBranch == '201' ]] | |
then | |
echo "Branch backstage-integration ✅" | |
else | |
echo "Branch backstage-integration ❌" | |
printf "${repo}\n" >> repos-with-error.txt | |
continue | |
fi | |
# Create "catalog-info.yaml" file | |
catalogInfo=$(sed "s/<NAME>/$repo/" < catalog-info.yaml | sed "s/<KIND>/$kind/" | sed "s/<ORG>/$ORG/" | sed "s/<SPEC_TYPE>/$specType/" | sed "s/<LANGUAGE>/$language/" | sed "s/<TEAM_OWNER>/$teamAdminSlug/" | sed "s/<DEFINITION>/$definition/" | base64 -w 0) | |
commitRc=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" -X PUT https://api.github.com/repos/$ORG/$repo/contents/catalog-info.yaml -d "{\"message\":\"Add catalog-info.yaml for Backstage integration.\",\"content\": \"$catalogInfo\",\"branch\": \"refs/heads/backstage-integration\"}") | |
if [[ $commitRc == '201' ]] | |
then | |
echo "catalog-info.yaml added ✅" | |
else | |
echo "catalog-info.yaml added ❌" | |
continue | |
fi | |
# Create Pull Request | |
createPrRc=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" -X POST https://api.github.com/repos/$ORG/$repo/pulls -d "{\"head\":\"backstage-integration\",\"base\":\"$mainName\",\"title\": \"Add catalog-info.yaml for Backstage integration.\",\"body\":\"This pull request adds a **Backstage entity metadata file** to this repository so that the component can be added to the $ORG software catalog.\n\nAfter this pull request is merged, the component will become available.\n\nFeel free to make changes to the file. For more information, read about the [descriptor format of catalog entities](https://backstage.io/docs/features/software-catalog/descriptor-format).\"}") | |
if [[ $createPrRc == '201' ]] | |
then | |
echo "PullRequest ✅" | |
else | |
echo "PullRequest ❌" | |
continue | |
fi | |
done <repos.txt |
I'm glad that the script was helpful. 🚀
🚀🚀
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
More than deserved credits to @axdotl, I just tweaked the script to make it even more "nice".