Skip to content

Commit f293fdf

Browse files
Merge branch 'master' into feature/prism-changes-node
2 parents 613ada1 + 9936159 commit f293fdf

File tree

5 files changed

+312
-6
lines changed

5 files changed

+312
-6
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: slack-alert-action
2+
description: "Action to send slack payload to public-sdk-events channel"
3+
4+
inputs:
5+
heading_text:
6+
required: true
7+
description: "Heading of the slack payload"
8+
alert_type:
9+
required: true
10+
description: "type of the slack alert"
11+
job_status:
12+
required: true
13+
description: "status of the job"
14+
XERO_SLACK_WEBHOOK_URL:
15+
required: true
16+
description: "webhook url for channel - public-sdk-events"
17+
job_url:
18+
required: true
19+
description: "job run id link"
20+
button_type:
21+
required: true
22+
description: "color for the check logs button"
23+
package_version:
24+
required: true
25+
description: "released package version"
26+
repo_link:
27+
required: true
28+
description: "link of the repo"
29+
30+
31+
runs:
32+
using: "composite"
33+
34+
steps:
35+
36+
- name: Send slack notification
37+
id: slack
38+
uses: slackapi/[email protected]
39+
env:
40+
SLACK_WEBHOOK_URL: ${{inputs.XERO_SLACK_WEBHOOK_URL}}
41+
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
42+
with:
43+
payload: |
44+
{
45+
"blocks": [
46+
{
47+
"type": "rich_text",
48+
"elements": [
49+
{
50+
"type": "rich_text_section",
51+
"elements": [
52+
{
53+
"type": "text",
54+
"text": "${{inputs.heading_text}} ",
55+
"style": {
56+
"bold": true
57+
}
58+
},
59+
{
60+
"type": "emoji",
61+
"name": "${{inputs.alert_type}}"
62+
}
63+
]
64+
}
65+
]
66+
},
67+
{
68+
"type": "divider"
69+
},
70+
{
71+
"type": "section",
72+
"fields": [
73+
{
74+
"type": "mrkdwn",
75+
"text": "*Repository:* \n ${{inputs.repo_link}}"
76+
},
77+
{
78+
"type": "mrkdwn",
79+
"text": "*Status:*\n ${{inputs.job_status}}"
80+
},
81+
{
82+
"type": "mrkdwn",
83+
"text": "*Package Version:*\n ${{inputs.package_version}}"
84+
}
85+
]
86+
},
87+
{
88+
"type": "actions",
89+
"elements": [
90+
{
91+
"type": "button",
92+
"text": {
93+
"type": "plain_text",
94+
"text": "Check the logs",
95+
"emoji": true
96+
},
97+
"style": "${{inputs.button_type}}",
98+
"url": "${{inputs.job_url}}"
99+
}
100+
]
101+
}
102+
]
103+
}

.github/octokit/index.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {Octokit} from "@octokit/rest";
2+
import {createAppAuth} from "@octokit/auth-app"
3+
4+
export const getAccessToken = async () => {
5+
6+
const {GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY} = process.env
7+
8+
const octoKitInstance = new Octokit({
9+
authStrategy: createAppAuth,
10+
auth: {
11+
appId: GITHUB_APP_ID,
12+
privateKey: GITHUB_APP_PRIVATE_KEY
13+
}
14+
});
15+
16+
const {data: installations} = await octoKitInstance.rest.apps.listInstallations()
17+
18+
console.log("installations -----", installations);
19+
20+
21+
if(!installations.length) {
22+
throw new Error("No Installations found for this github app")
23+
}
24+
25+
const installationId = installations[0].id;
26+
27+
const installationAccessToken = await octoKitInstance.rest.apps.createInstallationAccessToken({installation_id: installationId})
28+
29+
return installationAccessToken.data.token
30+
}

.github/octokit/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "xero-octokit",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"type": "module",
7+
"scripts": {
8+
"test": "echo \"Error: no test specified\" && exit 1"
9+
},
10+
"author": "",
11+
"license": "ISC",
12+
"dependencies": {
13+
"@octokit/auth-app": "^7.1.1",
14+
"@octokit/rest": "^21.0.2"
15+
}
16+
}

