Skip to content

Commit 1fffa71

Browse files
committed
Adding /ps-attach issue ops command
1 parent 0e868ea commit 1fffa71

File tree

4 files changed

+328
-4
lines changed

4 files changed

+328
-4
lines changed

.github/workflows/issue-ops-ps-commands.yml

Lines changed: 220 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ env:
1111
jobs:
1212
prechecks:
1313
name: Permission pre-check
14-
if: github.event.issue.pull_request != null && (startsWith(github.event.comment.body, '/ps-merge') || startsWith(github.event.comment.body, '/ps-create') || startsWith(github.event.comment.body, '/ps-update') || startsWith(github.event.comment.body, '/ps-approve') || startsWith(github.event.comment.body, '/ps-delete'))
14+
if: github.event.issue.pull_request != null && (startsWith(github.event.comment.body, '/ps-merge') || startsWith(github.event.comment.body, '/ps-create') || startsWith(github.event.comment.body, '/ps-update') || startsWith(github.event.comment.body, '/ps-approve') || startsWith(github.event.comment.body, '/ps-delete') || startsWith(github.event.comment.body, '/ps-attach'))
1515
outputs:
1616
ref: ${{steps.prechecks.outputs.ref}}
1717
eyes: ${{steps.prechecks.outputs.eyes}}
@@ -236,7 +236,7 @@ jobs:
236236
237237
const commentBody = `\
238238
### Schema changes merged successfully :tada:
239-
239+
240240
* :seedling: __DB-Branch__: [${BRANCH_NAME}](${BRANCH_URL})
241241
* :train2: [Deploy request](${DEPLOY_REQUEST_URL})
242242

@@ -447,7 +447,7 @@ jobs:
447447
working-directory: ${{env.pscale_base_directory}}/cli-helper-scripts/
448448
run: |
449449
mkdir -p ../env/
450-
envsubst < ps-env-template.sh > ../env/ps-env-${BRANCH_NAME}.sh
450+
envsubst < ps-env-template.sh > ../env/ps-env-${REF}.sh
451451
chmod a+x ../env/ps-env-${REF}.sh
452452
453453
- name: Commit changes
@@ -1092,3 +1092,220 @@ jobs:
10921092
comment_id: ${{github.event.comment.id}},
10931093
reaction_id: ${{needs.prechecks.outputs.eyes}}
10941094
})
1095+
1096+
act-on-ps-attach-request:
1097+
name: "/ps-attach - click here ..."
1098+
if: startsWith(github.event.comment.body, '/ps-attach')
1099+
needs: [prechecks]
1100+
runs-on: ubuntu-latest
1101+
steps:
1102+
- name: Validating command and associated PS env
1103+
id: validate_params
1104+
env:
1105+
REF: ${{ needs.prechecks.outputs.ref }}
1106+
comment: ${{ github.event.comment.body }}
1107+
baseDirectory: ${{env.pscale_base_directory}}
1108+
uses: actions/github-script@v3
1109+
with:
1110+
github-token: ${{ secrets.GITHUB_TOKEN }}
1111+
script: |
1112+
const { REF, comment, baseDirectory } = process.env;
1113+
deployRequestURL = orgName = dbName = branchName = deployRequestNumber = attachedEntity = "";
1114+
1115+
// check if comment starts with '/ps-attach' and is followed by a PlanetScale deployment URL in the form of 'https://app.planetscale.com/organization/database/deploy-requests/deployrequest-id'
1116+
// extract the deploy request number, and the organization name and database name from the URL
1117+
const regexpDeployRequest = /\/ps-attach\s+(https:\/\/app\.planetscale\.com\/([^\/]+)\/([^\/]+)\/deploy-requests\/([0-9]+))/;
1118+
1119+
// check if comment starts with '/ps-attach' and is followed by a PlanetScale branch URL in the form of 'https://app.planetscale.com/organization/database/branch-name'
1120+
const regexpBranch = /\/ps-attach\s+(https:\/\/app\.planetscale\.com\/([^\/]+)\/([^\/]+)\/([^\/]+))/;
1121+
1122+
// test comment with regexp for deploy request
1123+
if (regexpDeployRequest.test(comment)) {
1124+
const match = comment.match(regexpDeployRequest);
1125+
[, deployRequestURL, orgName, dbName, deployRequestNumber] = match;
1126+
attachedEntity = "deploy request ___" + deployRequestURL + "___";
1127+
} else if (regexpBranch.test(comment)) {
1128+
const match = comment.match(regexpBranch);
1129+
[, branchURL, orgName, dbName, branchName] = match;
1130+
attachedEntity = "DB branch ___" + branchName + "___";
1131+
} else {
1132+
message = `Invalid command. Please use the following format: \`/ps-attach https://app.planetscale.com/organization/database/deploy-requests/deployrequest-number\` or \`/ps-attach https://app.planetscale.com/organization/database/branch-name\``
1133+
core.setOutput('error', message);
1134+
throw new Error(message);
1135+
}
1136+
1137+
core.setOutput('DEPLOY_REQUEST_URL', deployRequestURL);
1138+
core.setOutput('ORG_NAME', orgName);
1139+
core.setOutput('DB_NAME', dbName);
1140+
core.setOutput('DEPLOY_REQUEST_NUMBER', deployRequestNumber);
1141+
core.setOutput('BRANCH_NAME', branchName);
1142+
1143+
const ps_env_name = baseDirectory + '/env/ps-env-' + REF + ".sh"
1144+
// check whether file ps_env_name exists in the repo and given ref
1145+
try {
1146+
const response = await github.repos.getContent({
1147+
...context.repo,
1148+
path: ps_env_name,
1149+
ref: REF
1150+
})
1151+
if (response.data.content) {
1152+
message = 'Script \`' + ps_env_name + '\` already exists, please use \`/ps-update "<DDL>"\` to update existing env.'
1153+
core.setOutput('error', message)
1154+
throw new Error(message)
1155+
}
1156+
} catch (error) {
1157+
// check error code and rethrow if not 404
1158+
if (error.status !== 404) {
1159+
throw error
1160+
}
1161+
}
1162+
1163+
const log_url = `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`
1164+
1165+
const commentBody = `\
1166+
👋 __${context.actor}__, attaching ${attachedEntity} to Git branch __${REF}__ now ...
1167+
1168+
You can watch the progress and authorize access [here](${log_url}).
1169+
`;
1170+
1171+
await github.issues.createComment({
1172+
...context.repo,
1173+
issue_number: context.issue.number,
1174+
body: commentBody
1175+
})
1176+
1177+
- name: Checkout
1178+
uses: actions/checkout@v2
1179+
with:
1180+
ref: ${{ needs.prechecks.outputs.ref }}
1181+
1182+
- name: Retrieve info on attached PS objects - if asked, please click on displayed link to authenticate
1183+
id: retrieve-attached-info
1184+
timeout-minutes: 3
1185+
env:
1186+
REF: ${{needs.prechecks.outputs.ref}}
1187+
PLANETSCALE_SERVICE_TOKEN_NAME: ${{secrets.PLANETSCALE_SERVICE_TOKEN_NAME}}
1188+
PLANETSCALE_SERVICE_TOKEN: ${{secrets.PLANETSCALE_SERVICE_TOKEN}}
1189+
DB_NAME: ${{steps.validate_params.outputs.DB_NAME}}
1190+
ORG_NAME: ${{steps.validate_params.outputs.ORG_NAME}}
1191+
DEPLOY_REQUEST_URL: ${{steps.validate_params.outputs.DEPLOY_REQUEST_URL}}
1192+
DEPLOY_REQUEST_NUMBER: ${{steps.validate_params.outputs.DEPLOY_REQUEST_NUMBER}}
1193+
BRANCH_NAME: ${{steps.validate_params.outputs.BRANCH_NAME}}
1194+
working-directory: ${{env.pscale_base_directory}}/cli-helper-scripts/
1195+
run: |
1196+
if [ -z "$DEPLOY_REQUEST_NUMBER" ]; then
1197+
./retrieve-branch-info.sh "$DB_NAME" "$ORG_NAME" "$BRANCH_NAME"
1198+
else
1199+
./retrieve-deploy-request-info.sh "$DB_NAME" "$ORG_NAME" "$DEPLOY_REQUEST_NUMBER"
1200+
fi
1201+
1202+
- name: Write information about associated PS database entities
1203+
env:
1204+
REF: ${{ needs.prechecks.outputs.ref }}
1205+
BRANCH_NAME: ${{ steps.retrieve-attached-info.outputs.BRANCH_NAME }}
1206+
DB_NAME: ${{ steps.retrieve-attached-info.outputs.DB_NAME }}
1207+
ORG_NAME: ${{ steps.retrieve-attached-info.outputs.ORG_NAME }}
1208+
DEPLOY_REQUEST_NUMBER: ${{ steps.retrieve-attached-info.outputs.DEPLOY_REQUEST_NUMBER }}
1209+
DEPLOY_REQUEST_URL: ${{ steps.retrieve-attached-info.outputs.DEPLOY_REQUEST_URL }}
1210+
BRANCH_URL: ${{ steps.retrieve-attached-info.outputs.BRANCH_URL }}
1211+
working-directory: ${{env.pscale_base_directory}}/cli-helper-scripts/
1212+
run: |
1213+
mkdir -p ../env/
1214+
envsubst < ps-env-template.sh > ../env/ps-env-${REF}.sh
1215+
chmod a+x ../env/ps-env-${REF}.sh
1216+
1217+
- name: Commit changes
1218+
uses: elstudio/actions-js-build/commit@v4
1219+
with:
1220+
commitMessage: Attach PS environment to branch ${{ steps.retrieve-attached-info.outputs.BRANCH_NAME }}
1221+
1222+
- name: PS Attach Deploy Request succeeded
1223+
id: ps-attach-succeeded
1224+
if: success()
1225+
uses: actions/github-script@v3
1226+
env:
1227+
DEPLOY_REQUEST_URL: ${{ steps.retrieve-attached-info.outputs.DEPLOY_REQUEST_URL }}
1228+
BRANCH_NAME: ${{ steps.retrieve-attached-info.outputs.BRANCH_NAME }}
1229+
BRANCH_URL: ${{ steps.retrieve-attached-info.outputs.BRANCH_URL }}
1230+
DB_NAME: ${{ steps.retrieve-attached-info.outputs.DB_NAME }}
1231+
ORG_NAME: ${{ steps.retrieve-attached-info.ORG_NAME }}
1232+
BRANCH_DIFF: ${{ steps.retrieve-attached-info.outputs.BRANCH_DIFF }}
1233+
with:
1234+
github-token: ${{ secrets.GITHUB_TOKEN }}
1235+
script: |
1236+
const { DEPLOY_REQUEST_URL, BRANCH_NAME, BRANCH_URL, DB_NAME, ORG_NAME, BRANCH_DIFF } = process.env;
1237+
const log_url = `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`
1238+
1239+
const commentBody = `\
1240+
### Deploy request and DB branch attached successfully :tada:
1241+
1242+
* :seedling: __DB-Branch__: [${BRANCH_NAME}](${BRANCH_URL})
1243+
* :train2: [Deploy request](${DEPLOY_REQUEST_URL})
1244+
* :lock: __Branch connection info__: [One-time link](${{ steps.retrieve-attached-info.outputs.CONNECTION_STRING_LINK }})
1245+
1246+
<details>
1247+
<summary>📖 Calculated schema changes:</summary>
1248+
1249+
\`\`\`
1250+
${BRANCH_DIFF}
1251+
\`\`\`
1252+
1253+
</details>
1254+
1255+
`;
1256+
1257+
github.issues.createComment({
1258+
...context.repo,
1259+
issue_number: ${{ github.event.issue.number }},
1260+
body: commentBody
1261+
});
1262+
1263+
await github.reactions.createForIssueComment({
1264+
...context.repo,
1265+
comment_id: ${{github.event.comment.id}},
1266+
content: '+1'
1267+
})
1268+
1269+
await github.reactions.deleteForIssueComment({
1270+
...context.repo,
1271+
comment_id: ${{github.event.comment.id}},
1272+
reaction_id: ${{needs.prechecks.outputs.eyes}}
1273+
})
1274+
1275+
- name: /ps-attach failed
1276+
id: ps-attach-failed
1277+
if: cancelled() || failure()
1278+
uses: actions/github-script@v3
1279+
env:
1280+
REF: ${{ needs.prechecks.outputs.ref }}
1281+
message: ${{steps.validate_params.outputs.error}}
1282+
with:
1283+
github-token: ${{ secrets.GITHUB_TOKEN }}
1284+
script: |
1285+
const { REF, message } = process.env;
1286+
const log_url = `${process.env.GITHUB_SERVER_URL}/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`
1287+
1288+
if (message === null || message === '') {
1289+
errorMessage = `Ataching DR/DB branch failed for branch __${REF}__ :cry:. [View error logs](${log_url}).`
1290+
} else {
1291+
errorMessage = message
1292+
}
1293+
1294+
github.issues.createComment({
1295+
...context.repo,
1296+
issue_number: ${{ github.event.issue.number }},
1297+
body: errorMessage
1298+
})
1299+
1300+
1301+
await github.reactions.createForIssueComment({
1302+
...context.repo,
1303+
comment_id: ${{github.event.comment.id}},
1304+
content: '-1'
1305+
})
1306+
1307+
await github.reactions.deleteForIssueComment({
1308+
...context.repo,
1309+
comment_id: ${{github.event.comment.id}},
1310+
reaction_id: ${{needs.prechecks.outputs.eyes}}
1311+
})

