Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: add nightly codespace CI #453

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
ci: improve ci script
manekinekko committed Mar 18, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit b12e3d75b2c9bf16ab77522fa4aab60131aef334
182 changes: 108 additions & 74 deletions .github/workflows/codespaces-ci.sh
Original file line number Diff line number Diff line change
@@ -10,90 +10,124 @@ GREEN='\033[0;32m'
NC='\033[0m' # No Color

# login to GitHub CLI
echo "Login to GitHub CLI..."
echo ${{ $GITHUB_TOKEN }} | gh auth login --with-token
function gh_login() {
echo "Loging in with GitHub CLI as admin..."
echo $X_GITHUB_TOKEN | gh auth login --with-token

echo "Check auth status..."
gh auth status
echo "Checking auth status..."
gh auth status
}

# create a codespace
echo "Create a codespace "$CODESPACE_NAME" for $GITHUB_REPOSITORY on branch $BRANCH..."
gh codespace create \
--repo $GITHUB_REPOSITORY \
--branch $BRANCH \
--display-name $CODESPACE_NAME \
--retention-period "1h" \
--idle-timeout "1h" \
--machine "largePremiumLinux" \
--status \
--default-permissions

CODESPACE_ID=$(gh codespace list -R $GITHUB_REPOSITORY --jq ".[] | select(.displayName == \"$CODESPACE_NAME\")" --json displayName,name) | jq -r '.name'
echo "Codespace created and started: $CODESPACE_ID"

# connect to the codespace and start the app
echo "Running all services..."
gh codespace ssh -c $CODESPACE_ID "npm start --prefix /workspaces/contoso-real-estate" &

# Wait for the app to start
echo "Waiting 30s for all ports to be fowarded..."
sleep 30
function gh_create_codespace() {
echo "Creating a codespace $CODESPACE_NAME for $GITHUB_REPOSITORY on branch $BRANCH..."
gh codespace create \
--repo $GITHUB_REPOSITORY \
--branch $BRANCH \
--display-name $CODESPACE_NAME \
--retention-period "1h" \
--idle-timeout "1h" \
--machine "largePremiumLinux" \
--status \
--default-permissions
}

# fetch the codespace ID
function gh_fetch_codespace_id() {
CODESPACE_ID=$(gh codespace list -R $GITHUB_REPOSITORY --jq ".[] | select(.displayName == \"$CODESPACE_NAME\")" --json displayName,name | jq -r '.name')
echo "Codespace created and started: $CODESPACE_ID"
}

# connect to the codespace and start the services
function gh_codespace_start_services() {
echo "Running all services (over SSH)..."
(gh codespace ssh -c $CODESPACE_ID "npm start --prefix /workspaces/contoso-real-estate") &
}

# check all services are running
nb_services_down=0
max_retries=5
while [ $nb_services_down > 0 ]; do

echo -ne "Fetching registered services..."
services=$(gh cs ports -c $CODESPACE_ID --json label,browseUrl | jq -r '.[] | select(.label != "") | .browseUrl')
nb_services=$(echo "$services" | awk 'END { print NR }')
echo " Found $nb_services"

function gh_codespace_check_services_status() {
nb_services_down=0
echo "---------------------------------------------------------------------------------------------------------"
for service in $services; do
echo -ne "Inspecting: $service ... "
status=$(curl -H "X-Github-Token: $GITHUB_TOKEN" -s -o /dev/null -w "%{http_code}" $service)

if [ $status == 200 ] || [ $status == 404 ]; then
echo -e "${GREEN}$status OK${NC}"
else
echo -e "${RED}$status ERROR${NC}"
((nb_services_down++))
fi
done
max_retries=5
while [ $nb_services_down > 0 ]; do

if [ $nb_services_down == 0 ]; then
echo "All services are running!"
break
fi
echo -ne "Fetching registered services..."
services=$(gh codespace ports -c $CODESPACE_ID --json label,browseUrl | jq -r '.[] | select(.label != "") | .browseUrl')
nb_services=$(echo "$services" | awk 'END { print NR }')
echo " Found $nb_services"

if [ $max_retries == 0 ]; then
echo "Max retries reached, exiting..."
break
fi
if [ -z "$services" ]; then
echo "No services found, exiting..."
break
fi

echo "---------------------------------------------------------------------------------------------------------"
echo "Found $nb_services_down services down..."
echo "Wait 10s before retrying... (retries left: $max_retries)"
sleep 10
((max_retries--))
done
nb_services_down=0
echo "---------------------------------------------------------------------------------------------------------"
for service in $services; do
echo -ne "Inspecting: $service ... "
status=$(curl -H "X-Github-Token: $GITHUB_TOKEN" -s -o /dev/null -w "%{http_code}" $service)

if [ $status == 200 ] || [ $status == 404 ]; then
echo -e "${GREEN}$status OK${NC}"
else
echo -e "${RED}$status ERROR${NC}"
((nb_services_down++))
fi
done

if [ $nb_services_down == 0 ]; then
echo "All services are running!"
break
fi

if [ $max_retries == 0 ]; then
echo "Max retries reached, exiting..."
break
fi

# print all codespaces logs
echo "Fetching codespace logs before exiting..."
gh codespace logs -c $CODESPACE_ID
echo "---------------------------------------------------------------------------------------------------------"
echo "Found $nb_services_down services down..."
echo "Wait 10s before retrying... (retries left: $max_retries)"
sleep 10
((max_retries--))
done
}

# Wait for the services to start
function wait_for_services() {
echo -ne "Waiting 30s for all services to start"
for i in {1..30}; do
echo -ne "."
sleep 1
done
echo ""
}

# stop and delete the codespace
echo "Stopping and deleting codespace $CODESPACE_ID..."
gh codespace stop -R $GITHUB_REPOSITORY
gh codespace delete -R $GITHUB_REPOSITORY

if [ $nb_services_down > 0 ]; then
echo -e "${RED}ERROR: Some services are still down, exiting with error.${NC}"
exit 1
else
echo -e "${GREEN}OK: All services are running, exiting with success.${NC}"
exit 0
fi
function gh_codespace_stop_and_delete() {
echo "Stopping and deleting codespace $CODESPACE_ID..."
gh codespace stop -c $CODESPACE_ID
gh codespace delete -c $CODESPACE_ID -f
}

function print_report_and_exit() {
if [ $nb_services == 0 ]; then
echo -e "${RED}ERROR: No services found. Inspect the logs above for more details.${NC}"
exit 1
elif [ $nb_services_down > 0 ]; then
echo -e "${RED}ERROR: $nb_services_down services are still down. Inspect the logs above for more details.${NC}"
exit 1
else
echo -e "${GREEN}OK: All services are running, exiting with success.${NC}"
exit 0
fi
}

############################################
gh_login;
gh_create_codespace;
gh_fetch_codespace_id;
gh_codespace_start_services;
wait_for_services;
gh_codespace_check_services_status;
gh_codespace_stop_and_delete;
print_report_and_exit;