Published: Mar 3, 2023 by Isaac Johnson
Earlier this week, we covered updating Azure DevOps webhook triggered pipelines to update Azure Work Items and create a Github Issue. The goal was to update our flows to start to use Github Issues over AzDO. Today, we’ll continue this journey as we focus on moving into Github Actions. We’ll use OIDC to auth to AKV for some secrets and learn how to parse out the GH JSON results to share the new Issue ID.
Lastly, we’ll tackle feedback forms including adding Authentication headers and wrap with creating and using a new Slack App to update a Slack channel.
The repos used below, if you wish to follow along:
Github Action creation
First, I’ll create a new GH Repo for this work
Next, I’ll clone and create a new workflow file
on:
repository_dispatch:
types: [on-demand-test]
jobs:
run_if_payload:
if: ${{ github.event }}
runs-on: ubuntu-latest
steps:
- run: |
set -x
export
- env:
MESSAGE: ${{ github.event.message }}
run: echo $MESSAGE
run_if_failure:
if: ${{ !github.event }}
runs-on: ubuntu-latest
steps:
- run: |
set -x
export
- env:
MESSAGE: ${{ github.event.client_payload.message }}
run: echo $MESSAGE
Unlike AzDO, we cannot invoke a Github webhook anonymously. It requires a Github PAT. That said, we can use the newer Narrowly Scoped PATs to reduce the abilities to the bare minimum.
There was no documentation on what it actually took to invoke a Webhook. I did many many trial-and-errors to get to the final set of permissions. Most came back with a with a response of:
$ curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer github_pat_asdfsadfasdfasdfasdsadf" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/idjohnson/workflowTriggerTest/dispatches -d '{"event_type":"on-demand-payload","client_payload":{"summary":"this is the summary","description":"this is the descriptionn"}}'
{
"message": "Resource not accessible by personal access token",
"documentation_url": "https://docs.github.com/rest/reference/repos#create-a-repository-dispatch-event"
}
to get there.
However, I narrowed it down to the following:
A fine-grained token limited to just the one repository
And then only two permissions are required:
- Contents: Read and write
- Metadata: Read-only
Now when I invoke the Webhook
$ curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer 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" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/idjohnson/workflowTriggerTest/dispatches -d '{"event_type":"on-demand-payload","client_payload":{"summary":"this is the summary","description":"this is the descriptionn"}}'
I can see the messages passed forward
Webform
Our next step is to move this out of Curl and use a webform
I needed to create a feedback form, I named src/feedback2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/styles.css">
<title>Form to API</title>
</head>
<body>
<div class="container card card-color">
<form action="" id="sampleForm">
<h2>Create a feedback task</h2>
<div class="form-row">
<label for="userId">Email Address</label>
<input type="email" class="input-text input-text-block w-100" id="userId" name="userId" value="anonymous@dontemailme.com">
</div>
<div class="form-row">
<label for="summary">Summary</label>
<input type="text" class="input-text input-text-block w-100" id="summary" name="summary">
</div>
<div class="form-row">
<label for="description">Description or Details</label>
<textarea class="input-text input-text-block ta-100" id="description" name="description"></textarea>
</div>
<div class="form-row mx-auto">
<button type="submit" class="btn-submit" id="btnSubmit">
Submit
</button>
</div>
</form>
</div>
<script src="js/app.js"></script>
</body>
</html>
My src/js/app.js had a slew of changes.
async function submitForm(e, form) {
// 1. Prevent reloading page
e.preventDefault();
// 2. Submit the form
// 2.1 User Interaction
const btnSubmit = document.getElementById('btnSubmit');
btnSubmit.disabled = true;
setTimeout(() => btnSubmit.disabled = false, 2000);
// 2.2 Build JSON body
const jsonFormData = buildJsonFormData(form);
// 2.3 Build Headers
const headers = buildHeaders();
// 2.4 Request & Response
const response = await fetchService.performPostHttpRequest(`https://api.github.com/repos/idjohnson/workflowTriggerTest/dispatches`, headers, jsonFormData); // Uses JSON Placeholder
console.log(response);
// 2.5 Inform user of result
if(response)
window.location = `/success.html`;
else
alert(`An error occured.`);
}
function buildHeaders() {
const headers = {
"Content-Type": "application/vnd.github+json",
"Authorization": "Bearer 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"
};
return headers;
}
function buildJsonFormData(form) {
const jsonRetData = { "event_type": "on-demand-payload" };
const jsonFormData = { };
for(const pair of new FormData(form)) {
jsonFormData[pair[0]] = pair[1];
}
jsonRetData.client_payload = jsonFormData;
console.log(jsonRetData);
return jsonRetData;
}
/*--/Functions--*/
/*--Event Listeners--*/
const sampleForm = document.querySelector("#sampleForm");
if(sampleForm) {
sampleForm.addEventListener("submit", function(e) {
submitForm(e, this);
});
}
The key areas I needed to change:
- the URL in fetchService.performPostHttpRequest.
- I removed the fields in success.html
- buildHeaders function removed auth set to null, added the bearer token (with low privs) and set the Content type.
- buildJsonFormData actually took me a bit to figure out - but I wanted to dynamically set the nested “client_payload” sub array.
Then src/js/service/fetchService.js stubbed out the json parsing on the response in performPostHttpRequest
async performPostHttpRequest(fetchLink, headers, body) {
if(!fetchLink || !headers || !body) {
throw new Error("One or more POST request parameters was not passed.");
}
try {
const rawResponse = await fetch(fetchLink, {
method: "POST",
headers: headers,
body: JSON.stringify(body)
});
console.log(rawResponse);
// Webhooks are not JSON
// const content = await rawResponse.json();
//return content;
return rawResponse;
}
catch(err) {
console.error(`Error at fetch POST: ${err}`);
throw err;
}
}
My last step was to just make sure scripts/dev in package.json served up the new HTML (feedback2.html)
"scripts": {
"dev": "npm run clean && parcel src/index.html --out-dir dev feedback2.html",
I finally got a successful result by running in dev
builder@DESKTOP-QADGF36:~/Workspaces/submitformtojsonapi$ npm run dev
> submittingformstoapis@1.0.0 dev /home/builder/Workspaces/submitformtojsonapi
> npm run clean && parcel src/index.html --out-dir dev feedback2.html
> submittingformstoapis@1.0.0 clean /home/builder/Workspaces/submitformtojsonapi
> rimraf ./dev && rimraf -rf ./.cache
Server running at http://localhost:1234
⠹ Building app.js...Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
⠸ Building app.js...Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
⠴ Building runtime.js...Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
✨ Built in 1.13s.
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
✨ Built in 57ms.
And testing the form:
This fired a build
to which I could see results
At this point, the pipeline is fairly “hello world”. All it really does is print back the elements as passed
on:
repository_dispatch:
types: [on-demand-payload]
jobs:
run_if_payload:
if: $
runs-on: ubuntu-latest
steps:
- run: |
set -x
export
- env:
MESSAGE: $
run: echo $MESSAGE
- env:
MESSAGE: $
run: echo $MESSAGE
Clearly to have some fun adding more Issues, triggering Slack and Discord, and sending emails, we’re going to need to save aside some secrets
Sticking with an ephemeral pipeline, this is a great excuse to try out what we went over last week on OIDC.
I’ll head to the Azure Portal and go to App Registrations:
and I’ll add a credential
Then select Github Actions creating Azure Resources
Then we’ll add our WorkflowTest repo and branch
We’ll now test
- name: 'Az CLI login'
uses: azure/login@v1
with:
client-id: '$'
tenant-id: '$'
subscription-id: '$'
- name: 'Run az commands'
run: |
az account show
az group list
I’ll set those variables as new Github Actions secrets
The first time testing, I got an error
Using OIDC authentication...
Error: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable. Please make sure to give write permissions to id-token in the workflow.
I needed to add at the top
permissions:
id-token: write
contents: read
which unblocked and let the action run without issue.
In our last writeup, we added an access policy to an AKV for that App Registration
- name: 'Check AKV'
run: |
az keyvault secret list --vault wldemokv -o table
We can add a secret for a GH Token (or put into AKV) then build out a new GH Action that replicates what we did last time in an Azure Pipeline
on:
repository_dispatch:
types: [on-demand-payload]
permissions:
id-token: write
contents: read
jobs:
run_if_payload:
if: $
runs-on: ubuntu-latest
steps:
- run: |
set -x
export
- env:
MESSAGE: $
run: echo $MESSAGE
- env:
MESSAGE: $
run: echo $MESSAGE
- name: 'Az CLI login'
uses: azure/login@v1
with:
client-id: '$'
tenant-id: '$'
subscription-id: '$'
- name: 'Run az commands'
run: |
az account show
az group list
- name: 'Check AKV'
run: |
az keyvault secret show --vault-name wldemokv --name sessmtppass -o json | jq -r .value > sessmtppass
az keyvault secret show --vault-name wldemokv --name sessmtpuser -o json | jq -r .value > sessmtpuser
sudo apt-get update
sudo apt-get install -y s-nail || true
cat >rawDescription <<EOOOOL
$
EOOOOL
cat >rawSummary <<EOOOOT
$
EOOOOT
set -x
cat rawSummary |sed ':a;N;$!ba;s/\n/ /g' | sed 's/"/\\"/g' > emailSummary
data="$( jq -nc --arg title "$" --arg body "$ :: Requested by $" '$ARGS.named')"
cat >emailJson2.json <<EOTT
$data
EOTT
curl -X POST -H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/idjohnson/jekyll-blog/issues -d @emailJson2.json > gh.o.json
export USERTLD=`echo "$" | sed 's/^.*@//'`
export GHURL=`cat gh.o.json | jq -r .html_url`
# Now Send Email
if [[ "$USERTLD" == "dontemailme.com" ]]; then
# do not CC user
echo "<h1>New Feature Requested</h1><p>user $ has requested "`cat emailSummary`"</p><p>$GHURL</p><br/><br/>Kind Regards,<br/>Isaac Johnson" | s-nail -s "Blog: Feature $WIID Requested" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c isaac.johnson@gmail.com -r isaac@freshbrewed.science isaac.johnson@gmail.com
else
# may not work
echo "<h1>New Feature Requested</h1><p>user $ has requested "`cat emailSummary`"</p><p>$GHURL</p><br/><br/>Kind Regards,<br/>Isaac Johnson" | s-nail -s "Blog: Feature $WIID Requested" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c $ -r isaac@freshbrewed.science isaac.johnson@gmail.com
fi
run_if_failure:
runs-on: ubuntu-latest
needs: run_if_payload
if: always() && (needs.run_if_payload.result == 'failure')
steps:
- run: |
az keyvault secret show --vault-name wldemokv --name sessmtppass -o json | jq -r .value > sessmtppass
az keyvault secret show --vault-name wldemokv --name sessmtpuser -o json | jq -r .value > sessmtpuser
sudo apt-get update
sudo apt-get install -y s-nail || true
export USERTLD=`echo "$" | sed 's/^.*@//'`
echo "<h1>New Feature Requested</h1><p>user $ but the formatting must have failed. Please check the pipeline!" | s-nail -s "Blog: Feature Requested (FAIL processing)" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c isaac.johnson@gmail.com -r isaac@freshbrewed.science isaac.johnson@gmail.com
- env:
MESSAGE: $
run: echo $MESSAGE
Let’s now give that a test. First, locally
$ curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer 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" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/idjohnson/workflowTriggerTest/dispatches -d '{"event_type":"on-demand-payload","client_payload":{"summary":"Github Actions","description":"Let'\''s Do more Github Actions","userid":"isa
ac.johnson@gmail.com"}}'
which triggers the pipeline
creates the GH Issue
and sends the email
Slack app
First, we need to Login to Slack in a browser and go to the API endpoint to create a new API app
I’ll give it a name and select a workspace
Next, I need to install to a workspace
I’ll choose “#Builds#
That gets us a Webhook URL
Which I can test with the URL
$ curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/asdfasdfsadf/asdfasdfasdf1/asdfasdfasdfsadf
which I can now see
I’ll add to AKV
Finishing the feedback form.
Since I don’t really want to loose my work so far (as I did before). I’ll fork the original repo to https://github.com/idjohnson/submitformtojsonapi. I’ve left it public so you can follow along.
I propagated the new files
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: package.json
modified: src/css/styles.css
modified: src/index.html
modified: src/js/app.js
modified: src/js/service/FetchService.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/feedback2.html
no changes added to commit (use "git add" and/or "git commit -a")
Then I’ll run install and test dev
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi$ npm install
> deasync@0.1.20 install /home/builder/Workspaces/ijohnson-submitformtojsonapi/node_modules/deasync
> node ./build.js
`linux-x64-node-10` exists; testing
Binary is fine; exiting
> core-js@2.6.11 postinstall /home/builder/Workspaces/ijohnson-submitformtojsonapi/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
> parcel-bundler@1.12.4 postinstall /home/builder/Workspaces/ijohnson-submitformtojsonapi/node_modules/parcel-bundler
> node -e "console.log('\u001b[35m\u001b[1mLove Parcel? You can now donate to our open collective:\u001b[22m\u001b[39m\n > \u001b[34mhttps://opencollective.com/parcel/donate\u001b[0m')"
Love Parcel? You can now donate to our open collective:
> https://opencollective.com/parcel/donate
npm WARN submittingformstoapis@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.13 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
added 768 packages from 463 contributors and audited 770 packages in 10.187s
23 packages are looking for funding
run `npm fund` for details
found 133 vulnerabilities (13 low, 61 moderate, 49 high, 10 critical)
run `npm audit fix` to fix them, or `npm audit` for details
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi$ npm run dev
> submittingformstoapis@1.0.0 dev /home/builder/Workspaces/ijohnson-submitformtojsonapi
> npm run clean && parcel src/index.html --out-dir dev feedback2.html
> submittingformstoapis@1.0.0 clean /home/builder/Workspaces/ijohnson-submitformtojsonapi
> rimraf ./dev && rimraf -rf ./.cache
Server running at http://localhost:35663 - configured port 1234 could not be used.
⠙ Building app.js...Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
⠼ Building runtime.js...Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
✨ Built in 1.12s.
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
And I can see that running
The background colour and fonts aren’t quite right.
I pulled the existing CSS with view-source:https://freshbrewed.science/styles.c9ed72d6.css
then used pretty print to format so I could compare and fix.
That now looks right
I’ll now test before bringing into this repo
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi/dev$ aws s3 cp --recursive --acl public-read-write ./ s3://freshbrewed-test/
upload: ./styles.b61e60ae.css to s3://freshbrewed-test/styles.b61e60ae.css
upload: ./feedback.html to s3://freshbrewed-test/feedback.html
upload: ./styles.b61e60ae.css.map to s3://freshbrewed-test/styles.b61e60ae.css.map
upload: ./styles.b61e60ae.js to s3://freshbrewed-test/styles.b61e60ae.js
upload: ./styles.b61e60ae.js.map to s3://freshbrewed-test/styles.b61e60ae.js.map
upload: ./app.c3f9f951.js.map to s3://freshbrewed-test/app.c3f9f951.js.map
upload: ./app.c3f9f951.js to s3://freshbrewed-test/app.c3f9f951.js
And test
Which worked
And email
I see two last minor issues - I need to fix the GH URL and add the Slack work we did.
The diff looks as
$ git diff
diff --git a/.github/workflows/triggerTest.yml b/.github/workflows/triggerTest.yml
index 9e4c482..1cb065a 100644
--- a/.github/workflows/triggerTest.yml
+++ b/.github/workflows/triggerTest.yml
@@ -61,7 +61,15 @@ jobs:
export USERTLD=`echo "$" | sed 's/^.*@//'`
- export GHURL=`cat gh.o.json | jq -r .url`
+ export GHURL=`cat gh.o.json | jq -r .html_url`
+
+ # Slack Notification
+ slackdata="$( jq -nc --arg text "Feature Request $GHURL: $ Requested by $" '$ARGS.named')"
+ cat >slackjson.json <<EOTT
+ $slackdata
+ EOTT
+
+ curl -X POST -H 'Content-type: application/json' `az keyvault secret show --vault-name wldemokv --name slackbuildswh -o json | jq -r .value | tr -d '\n'` -d @slackjson.json
# Now Send Email
if [[ "$USERTLD" == "dontemailme.com" ]]; then
@@ -71,10 +79,6 @@ jobs:
# may not work
echo "<h1>New Feature Requested</h1><p>user $ has requested "`cat emailSummary`"</p><p>$GHURL</p><br/><br/>Kind Regards,<br/>Isaac Johnson" | s-nail -s "Blog: Feature $WIID Requested" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c $ -r isaac@freshbrewed.science isaac.johnson@gmail.com
fi
-
- az keyvault secret show --vault-name wldemokv --name slackbuildswh -o json | jq -r .value > slackbuildswh
-
-
run_if_failure:
runs-on: ubuntu-latest
@@ -89,7 +93,15 @@ jobs:
sudo apt-get install -y s-nail || true
export USERTLD=`echo "$" | sed 's/^.*@//'`
- echo "<h1>New Feature Requested</h1><p>user $ but the formatting must have failed. Please check the pipeline!" | s-nail -s "Blog: Feature Requested (FAIL processing)" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c isaac.johnson@gmail.com -r isaac@freshbrewed.science isaac.johnson@gmail.com
+ echo "<h1>New Feature Requested</h1><p>user $ but the formatting must have failed. Please check the pipeline: Run ID $GITHUB_RUN_ID!" | s-nail -s "Blog: Feature Requested (FAIL processing)" -M "text/html" -S smtp=email-smtp.us-east-1.amazonaws.com:587 -S smtp-use-starttls -S ssl-verify=ignore -S smtp-auth=login -S smtp-auth-user=`cat sessmtpuser` -S smtp-auth-password=`cat sessmtppass` -c isaac.johnson@gmail.com -r isaac@freshbrewed.science isaac.johnson@gmail.com
+
+ # Slack Notification
+ slackdata="$( jq -nc --arg text "Feature Request Issue Create Failure: see $GITHUB_JOB on Run $GITHUB_RUN_ID :: requested by $" '$ARGS.named')"
+ cat >slackjson.json <<EOTT
+ $slackdata
+ EOTT
+
+ curl -X POST -H 'Content-type: application/json' `az keyvault secret show --vault-name wldemokv --name slackbuildswh -o json | jq -r .value | tr -d '\n'` -d @slackjson.json
- env:
MESSAGE: $
run: echo $MESSAGE
The key things was fixing the URL to ‘.html_url’ from the GH payload and adding Slack notifications. I also noted the failed run ID should it fail.
I’ll use a more complicated test this time
I can now see that worked in Slack
In email
and as a Github Issue
Feedback Form and Tokens
Tokens have expirations. As it stands, if I do nothing my feedback form will stop working in less than 90 days.
And any updates necessarily create new tokens (which mean new builds of the static form)
At best I can generate one a Year out. I did that but then noted the Expiry in AKV
I did an update and then rebuilt and pushed, including to Production (after I tested)
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi/dev$ mv index.html feedback.html
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi/dev$ aws s3 cp --recursive --acl public-read-write ./ s3://freshbrewed-test/
upload: ./styles.b61e60ae.css.map to s3://freshbrewed-test/styles.b61e60ae.css.map
upload: ./feedback.html to s3://freshbrewed-test/feedback.html
upload: ./styles.b61e60ae.css to s3://freshbrewed-test/styles.b61e60ae.css
upload: ./styles.b61e60ae.js.map to s3://freshbrewed-test/styles.b61e60ae.js.map
upload: ./app.c3f9f951.js.map to s3://freshbrewed-test/app.c3f9f951.js.map
upload: ./styles.b61e60ae.js to s3://freshbrewed-test/styles.b61e60ae.js
upload: ./app.c3f9f951.js to s3://freshbrewed-test/app.c3f9f951.js
builder@DESKTOP-QADGF36:~/Workspaces/ijohnson-submitformtojsonapi/dev$ aws s3 cp --recursive --acl public-read-write ./ s3://freshbrewed.science/
upload: ./styles.b61e60ae.css.map to s3://freshbrewed.science/styles.b61e60ae.css.map
upload: ./styles.b61e60ae.js to s3://freshbrewed.science/styles.b61e60ae.js
upload: ./styles.b61e60ae.css to s3://freshbrewed.science/styles.b61e60ae.css
upload: ./feedback.html to s3://freshbrewed.science/feedback.html
upload: ./styles.b61e60ae.js.map to s3://freshbrewed.science/styles.b61e60ae.js.map
upload: ./app.c3f9f951.js to s3://freshbrewed.science/app.c3f9f951.js
upload: ./app.c3f9f951.js.map to s3://freshbrewed.science/app.c3f9f951.js.map
Lastly, I’ll delete the old token so any exposed GHP token here has been expired
Summary
In this entry we tackled a lot - we covered moving from the Azure DevOps workflow into a new Github Action in a new GH Repo. We covered secrets on the repo as well as federated access to Azure Key Vault shared secrets via OIDC using a new repo+branch endpoint.
Next, we tackled setting up Slack using the App workflow and creating the HTML static form to Post to our payload. This included handling additional authentication headers (which the anonymous endpoints of Azure DevOps let us avoid prior).
I had to put a pin in the next steps; I want to add back Teams integration and add Hosted JIRA as well since a lot of folks out there use the Atlassian suites.
One limitation here is that I necessarily had to expose my Github Token on a specific repo. Ideally, I would abstract that somehow - by either triggering a lambda that would re-wrap the contents and pass them forward or coming up with another trigger. However, IF I had to move to a new serverless “runner”, then I likely wouldn’t two-step - I would just write the logic up as an Azure Function, AWS Lambda or a GCP Cloud Function. That is, there would be no need to keep a Github flow if I already have a place to do work.