diff --git a/action.yml b/action.yml index cbbd82fb..a3b90d5a 100644 --- a/action.yml +++ b/action.yml @@ -19,10 +19,10 @@ inputs: required: true context: description: Directory in the repository where the Dockerfile or start command is located - default: "./" + required: false dockerfile: description: Path to the Dockerfile (optional) - required: false + default: "./Dockerfile" exposed_port: description: Port to expose in the container required: true diff --git a/entrypoint.sh b/entrypoint.sh index c33553dc..30c73fce 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -28,7 +28,7 @@ comment() { - PR Deploy + PR Deploy ${status_message} Visit Preview $(date +'%b %d, %Y %I:%M%p') @@ -42,6 +42,13 @@ comment() { -d "$comment_body" \ -H "Accept: application/vnd.github.v3+json" \ "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/issues/${PR_NUMBER}/comments" | jq -r '.id') + + elif [ "$COMMENT_ID" == "null" ]; then + # Create a new comment + COMMENT_ID=$(curl -s -H "Authorization: token $GITHUB_TOKEN" -X POST \ + -d "$comment_body" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/issues/${PR_NUMBER}/comments" | jq -r '.id') else # Update an existing comment curl -s -H "Authorization: token $GITHUB_TOKEN" -X PATCH \ @@ -74,6 +81,19 @@ SANITIZED_OUTPUT=$(echo "$REMOTE_OUTPUT" | sed 's/[[:cntrl:]]//g') COMMENT_ID=$(echo "$SANITIZED_OUTPUT" | jq -r '.COMMENT_ID') DEPLOYED_URL=$(echo "$SANITIZED_OUTPUT" | jq -r '.DEPLOYED_URL') +if [ "$COMMENT_ID" == "null" ]; then + # Checks if the action is opened + if [[ "$PR_ACTION" == "opened" || "$PR_ACTION" == "synchronize" || "$PR_ACTION" == "reopened" ]]; then + comment "Deploying ⏳" "#" + elif [ "$PR_ACTION" == "closed" ]; then + comment "Terminated 🛑" "#" + fi + + # Run the pr-deploy.sh script on the remote server and capture the output from the remote script + NEW_REMOTE_OUTPUT=$(sshpass -p "$SERVER_PASSWORD" ssh -o StrictHostKeyChecking=no -p $SERVER_PORT $SERVER_USERNAME@$SERVER_HOST bash /srv/pr-deploy.sh $CONTEXT $DOCKERFILE $EXPOSED_PORT $REPO_URL $REPO_ID $GITHUB_HEAD_REF $PR_ACTION $PR_NUMBER $COMMENT_ID | tail -n 1) + exit 0 +fi + if [ -z "$DEPLOYED_URL" ]; then if [ "$PR_ACTION" == "closed" ]; then comment "Terminated 🛑" "#" && exit 0 diff --git a/pr-deploy.sh b/pr-deploy.sh index 30db7ea8..50fa1b2d 100644 --- a/pr-deploy.sh +++ b/pr-deploy.sh @@ -12,12 +12,37 @@ PR_ACTION=$7 PR_NUMBER=$8 COMMENT_ID=$9 PR_ID="pr_${REPO_ID}${PR_NUMBER}" +# JSON file to store PIDs +PID_FILE="/srv/pr-deploy/nohup.json" +COMMENT_ID_FILE="/srv/pr-deploy/comments.json" +DEPLOY_FOLDER="/srv/pr-deploy" function handle_error { echo "{\"COMMENT_ID\": \"$COMMENT_ID\", \"DEPLOYED_URL\": \"\"}" exit 1 } +# This helps to kill the process created by nohup using the process id +function kill_process_with_pid() { + # serveo + local key=$1 + ID=$(jq -r --arg key "$key" '.[$key]' "${PID_FILE}") + if [ -n $ID ]; then + kill -9 $ID + jq --arg key "$key" 'del(.[$key])' "${PID_FILE}" > tmp && mv tmp "${PID_FILE}" + fi +} + +# Initialize the JSON file for nohup if it doesn't exist +if [ ! -f "$PID_FILE" ]; then + echo "{}" > "$PID_FILE" +fi + +# Initialize the JSON file for comment if it doesn't exist +if [ ! -f "$COMMENT_ID_FILE" ]; then + echo "{}" > "$COMMENT_ID_FILE" +fi + # Set up trap to handle errors trap 'handle_error' ERR @@ -37,16 +62,18 @@ fi FREE_PORT=$(python3 -c 'import socket; s = socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()') # Setup directory -mkdir -p /srv/hngprojects/ -cd /srv/hngprojects +mkdir -p ${DEPLOY_FOLDER}/ +cd ${DEPLOY_FOLDER} rm -rf $PR_ID # Handle COMMENT_ID if [ -n "$COMMENT_ID" ]; then - echo "$COMMENT_ID" > "${PR_ID}.txt" + # echo "$COMMENT_ID" > "${PR_ID}.txt" + jq --arg pr_id "$PR_ID" --arg cid "$COMMENT_ID" '.[$pr_id] = $cid' "$COMMENT_ID_FILE" > tmp.$$.json && mv tmp.$$.json "$COMMENT_ID_FILE" else - if [ -f "${PR_ID}.txt" ]; then - COMMENT_ID=$(cat "${PR_ID}.txt") + if [ -f "$COMMENT_ID_FILE" ]; then + COMMENT_ID=$(jq -r --arg key "$PR_ID" '.[$key]' "${COMMENT_ID_FILE}") + else COMMENT_ID="" fi @@ -66,7 +93,7 @@ case $PR_ACTION in [ -n "$IMAGE_ID" ] && sudo docker rmi -f $IMAGE_ID # Exit early for 'closed' action - [ "$PR_ACTION" == "closed" ] && echo "{\"COMMENT_ID\": \"$COMMENT_ID\", \"DEPLOYED_URL\": \"\"}" && exit 0 + [ "$PR_ACTION" == "closed" ] && echo "{\"COMMENT_ID\": \"$COMMENT_ID\", \"DEPLOYED_URL\": \"\"}" && kill_process_with_pid $PR_ID && exit 0 ;; esac @@ -83,27 +110,25 @@ sudo docker run -d -p $FREE_PORT:$EXPOSED_PORT --name $PR_ID $PR_ID echo "Start SSH session..." -# Checks if serveo +# function to check if serveo was successful # check_serveo() { -# grep -q "ssh: connect to host serveo.net port 22: Connection refused" serveo_output.log || grep -q "ssh: connect to host serveo.net port 22: Connection timed out" serveo_output.log +# grep "Forwarding HTTP traffic from" serveo_output.log | tail -n 1 | awk '{print $5}' # } - # Set up tunneling using Serveo with a random high-numbered port nohup ssh -tt -o StrictHostKeyChecking=no -R 80:localhost:$FREE_PORT serveo.net > serveo_output.log 2>&1 & +SERVEO_PID=$! sleep 3 -# # Check if Serveo tunnel was set up successfully -# if [ check_serveo ]; then + +# Check if Serveo tunnel was set up successfully DEPLOYED_URL=$(grep "Forwarding HTTP traffic from" serveo_output.log | tail -n 1 | awk '{print $5}') -# else - # nohup ssh -tt -o StrictHostKeyChecking=no -R 80:localhost:$FREE_PORT ssh.localhost.run > localhost_run_output.log 2>&1 & - # sleep 30 - # # if grep -q "Connect to" localhost_run_output.log; then - # DEPLOYED_URL=$(grep "tunneled with tls termination" localhost_run_output.log | awk '{print $NF}') - # else - # DEPLOYED_URL="" - # fi -# fi + +# update the nohup ids +if [ -n DEPLOYED_URL ]; then + # jq --arg pid "$SERVEO_PID" '.serveo = $pid' "$PID_FILE" > tmp.$$.json && mv tmp.$$.json "$PID_FILE" + jq --arg pr_id "$PR_ID" --arg pid "$SERVEO_PID" '.[$pr_id] = $pid' "$PID_FILE" > tmp.$$.json && mv tmp.$$.json "$PID_FILE" + +fi # Output the final JSON