.pscale/cli-helper-scripts/ps-create-helper-functions.sh

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,12 @@ function create-deploy-request {
5757
echo "Deploy request could not be created: $raw_output"
5858
exit 1
5959
fi
60-
deploy_request_number=`echo $raw_output | jq -r '.number'`
60+
local deploy_request_number=`echo $raw_output | jq -r '.number'`
61+
# if deploy request number is empty, then error
62+
if [ -z "$deploy_request_number" ]; then
63+
echo "Could not retrieve deploy request number: $raw_output"
64+
exit 1
65+
fi
6166

6267
local deploy_request="https://app.planetscale.com/${ORG_NAME}/${DB_NAME}/deploy-requests/${deploy_request_number}"
6368
echo "Check out the deploy request created at $deploy_request"
@@ -69,6 +74,75 @@ function create-deploy-request {
6974
fi
7075
}
7176

77+
function create-deploy-request-info {
78+
local DB_NAME=$1
79+
local ORG_NAME=$2
80+
local DEPLOY_REQUEST_NUMBER=$3
81+
82+
local raw_output=`pscale deploy-request show "$DB_NAME" "$DEPLOY_REQUEST_NUMBER" --org "$ORG_NAME" --format json`
83+
if [ $? -ne 0 ]; then
84+
echo "Deploy request could not be retrieved: $raw_output"
85+
exit 1
86+
fi
87+
# extract the branch name from the deploy request
88+
local branch_name=`echo $raw_output | jq -r '.branch'`
89+
90+
# check if the branch name is empty
91+
if [ -z "$branch_name" ]; then
92+
echo "Could not extract branch name from deploy request $DEPLOY_REQUEST_NUMBER"
93+
exit 1
94+
fi
95+
96+
export BRANCH_NAME="$branch_name"
97+
local deploy_request="https://app.planetscale.com/${ORG_NAME}/${DB_NAME}/deploy-requests/${DEPLOY_REQUEST_NUMBER}"
98+
99+
local branch_url="https://app.planetscale.com/${ORG_NAME}/${DB_NAME}/${BRANCH_NAME}"
100+
export BRANCH_URL="$branch_url"
101+
102+
# if CI variable is set, export deployment request info
103+
if [ -n "$CI" ]; then
104+
echo "::set-output name=BRANCH_NAME::$branch_name"
105+
echo "::set-output name=DB_NAME::$DB_NAME"
106+
echo "::set-output name=ORG_NAME::$ORG_NAME"
107+
echo "::set-output name=DEPLOY_REQUEST_URL::$deploy_request"
108+
echo "::set-output name=DEPLOY_REQUEST_NUMBER::$DEPLOY_REQUEST_NUMBER"
109+
echo "::set-output name=BRANCH_URL::$branch_url"
110+
fi
111+
}
112+
113+
function create-branch-info {
114+
local DB_NAME=$1
115+
local BRANCH_NAME=$2
116+
local ORG_NAME=$3
117+
118+
local raw_output=`pscale branch show "$DB_NAME" "$BRANCH_NAME" --org "$ORG_NAME" --format json`
119+
if [ $? -ne 0 ]; then
120+
echo "Branch could not be retrieved: $raw_output"
121+
exit 1
122+
fi
123+
# extract the branch name from the deploy request
124+
local branch_name=`echo $raw_output | jq -r '.name'`
125+
126+
# check if the branch name is empty
127+
if [ -z "$branch_name" ]; then
128+
echo "Could not extract existing branch name from branch $BRANCH_NAME"
129+
exit 1
130+
fi
131+
132+
export BRANCH_NAME="$branch_name"
133+
134+
local branch_url="https://app.planetscale.com/${ORG_NAME}/${DB_NAME}/${BRANCH_NAME}"
135+
export BRANCH_URL="$branch_url"
136+
137+
# if CI variable is set, export branch info
138+
if [ -n "$CI" ]; then
139+
echo "::set-output name=BRANCH_NAME::$branch_name"
140+
echo "::set-output name=DB_NAME::$DB_NAME"
141+
echo "::set-output name=ORG_NAME::$ORG_NAME"
142+
echo "::set-output name=BRANCH_URL::$branch_url"
143+
fi
144+
}
145+
72146
function create-diff-for-ci {
73147
local DB_NAME=$1
74148
local ORG_NAME=$2
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
. use-pscale-docker-image.sh
4+
5+
. authenticate-ps.sh
6+
7+
DB_NAME="$1"
8+
ORG_NAME="$2"
9+
BRANCH_NAME="$3"
10+
11+
. ps-create-helper-functions.sh
12+
create-branch-info "$DB_NAME" "$BRANCH_NAME" "$ORG_NAME"
13+
create-deploy-request "$DB_NAME" "$BRANCH_NAME" "$ORG_NAME"
14+
15+
. create-branch-connection-string.sh
16+
create-branch-connection-string "$DB_NAME" "$BRANCH_NAME" "$ORG_NAME" "creds-${BRANCH_NAME}" "sharesecret"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
3+
. use-pscale-docker-image.sh
4+
5+
. authenticate-ps.sh
6+
7+
DB_NAME="$1"
8+
ORG_NAME="$2"
9+
DEPLOY_REQUEST_NUMBER="$3"
10+
11+
. ps-create-helper-functions.sh
12+
create-deploy-request-info "$DB_NAME" "$ORG_NAME" "$DEPLOY_REQUEST_NUMBER"
13+
14+
create-diff-for-ci "$DB_NAME" "$ORG_NAME" "$DEPLOY_REQUEST_NUMBER" "$BRANCH_NAME" "update"
15+
16+
. create-branch-connection-string.sh
17+
create-branch-connection-string "$DB_NAME" "$BRANCH_NAME" "$ORG_NAME" "creds-${BRANCH_NAME}" "sharesecret"

0 commit comments

Comments
 (0)