.github/workflows/publish.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
name: Publish & Release SDK
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
cab_id:
6+
description: "CAB id for the change/release"
7+
required: true
8+
type: string
9+
10+
jobs:
11+
publish:
12+
runs-on: ubuntu-latest
13+
environment: prod
14+
outputs:
15+
release_number: ${{steps.get_latest_release_number.outputs.release_tag}}
16+
permissions:
17+
contents: write
18+
pull-requests: write
19+
steps:
20+
- name: Checkout xero-node repo
21+
uses: actions/checkout@v4
22+
with:
23+
repository: XeroAPI/xero-node
24+
path: xero-node
25+
26+
- name: Set up Node environment
27+
uses: actions/setup-node@v4
28+
with:
29+
node-version: 20
30+
cache: 'npm'
31+
cache-dependency-path: '**/package-lock.json'
32+
registry-url: 'https://registry.npmjs.org'
33+
34+
- name: Install dependencies
35+
run: npm ci
36+
working-directory: xero-node
37+
38+
- name: Run Build
39+
run: npm run build
40+
working-directory: xero-node
41+
42+
- name: Fetch Latest release number
43+
id: get_latest_release_number
44+
run: |
45+
latest_version=$(gh release view --json tagName --jq '.tagName')
46+
echo "Latest release version is - $latest_version"
47+
echo "::set-output name=release_tag::$latest_version"
48+
working-directory: xero-node
49+
env:
50+
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
51+
52+
- name: Publish to npm
53+
env:
54+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
55+
run: npm publish
56+
working-directory: xero-node
57+
58+
notify-codegen-repo:
59+
needs: publish
60+
if: always()
61+
runs-on: ubuntu-latest
62+
permissions:
63+
contents: write
64+
pull-requests: write
65+
66+
steps:
67+
- name: Checkout
68+
uses: actions/checkout@v4
69+
with:
70+
repository: XeroAPI/xero-node
71+
path: xero-node
72+
73+
- name: Install octokit dependencies
74+
run: npm i
75+
working-directory: xero-node/.github/octokit
76+
77+
- name: Get github app access token
78+
id: get_access_token
79+
env:
80+
GITHUB_APP_ID: ${{ secrets.XERO_CODEGEN_BOT_APPLICATION_ID }}
81+
GITHUB_APP_PRIVATE_KEY: ${{ secrets.XERO_CODEGEN_BOT_APPLICATION_KEY }}
82+
uses: actions/github-script@v7
83+
with:
84+
result-encoding: string
85+
script: |
86+
const { getAccessToken } = await import('${{ github.workspace }}/xero-node/.github/octokit/index.js')
87+
const token = await getAccessToken()
88+
return token
89+
90+
- name: Notify codegen repo
91+
run: |
92+
curl -X POST -H "Authorization: token ${{ steps.get_access_token.outputs.result }}" \
93+
-H "Accept: application/vnd.github.v3+json" \
94+
-H "Content-Type: application/json" \
95+
https://api.github.com/repos/xero-internal/xeroapi-sdk-codegen/actions/workflows/notify-sdk-publish.yml/dispatches \
96+
-d '{
97+
"ref": "master",
98+
"inputs": {
99+
"commit": "${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}",
100+
"status": "${{needs.publish.result}}",
101+
"deployer": "xero-codegen-bot",
102+
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
103+
"environment": "prod",
104+
"sdk_type": "node",
105+
"cab_key": "${{ github.event.inputs.cab_id }}"
106+
}
107+
}'
108+
109+
notify-slack-on-success:
110+
runs-on: ubuntu-latest
111+
needs: publish
112+
permissions:
113+
contents: read
114+
if: success()
115+
steps:
116+
- name: Checkout xero-node repo
117+
uses: actions/checkout@v4
118+
with:
119+
repository: XeroAPI/xero-node
120+
path: xero-node
121+
122+
- name: Send slack notification on success
123+
uses: ./xero-node/.github/actions/notify-slack
124+
with:
125+
heading_text: "Publish job has succeeded !"
126+
alert_type: "thumbsup"
127+
job_status: "Success"
128+
XERO_SLACK_WEBHOOK_URL: ${{secrets.XERO_SLACK_WEBHOOK_URL}}
129+
job_url: "https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"
130+
button_type: "primary"
131+
package_version: ${{needs.publish.outputs.release_number}}
132+
repo_link: ${{github.server_url}}/${{github.repository}}
133+
134+
notify-slack-on-failure:
135+
runs-on: ubuntu-latest
136+
needs: publish
137+
permissions:
138+
contents: read
139+
if: failure()
140+
steps:
141+
- name: Checkout xero-node repo
142+
uses: actions/checkout@v4
143+
with:
144+
repository: XeroAPI/xero-node
145+
path: xero-node
146+
147+
- name: Send slack notification on failure
148+
uses: ./xero-node/.github/actions/notify-slack
149+
with:
150+
heading_text: "Publish job has failed !"
151+
alert_type: "alert"
152+
job_status: "Failed"
153+
XERO_SLACK_WEBHOOK_URL: ${{secrets.XERO_SLACK_WEBHOOK_URL}}
154+
job_url: "https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"
155+
button_type: "danger"
156+
package_version: ${{needs.publish.outputs.release_number}}
157+
repo_link: ${{github.server_url}}/${{github.repository}}

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ const xero = new XeroClient({
7575
clientId: 'YOUR_CLIENT_ID',
7676
clientSecret: 'YOUR_CLIENT_SECRET',
7777
redirectUris: [`http://localhost:${port}/callback`],
78-
scopes: 'openid profile email accounting.transactions offline_access'.split(" "),
78+
scopes: 'openid profile email accounting.settings accounting.transactions offline_access'.split(" "),
7979
state: 'returnPage=my-sweet-dashboard', // custom params (optional)
8080
httpTimeout: 3000, // ms (optional)
8181
clockTolerance: 10 // seconds (optional)
@@ -113,7 +113,7 @@ It is recommended that you store this token set JSON in a datastore in relation
113113
| access_token: | "xxx.yyy.zzz" | [Bearer token](https://oauth.net/2/jwt/) with a 30 minute expiration required for all API calls |
114114
| expires_in: | 1800 | Time in seconds till the token expires - 1800s is 30m |
115115
| refresh_token: | "XXXXXXX" | Alphanumeric string used to obtain a new Token Set w/ a fresh access_token - 60 day expiry |
116-
| scope: | ["email", "profile", "openid", "accounting.transactions", "offline_access"] | The Xero permissions that are embedded in the `access_token` |
116+
| scope: | ["email", "profile", "openid", "accounting.settings", "accounting.transactions", "offline_access"] | The Xero permissions that are embedded in the `access_token` |
117117
118118
Example Token Set JSON:
119119
```
@@ -123,7 +123,7 @@ Example Token Set JSON:
123123
"expires_in": 1800,
124124
"token_type": "Bearer",
125125
"refresh_token": "xxxxxxxxx",
126-
"scope": ["email", "profile", "openid", "accounting.transactions", "offline_access"]
126+
"scope": ["email", "profile", "openid", "accounting.settings", "accounting.transactions", "offline_access"]
127127
}
128128
```
129129
@@ -233,7 +233,7 @@ const xero = new XeroClient({
233233
clientSecret: 'YOUR_CLIENT_SECRET', // required
234234
redirectUris: [`http://localhost:${port}/callback`], // not used for client_credentials auth flow
235235
grantType: 'client_credentials', // only used for client_credentials auth flow
236-
scopes: 'openid profile email accounting.transactions offline_access'.split(" "), // not used for client_credentials auth flow
236+
scopes: 'openid profile email accounting.settings accounting.transactions offline_access'.split(" "), // not used for client_credentials auth flow
237237
state: 'returnPage=my-sweet-dashboard', // custom params (optional), not used for client_credentials auth flow
238238
httpTimeout: 3000, // ms (optional)
239239
clockTolerance: 10 // seconds (optional)
@@ -261,7 +261,7 @@ const xero = new XeroClient({
261261
clientId: 'YOUR_CLIENT_ID',
262262
clientSecret: 'YOUR_CLIENT_SECRET',
263263
redirectUris: [`http://localhost:${port}/callback`],
264-
scopes: 'openid profile email accounting.transactions offline_access'.split(" ")
264+
scopes: 'openid profile email accounting.settings accounting.transactions offline_access'.split(" ")
265265
});
266266

267267
await xero.initialize();
@@ -316,7 +316,7 @@ const xero = new XeroClient({
316316
clientId: 'YOUR_CLIENT_ID',
317317
clientSecret: 'YOUR_CLIENT_SECRET',
318318
redirectUris: [`http://localhost:${port}/callback`],
319-
scopes: 'openid profile email accounting.transactions offline_access'.split(" ")
319+
scopes: 'openid profile email accounting.settings accounting.transactions offline_access'.split(" ")
320320
});
321321

322322
await xero.initialize();

0 commit comments

Comments
 (0)