@duckduckgo/autoconsent 10.2.0 → 10.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/actions/setup-release-scripts/action.yml +15 -0
- package/.github/workflows/asana.yml +2 -4
- package/.github/workflows/ddg-release.yml +303 -0
- package/CHANGELOG.md +33 -0
- package/ci/asana-create-tasks.js +174 -0
- package/ci/asana-update-tasks.js +57 -0
- package/ci/clients_pr_template.md +12 -0
- package/ci/create-pr-template.js +61 -0
- package/ci/release-utils.js +61 -0
- package/dist/addon-firefox/content.bundle.js +2 -2
- package/dist/addon-firefox/manifest.json +1 -1
- package/dist/addon-firefox/rules.json +5 -5
- package/dist/addon-mv3/content.bundle.js +2 -2
- package/dist/addon-mv3/manifest.json +1 -1
- package/dist/addon-mv3/rules.json +5 -5
- package/dist/autoconsent.cjs.js +2 -2
- package/dist/autoconsent.esm.js +2 -2
- package/dist/autoconsent.playwright.js +1 -1
- package/dist/autoconsent.unit.js +7 -7
- package/lib/cmps/onetrust.ts +2 -2
- package/package.json +7 -3
- package/rules/autoconsent/sirdata.json +25 -7
- package/rules/rules.json +5 -5
- package/scripts/get-text-for-xpath.ts +78 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: 'Setup Release Scripts'
|
|
2
|
+
description: 'Install release script dependencies using correct node version'
|
|
3
|
+
runs:
|
|
4
|
+
using: "composite"
|
|
5
|
+
steps:
|
|
6
|
+
- uses: actions/setup-node@v3
|
|
7
|
+
with:
|
|
8
|
+
node-version: 18.x
|
|
9
|
+
cache: 'npm'
|
|
10
|
+
cache-dependency-path: 'autoconsent/package-lock.json'
|
|
11
|
+
- run: |
|
|
12
|
+
cd autoconsent
|
|
13
|
+
npm ci
|
|
14
|
+
cd ..
|
|
15
|
+
shell: bash
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
name: 'asana sync'
|
|
2
2
|
on:
|
|
3
|
+
pull_request_review:
|
|
3
4
|
pull_request_target:
|
|
4
5
|
types:
|
|
5
6
|
- opened
|
|
@@ -12,15 +13,12 @@ on:
|
|
|
12
13
|
jobs:
|
|
13
14
|
sync:
|
|
14
15
|
runs-on: ubuntu-latest
|
|
15
|
-
environment: development
|
|
16
|
-
concurrency: 'asana-${{ github.repository }}'
|
|
17
16
|
steps:
|
|
18
17
|
- uses: actions/checkout@v3
|
|
19
|
-
- uses: sammacbeth/action-asana-sync@
|
|
18
|
+
- uses: sammacbeth/action-asana-sync@v6
|
|
20
19
|
with:
|
|
21
20
|
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
|
|
22
21
|
ASANA_WORKSPACE_ID: ${{ secrets.ASANA_WORKSPACE_ID }}
|
|
23
22
|
ASANA_PROJECT_ID: '1203409672862476'
|
|
24
23
|
move_to_section_id: '1203409672862480'
|
|
25
24
|
USER_MAP: ${{ vars.USER_MAP }}
|
|
26
|
-
NO_AUTOCLOSE_PROJECTS: '1203409672862476'
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
name: Propagate Autoconsent To DDG Apps
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [ published ]
|
|
6
|
+
|
|
7
|
+
env:
|
|
8
|
+
VERSION: ${{ github.event.release.tag_name }}
|
|
9
|
+
RELEASE_URL: ${{ github.event.release.html_url }}
|
|
10
|
+
RELEASE_NOTES: ${{ github.event.release.body }}
|
|
11
|
+
PR_TITLE: Update autoconsent to ${{ github.event.release.tag_name }}
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
|
|
15
|
+
# ------------------------------------------------------------------------------
|
|
16
|
+
# Create initial Asana subtasks
|
|
17
|
+
# ------------------------------------------------------------------------------
|
|
18
|
+
create_asana_tasks:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
outputs:
|
|
21
|
+
asana-output: ${{ steps.create-asana-tasks.outputs.ASANA_OUTPUT }}
|
|
22
|
+
steps:
|
|
23
|
+
# --- Setup ---
|
|
24
|
+
- uses: actions/checkout@v3
|
|
25
|
+
with:
|
|
26
|
+
path: autoconsent/
|
|
27
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
28
|
+
# --- Effect ---
|
|
29
|
+
- name: Create Asana Tasks
|
|
30
|
+
id: create-asana-tasks
|
|
31
|
+
env:
|
|
32
|
+
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
|
|
33
|
+
run: |
|
|
34
|
+
JSON_STRING="$(node ./autoconsent/ci/asana-create-tasks.js)"
|
|
35
|
+
echo "ASANA_OUTPUT=$JSON_STRING" >> $GITHUB_OUTPUT
|
|
36
|
+
|
|
37
|
+
# ------------------------------------------------------------------------------
|
|
38
|
+
# Create PR with updated autoconsent on Android
|
|
39
|
+
# ------------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
update_android:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
outputs:
|
|
44
|
+
pull-request-url: ${{ steps.create-pr.outputs.pull-request-url }}
|
|
45
|
+
needs: create_asana_tasks
|
|
46
|
+
steps:
|
|
47
|
+
# --- Setup ---
|
|
48
|
+
- uses: actions/checkout@v3
|
|
49
|
+
with:
|
|
50
|
+
path: autoconsent/
|
|
51
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
52
|
+
# --- Action ---
|
|
53
|
+
- name: Checkout Android
|
|
54
|
+
uses: actions/checkout@v3
|
|
55
|
+
with:
|
|
56
|
+
repository: duckduckgo/android
|
|
57
|
+
path: android/
|
|
58
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
59
|
+
- uses: actions/setup-node@v3
|
|
60
|
+
with:
|
|
61
|
+
node-version: current
|
|
62
|
+
- name: Update Android autoconsent reference
|
|
63
|
+
run: |
|
|
64
|
+
cd android
|
|
65
|
+
npm install @duckduckgo/autoconsent@${{ env.VERSION }}
|
|
66
|
+
npm run rebuild-autoconsent
|
|
67
|
+
cd ..
|
|
68
|
+
- name: Create Android PR Body
|
|
69
|
+
env:
|
|
70
|
+
ASANA_OUTPUT: ${{ needs.create_asana_tasks.outputs.asana-output }}
|
|
71
|
+
run: |
|
|
72
|
+
TEMPLATE="$(node ./autoconsent/ci/create-pr-template.js android)"
|
|
73
|
+
# Creates a randomised delimiter. See https://app.asana.com/0/1199892415909552/1203243297643584/f
|
|
74
|
+
DELIMITER=$(echo $RANDOM | md5sum | head -c 20;)
|
|
75
|
+
echo "PR_BODY_ANDROID<<$DELIMITER" >> $GITHUB_ENV
|
|
76
|
+
echo "$TEMPLATE" >> $GITHUB_ENV
|
|
77
|
+
echo "$DELIMITER" >> $GITHUB_ENV
|
|
78
|
+
# --- Effect ---
|
|
79
|
+
- name: Create PR for Android
|
|
80
|
+
uses: peter-evans/create-pull-request@88bf0de51c7487d91e1abbb4899332e602c58bbf
|
|
81
|
+
id: create-pr
|
|
82
|
+
with:
|
|
83
|
+
path: android/
|
|
84
|
+
add-paths: |
|
|
85
|
+
package.json
|
|
86
|
+
package-lock.json
|
|
87
|
+
autoconsent/
|
|
88
|
+
commit-message: Update autoconsent to ${{ env.VERSION }}
|
|
89
|
+
branch: update-autoconsent-${{ env.VERSION }}
|
|
90
|
+
title: ${{ env.PR_TITLE }}
|
|
91
|
+
body: "${{ env.PR_BODY_ANDROID }}"
|
|
92
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# ------------------------------------------------------------------------------
|
|
96
|
+
# Create PR with updated autoconsent on iOS
|
|
97
|
+
# ------------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
update_ios:
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
outputs:
|
|
102
|
+
pull-request-url: ${{ steps.create-pr.outputs.pull-request-url }}
|
|
103
|
+
needs: create_asana_tasks
|
|
104
|
+
steps:
|
|
105
|
+
# --- Setup ---
|
|
106
|
+
- uses: actions/checkout@v3
|
|
107
|
+
with:
|
|
108
|
+
path: autoconsent/
|
|
109
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
110
|
+
# --- Action ---
|
|
111
|
+
- name: Checkout iOS
|
|
112
|
+
uses: actions/checkout@v3
|
|
113
|
+
with:
|
|
114
|
+
repository: duckduckgo/iOS
|
|
115
|
+
path: ios/
|
|
116
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
117
|
+
- uses: actions/setup-node@v3
|
|
118
|
+
with:
|
|
119
|
+
node-version: current
|
|
120
|
+
- name: Update iOS autoconsent reference
|
|
121
|
+
run: |
|
|
122
|
+
cd ios
|
|
123
|
+
npm install @duckduckgo/autoconsent@${{ env.VERSION }}
|
|
124
|
+
npm run rebuild-autoconsent
|
|
125
|
+
cd ..
|
|
126
|
+
- name: Create iOS PR Body
|
|
127
|
+
env:
|
|
128
|
+
ASANA_OUTPUT: ${{ needs.create_asana_tasks.outputs.asana-output }}
|
|
129
|
+
run: |
|
|
130
|
+
TEMPLATE="$(node ./autoconsent/ci/create-pr-template.js ios)"
|
|
131
|
+
# Creates a randomised delimiter. See https://app.asana.com/0/1199892415909552/1203243297643584/f
|
|
132
|
+
DELIMITER=$(echo $RANDOM | md5sum | head -c 20;)
|
|
133
|
+
echo "PR_BODY_IOS<<$DELIMITER" >> $GITHUB_ENV
|
|
134
|
+
echo "$TEMPLATE" >> $GITHUB_ENV
|
|
135
|
+
echo "$DELIMITER" >> $GITHUB_ENV
|
|
136
|
+
# --- Effect ---
|
|
137
|
+
- name: Create PR for iOS
|
|
138
|
+
uses: peter-evans/create-pull-request@88bf0de51c7487d91e1abbb4899332e602c58bbf
|
|
139
|
+
id: create-pr
|
|
140
|
+
with:
|
|
141
|
+
path: ios/
|
|
142
|
+
add-paths: |
|
|
143
|
+
package.json
|
|
144
|
+
package-lock.json
|
|
145
|
+
DuckDuckGo/Autoconsent/
|
|
146
|
+
commit-message: Update autoconsent to ${{ env.VERSION }}
|
|
147
|
+
branch: update-autoconsent-${{ env.VERSION }}
|
|
148
|
+
title: ${{ env.PR_TITLE }}
|
|
149
|
+
body: "${{ env.PR_BODY_IOS }}"
|
|
150
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
151
|
+
|
|
152
|
+
# ------------------------------------------------------------------------------
|
|
153
|
+
# Create PR with updated autoconsent on macOS
|
|
154
|
+
# ------------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
update_macos:
|
|
157
|
+
runs-on: ubuntu-latest
|
|
158
|
+
outputs:
|
|
159
|
+
pull-request-url: ${{ steps.create-pr.outputs.pull-request-url }}
|
|
160
|
+
needs: create_asana_tasks
|
|
161
|
+
steps:
|
|
162
|
+
# --- Setup ---
|
|
163
|
+
- uses: actions/checkout@v3
|
|
164
|
+
with:
|
|
165
|
+
path: autoconsent/
|
|
166
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
167
|
+
# --- Action ---
|
|
168
|
+
- name: Checkout macOS
|
|
169
|
+
uses: actions/checkout@v3
|
|
170
|
+
with:
|
|
171
|
+
repository: duckduckgo/macos-browser
|
|
172
|
+
path: macos/
|
|
173
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
174
|
+
- uses: actions/setup-node@v3
|
|
175
|
+
with:
|
|
176
|
+
node-version: current
|
|
177
|
+
- name: Update macOS autoconsent reference
|
|
178
|
+
run: |
|
|
179
|
+
cd macos
|
|
180
|
+
npm install @duckduckgo/autoconsent@${{ env.VERSION }}
|
|
181
|
+
npm run rebuild-autoconsent
|
|
182
|
+
cd ..
|
|
183
|
+
- name: Create macOS PR Body
|
|
184
|
+
env:
|
|
185
|
+
ASANA_OUTPUT: ${{ needs.create_asana_tasks.outputs.asana-output }}
|
|
186
|
+
run: |
|
|
187
|
+
TEMPLATE="$(node ./autoconsent/ci/create-pr-template.js macos)"
|
|
188
|
+
# Creates a randomised delimiter. See https://app.asana.com/0/1199892415909552/1203243297643584/f
|
|
189
|
+
DELIMITER=$(echo $RANDOM | md5sum | head -c 20;)
|
|
190
|
+
echo "PR_BODY_MACOS<<$DELIMITER" >> $GITHUB_ENV
|
|
191
|
+
echo "$TEMPLATE" >> $GITHUB_ENV
|
|
192
|
+
echo "$DELIMITER" >> $GITHUB_ENV
|
|
193
|
+
# --- Effect ---
|
|
194
|
+
- name: Create PR for macOS
|
|
195
|
+
uses: peter-evans/create-pull-request@88bf0de51c7487d91e1abbb4899332e602c58bbf
|
|
196
|
+
id: create-pr
|
|
197
|
+
with:
|
|
198
|
+
path: macos/
|
|
199
|
+
add-paths: |
|
|
200
|
+
package.json
|
|
201
|
+
package-lock.json
|
|
202
|
+
DuckDuckGo/Autoconsent/
|
|
203
|
+
commit-message: Update autoconsent to ${{ env.VERSION }}
|
|
204
|
+
branch: update-autoconsent-${{ env.VERSION }}
|
|
205
|
+
title: ${{ env.PR_TITLE }}
|
|
206
|
+
body: "${{ env.PR_BODY_MACOS }}"
|
|
207
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
208
|
+
|
|
209
|
+
# ------------------------------------------------------------------------------
|
|
210
|
+
# Create PR with updated autofill on Windows
|
|
211
|
+
# ------------------------------------------------------------------------------
|
|
212
|
+
|
|
213
|
+
update_windows:
|
|
214
|
+
runs-on: ubuntu-latest
|
|
215
|
+
outputs:
|
|
216
|
+
pull-request-url: ${{ steps.create-pr.outputs.pull-request-url }}
|
|
217
|
+
needs: create_asana_tasks
|
|
218
|
+
steps:
|
|
219
|
+
# --- Setup ---
|
|
220
|
+
- uses: actions/checkout@v3
|
|
221
|
+
with:
|
|
222
|
+
path: autoconsent/
|
|
223
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
224
|
+
# --- Action ---
|
|
225
|
+
- name: Checkout Windows
|
|
226
|
+
uses: actions/checkout@v3
|
|
227
|
+
with:
|
|
228
|
+
repository: duckduckgo/windows-browser
|
|
229
|
+
path: windows/
|
|
230
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
231
|
+
- uses: actions/setup-node@v3
|
|
232
|
+
with:
|
|
233
|
+
node-version: current
|
|
234
|
+
- name: Update Windows autoconsent reference
|
|
235
|
+
run: |
|
|
236
|
+
cd windows/WindowsBrowser/Application/Autoconsent/External
|
|
237
|
+
npm install @duckduckgo/autoconsent@${{ env.VERSION }}
|
|
238
|
+
npm run rebuild-autoconsent
|
|
239
|
+
cd ../../../../../
|
|
240
|
+
- name: Create Windows PR Body
|
|
241
|
+
env:
|
|
242
|
+
ASANA_OUTPUT: ${{ needs.create_asana_tasks.outputs.asana-output }}
|
|
243
|
+
run: |
|
|
244
|
+
TEMPLATE="$(node ./autoconsent/ci/create-pr-template.js windows)"
|
|
245
|
+
# Creates a randomised delimiter. See https://app.asana.com/0/1199892415909552/1203243297643584/f
|
|
246
|
+
DELIMITER=$(echo $RANDOM | md5sum | head -c 20;)
|
|
247
|
+
echo "PR_BODY_WINDOWS<<$DELIMITER" >> $GITHUB_ENV
|
|
248
|
+
echo "$TEMPLATE" >> $GITHUB_ENV
|
|
249
|
+
echo "$DELIMITER" >> $GITHUB_ENV
|
|
250
|
+
# --- Effect ---
|
|
251
|
+
- name: Create PR for Windows
|
|
252
|
+
uses: peter-evans/create-pull-request@88bf0de51c7487d91e1abbb4899332e602c58bbf
|
|
253
|
+
id: create-pr
|
|
254
|
+
with:
|
|
255
|
+
path: windows/
|
|
256
|
+
add-paths: |
|
|
257
|
+
WindowsBrowser/Application/Autoconsent/
|
|
258
|
+
commit-message: Update autoconsent to ${{ env.VERSION }}
|
|
259
|
+
branch: update-autoconsent-${{ env.VERSION }}
|
|
260
|
+
title: ${{ env.PR_TITLE }}
|
|
261
|
+
body: "${{ env.PR_BODY_WINDOWS }}"
|
|
262
|
+
token: ${{ secrets.DAX_WEB_AUTOFILL_AUTOMATION }}
|
|
263
|
+
|
|
264
|
+
# ------------------------------------------------------------------------------
|
|
265
|
+
# Update Asana subtasks with PR URLs
|
|
266
|
+
# ------------------------------------------------------------------------------
|
|
267
|
+
|
|
268
|
+
update_asana_tasks:
|
|
269
|
+
runs-on: ubuntu-latest
|
|
270
|
+
# Always run this final step, even if any of the updates have failed
|
|
271
|
+
# unless the previous jobs were cancelled
|
|
272
|
+
if: ${{ always() && !contains(needs.*.result, 'cancelled') }}
|
|
273
|
+
needs: [create_asana_tasks, update_android, update_ios, update_macos, update_windows]
|
|
274
|
+
steps:
|
|
275
|
+
# --- Setup ---
|
|
276
|
+
- uses: actions/checkout@v3
|
|
277
|
+
with:
|
|
278
|
+
path: autoconsent/
|
|
279
|
+
- uses: ./autoconsent/.github/actions/setup-release-scripts
|
|
280
|
+
# --- Effect ---
|
|
281
|
+
- name: Update Asana tasks
|
|
282
|
+
env:
|
|
283
|
+
ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }}
|
|
284
|
+
ASANA_OUTPUT: ${{ needs.create_asana_tasks.outputs.asana-output }}
|
|
285
|
+
IOS_PR_URL: ${{ needs.update_ios.outputs.pull-request-url }}
|
|
286
|
+
MACOS_PR_URL: ${{ needs.update_macos.outputs.pull-request-url }}
|
|
287
|
+
WINDOWS_PR_URL: ${{ needs.update_windows.outputs.pull-request-url }}
|
|
288
|
+
ANDROID_PR_URL: ${{ needs.update_android.outputs.pull-request-url }}
|
|
289
|
+
run: |
|
|
290
|
+
node ./autoconsent/ci/asana-update-tasks.js
|
|
291
|
+
|
|
292
|
+
- name: Ouput workflow summary
|
|
293
|
+
# Show failure message if any of the jobs report failed
|
|
294
|
+
if: ${{ contains(needs.*.result, 'failure') }}
|
|
295
|
+
run: |
|
|
296
|
+
echo "Release process completed but with failures reported." >> $GITHUB_STEP_SUMMARY
|
|
297
|
+
echo "Please review the job output to see which steps require manual intervention." >> $GITHUB_STEP_SUMMARY
|
|
298
|
+
- name: Ouput workflow summary
|
|
299
|
+
# Show success message as long as none of the jobs report failed
|
|
300
|
+
if: ${{ !contains(needs.*.result, 'failure') }}
|
|
301
|
+
run: |
|
|
302
|
+
echo "Release process completed successfully." >> $GITHUB_STEP_SUMMARY
|
|
303
|
+
echo "All PRs and Asana tasks created! :rocket:" >> $GITHUB_STEP_SUMMARY
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
# v10.3.1 (Fri Mar 15 2024)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- Fix the trigger event for the CI automation [#394](https://github.com/duckduckgo/autoconsent/pull/394) ([@muodov](https://github.com/muodov))
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Maxim Tsoy ([@muodov](https://github.com/muodov))
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# v10.3.0 (Fri Mar 15 2024)
|
|
14
|
+
|
|
15
|
+
#### 🚀 Enhancement
|
|
16
|
+
|
|
17
|
+
- DDG release automation [#389](https://github.com/duckduckgo/autoconsent/pull/389) ([@muodov](https://github.com/muodov))
|
|
18
|
+
- Bump the dev-dependencies group with 4 updates [#390](https://github.com/duckduckgo/autoconsent/pull/390) ([@dependabot[bot]](https://github.com/dependabot[bot]))
|
|
19
|
+
|
|
20
|
+
#### 🐛 Bug Fix
|
|
21
|
+
|
|
22
|
+
- Fix infinite reload for OneTrust sites [#393](https://github.com/duckduckgo/autoconsent/pull/393) ([@muodov](https://github.com/muodov))
|
|
23
|
+
- Script to crawl page text content in multiple languages. [#386](https://github.com/duckduckgo/autoconsent/pull/386) ([@sammacbeth](https://github.com/sammacbeth))
|
|
24
|
+
- Update Asana sync action [#388](https://github.com/duckduckgo/autoconsent/pull/388) ([@sammacbeth](https://github.com/sammacbeth))
|
|
25
|
+
|
|
26
|
+
#### Authors: 3
|
|
27
|
+
|
|
28
|
+
- [@dependabot[bot]](https://github.com/dependabot[bot])
|
|
29
|
+
- Maxim Tsoy ([@muodov](https://github.com/muodov))
|
|
30
|
+
- Sam Macbeth ([@sammacbeth](https://github.com/sammacbeth))
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
1
34
|
# v10.2.0 (Tue Mar 05 2024)
|
|
2
35
|
|
|
3
36
|
#### 🚀 Enhancement
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
/* eslint-disable camelcase */
|
|
3
|
+
const timersPromises = require('node:timers/promises')
|
|
4
|
+
const Asana = require('asana')
|
|
5
|
+
const MarkdownIt = require('markdown-it')
|
|
6
|
+
const {getLink} = require('./release-utils.js')
|
|
7
|
+
const md = new MarkdownIt()
|
|
8
|
+
|
|
9
|
+
const ASANA_ACCESS_TOKEN = process.env.ASANA_ACCESS_TOKEN
|
|
10
|
+
const commit = process.env.GITHUB_SHA
|
|
11
|
+
const version = process.env.VERSION
|
|
12
|
+
const releaseUrl = process.env.RELEASE_URL || 'https://example.com/'
|
|
13
|
+
const releaseNotesRaw = process.env.RELEASE_NOTES || '<EMPTY RELEASE NOTES>'
|
|
14
|
+
const releaseNotes = md.render(releaseNotesRaw)
|
|
15
|
+
|
|
16
|
+
const templateTaskGid = '1206774921409831'
|
|
17
|
+
const autoconsentProjectGid = '1201844467387842'
|
|
18
|
+
const releaseSectionGid = '1202253736774466'
|
|
19
|
+
const projectExtractorRegex = /\[\[project_gids=(.+)]]\s/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {{taskGid: string, taskUrl: string, displayName: string}} platformData
|
|
23
|
+
*
|
|
24
|
+
* @typedef {{
|
|
25
|
+
* android: platformData,
|
|
26
|
+
* windows: platformData
|
|
27
|
+
* }} AsanaOutput
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/** @type {AsanaOutput} */
|
|
31
|
+
const platforms = {
|
|
32
|
+
android: {
|
|
33
|
+
displayName: 'Android',
|
|
34
|
+
taskGid: '',
|
|
35
|
+
taskUrl: ''
|
|
36
|
+
},
|
|
37
|
+
windows: {
|
|
38
|
+
displayName: 'Windows',
|
|
39
|
+
taskGid: '',
|
|
40
|
+
taskUrl: ''
|
|
41
|
+
},
|
|
42
|
+
ios: {
|
|
43
|
+
displayName: 'iOS',
|
|
44
|
+
taskGid: '',
|
|
45
|
+
taskUrl: ''
|
|
46
|
+
},
|
|
47
|
+
macos: {
|
|
48
|
+
displayName: 'macOS',
|
|
49
|
+
taskGid: '',
|
|
50
|
+
taskUrl: ''
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let asana
|
|
55
|
+
|
|
56
|
+
const setupAsana = () => {
|
|
57
|
+
asana = Asana.Client.create({
|
|
58
|
+
'defaultHeaders': {
|
|
59
|
+
'Asana-Enable': 'new_project_templates,new_user_task_lists,new_goal_memberships'
|
|
60
|
+
}
|
|
61
|
+
}).useAccessToken(ASANA_ACCESS_TOKEN)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const duplicateTemplateTask = (templateTaskGid) => {
|
|
65
|
+
const duplicateOption = {
|
|
66
|
+
include: ['notes', 'assignee', 'subtasks', 'projects'],
|
|
67
|
+
name: `Autoconsent release ${version}`,
|
|
68
|
+
opt_fields: 'html_notes'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return asana.tasks.duplicateTask(templateTaskGid, duplicateOption)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const waitForJobSuccess = async (job_gid, attempts = 1) => {
|
|
75
|
+
const interval = 500
|
|
76
|
+
const maxAttempts = 20
|
|
77
|
+
|
|
78
|
+
return new Promise(async (resolve, reject) => {
|
|
79
|
+
const { status } = await asana.jobs.getJob(job_gid)
|
|
80
|
+
if (status === 'succeeded') {
|
|
81
|
+
return resolve(status)
|
|
82
|
+
}
|
|
83
|
+
attempts += 1
|
|
84
|
+
|
|
85
|
+
if (attempts > maxAttempts) {
|
|
86
|
+
return reject(new Error(`The job ${job_gid} took too long to execute`))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await timersPromises.setTimeout(interval)
|
|
90
|
+
return waitForJobSuccess(job_gid, attempts)
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const asanaCreateTasks = async () => {
|
|
95
|
+
setupAsana()
|
|
96
|
+
|
|
97
|
+
// Duplicating template task...
|
|
98
|
+
const { new_task, gid: duplicateTaskJobGid } = await duplicateTemplateTask(templateTaskGid)
|
|
99
|
+
|
|
100
|
+
const { html_notes: notes } = await asana.tasks.getTask(new_task.gid, { opt_fields: 'html_notes' })
|
|
101
|
+
|
|
102
|
+
const updatedNotes =
|
|
103
|
+
notes.replace('[[version]]', version)
|
|
104
|
+
.replace('[[commit]]', commit)
|
|
105
|
+
.replace('[[release_url]]', getLink(releaseUrl, 'Autoconsent Release'))
|
|
106
|
+
.replace('[[notes]]', releaseNotes)
|
|
107
|
+
.replace(/<\/?p>/ig, '\n')
|
|
108
|
+
// Asana supports only h1 and h2
|
|
109
|
+
.replace(/<(h3|h4)>/ig, '<h2>').replace(/<\/(h3|h4)>/ig, '</h2>')
|
|
110
|
+
|
|
111
|
+
// Updating task and moving to Release section...
|
|
112
|
+
console.error(JSON.stringify(updatedNotes))
|
|
113
|
+
await asana.tasks.updateTask(new_task.gid, {html_notes: updatedNotes})
|
|
114
|
+
|
|
115
|
+
await asana.tasks.addProjectForTask(new_task.gid, { project: autoconsentProjectGid, section: releaseSectionGid })
|
|
116
|
+
|
|
117
|
+
// The duplicateTask job returns when the task itself has been duplicated, ignoring the subtasks.
|
|
118
|
+
// We want to wait that the job completes so that we can fetch all the subtasks correctly.
|
|
119
|
+
await waitForJobSuccess(duplicateTaskJobGid)
|
|
120
|
+
|
|
121
|
+
// Getting subtasks...
|
|
122
|
+
const { data: subtasks } = await asana.tasks.getSubtasksForTask(new_task.gid, {opt_fields: 'name,html_notes,permalink_url'})
|
|
123
|
+
|
|
124
|
+
// Updating subtasks and moving to appropriate projects...
|
|
125
|
+
for (const subtask of subtasks) {
|
|
126
|
+
const {gid, name, html_notes, permalink_url} = subtask
|
|
127
|
+
|
|
128
|
+
const platform = Object.keys(platforms).find(
|
|
129
|
+
(key) => name.includes(platforms[key].displayName)
|
|
130
|
+
)
|
|
131
|
+
if (!platform) throw new Error('Unexpected platform name: ' + name)
|
|
132
|
+
|
|
133
|
+
platforms[platform].taskGid = gid
|
|
134
|
+
platforms[platform].taskUrl = permalink_url
|
|
135
|
+
|
|
136
|
+
const newName = name.replace('[[version]]', version)
|
|
137
|
+
const extractedProjects = html_notes.match(projectExtractorRegex)?.[1]
|
|
138
|
+
|
|
139
|
+
const subtaskNotes =
|
|
140
|
+
html_notes.replace(projectExtractorRegex, '')
|
|
141
|
+
.replace('[[notes]]', updatedNotes)
|
|
142
|
+
|
|
143
|
+
await asana.tasks.updateTask(gid, { name: newName, html_notes: subtaskNotes })
|
|
144
|
+
|
|
145
|
+
if (extractedProjects) {
|
|
146
|
+
for (const projectGid of extractedProjects.split(',')) {
|
|
147
|
+
await asana.tasks.addProjectForTask(gid, { project: projectGid, insert_after: null })
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const finalNotes =
|
|
153
|
+
updatedNotes
|
|
154
|
+
.replace('<li>[[pr_url]]</li>', version)
|
|
155
|
+
.replace('<li>[[extra_content]]</li>', version)
|
|
156
|
+
|
|
157
|
+
await asana.tasks.updateTask(new_task.gid, {html_notes: finalNotes})
|
|
158
|
+
|
|
159
|
+
const jsonString = JSON.stringify(platforms)
|
|
160
|
+
return {stdout: jsonString}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
asanaCreateTasks()
|
|
164
|
+
.then((result) => {
|
|
165
|
+
// The log is needed to read the value from the bash context
|
|
166
|
+
console.log(result.stdout)
|
|
167
|
+
})
|
|
168
|
+
.catch((e) => {
|
|
169
|
+
// The Asana API returns errors in e.value.errors. If that's undefined log whatever else we got
|
|
170
|
+
console.error(e.value?.errors || e)
|
|
171
|
+
process.exit(1)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
module.exports = {asanaCreateTasks}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const Asana = require('asana')
|
|
2
|
+
const {replaceAllInString, getLink} = require('./release-utils.js')
|
|
3
|
+
|
|
4
|
+
const ASANA_ACCESS_TOKEN = process.env.ASANA_ACCESS_TOKEN
|
|
5
|
+
const prUrls = {
|
|
6
|
+
android: process.env.ANDROID_PR_URL || 'https://example.com/',
|
|
7
|
+
ios: process.env.IOS_PR_URL || 'https://example.com/',
|
|
8
|
+
macos: process.env.MACOS_PR_URL || 'https://example.com/',
|
|
9
|
+
windows: process.env.WINDOWS_PR_URL || 'https://example.com/',
|
|
10
|
+
}
|
|
11
|
+
const asanaOutputRaw = process.env.ASANA_OUTPUT
|
|
12
|
+
|
|
13
|
+
let asana
|
|
14
|
+
|
|
15
|
+
const setupAsana = () => {
|
|
16
|
+
asana = Asana.Client.create({
|
|
17
|
+
'defaultHeaders': {
|
|
18
|
+
'Asana-Enable': 'new_project_templates,new_user_task_lists,new_goal_memberships'
|
|
19
|
+
}
|
|
20
|
+
}).useAccessToken(ASANA_ACCESS_TOKEN)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const asanaUpdateTasks = async () => {
|
|
24
|
+
let asanaOutput
|
|
25
|
+
try {
|
|
26
|
+
asanaOutput = JSON.parse(asanaOutputRaw || '')
|
|
27
|
+
} catch (e) {
|
|
28
|
+
throw new Error('Unable to parse Asana output JSON')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
setupAsana()
|
|
32
|
+
|
|
33
|
+
const platformEntries = Object.entries(asanaOutput)
|
|
34
|
+
for (const [platformName, platformObj] of platformEntries) {
|
|
35
|
+
// If we're missing required data, either we haven't implemented automation for that platform yet,
|
|
36
|
+
// or something went wrong in a previous job
|
|
37
|
+
if (!platformObj.taskGid || !prUrls[platformName]) continue
|
|
38
|
+
|
|
39
|
+
const { html_notes: notes } = await asana.tasks.getTask(platformObj.taskGid, { opt_fields: 'html_notes' })
|
|
40
|
+
|
|
41
|
+
const prLink = getLink(prUrls[platformName], `${platformObj.displayName} PR`)
|
|
42
|
+
/** @type {[[RegExp, string]]} */
|
|
43
|
+
const taskDescriptionSubstitutions = [
|
|
44
|
+
[/\[\[pr_url]]/, prLink]
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
const updatedNotes = replaceAllInString(notes, taskDescriptionSubstitutions)
|
|
48
|
+
|
|
49
|
+
await asana.tasks.updateTask(platformObj.taskGid, { html_notes: updatedNotes })
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
asanaUpdateTasks().catch((e) => {
|
|
54
|
+
// The Asana API returns errors in e.value.errors. If that's undefined log whatever else we got
|
|
55
|
+
console.error(e.value?.errors || e)
|
|
56
|
+
process.exit(1)
|
|
57
|
+
})
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Task/Issue URL: [[asana_url]]
|
|
2
|
+
Autoconsent Release: [[autoconsent_release_url]]
|
|
3
|
+
[[extra_content]]
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
Updates Autoconsent to version [[[version]]]([[autoconsent_release_url]]).
|
|
7
|
+
|
|
8
|
+
### Autoconsent [[version]] release notes
|
|
9
|
+
[[description]]
|
|
10
|
+
|
|
11
|
+
## Steps to test
|
|
12
|
+
This release has been tested during Autoconsent development. You can check the release notes for more information.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const {readFileSync} = require('fs')
|
|
2
|
+
const {join} = require('path')
|
|
3
|
+
const {replaceAllInString} = require('./release-utils.js')
|
|
4
|
+
const cwd = join(__dirname, '..')
|
|
5
|
+
const filepath = (...path) => join(cwd, ...path)
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{
|
|
9
|
+
* releaseNotesRaw: string,
|
|
10
|
+
* asanaOutputRaw: string,
|
|
11
|
+
* releaseUrl: string,
|
|
12
|
+
* version: string
|
|
13
|
+
* }} CreatePRTemplateData
|
|
14
|
+
* @typedef {'android' | 'extensions' | 'bsk' | 'ios' | 'macos' | 'windows'} ReleasePlatform
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const platform = /** @type {ReleasePlatform} */ (process.argv[2])
|
|
18
|
+
|
|
19
|
+
/** @type {CreatePRTemplateData} */
|
|
20
|
+
const data = {
|
|
21
|
+
version: process.env.VERSION || '',
|
|
22
|
+
releaseUrl: process.env.RELEASE_URL || '',
|
|
23
|
+
releaseNotesRaw: process.env.RELEASE_NOTES || '',
|
|
24
|
+
asanaOutputRaw: process.env.ASANA_OUTPUT || '{}'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Outputs the PR template populated with data
|
|
29
|
+
* @param {ReleasePlatform} platform
|
|
30
|
+
* @param {CreatePRTemplateData} data
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
function createPRTemplate (platform, data) {
|
|
34
|
+
const asanaOutput = JSON.parse(data.asanaOutputRaw)
|
|
35
|
+
const templatePath = filepath(`./ci/clients_pr_template.md`)
|
|
36
|
+
const template = readFileSync(templatePath, 'utf8')
|
|
37
|
+
|
|
38
|
+
const asanaUrlRegex = /\[\[asana_url]]/
|
|
39
|
+
const autoconsentReleaseUrlRegex = /\[\[autoconsent_release_url]]/
|
|
40
|
+
const extraContentRegex = /\[\[extra_content]]/
|
|
41
|
+
const versionRegex = /\[\[version]]/
|
|
42
|
+
const descriptionRegex = /\[\[description]]/
|
|
43
|
+
|
|
44
|
+
let extraContent = ''
|
|
45
|
+
|
|
46
|
+
let asanaUrl = asanaOutput[platform]?.taskUrl
|
|
47
|
+
|
|
48
|
+
const updatedTemplate = replaceAllInString(template, [
|
|
49
|
+
[asanaUrlRegex, asanaUrl],
|
|
50
|
+
[autoconsentReleaseUrlRegex, data.releaseUrl],
|
|
51
|
+
[extraContentRegex, extraContent],
|
|
52
|
+
[versionRegex, data.version],
|
|
53
|
+
[descriptionRegex, data.releaseNotesRaw]
|
|
54
|
+
])
|
|
55
|
+
return updatedTemplate
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The log is needed to read the value from the bash context
|
|
59
|
+
console.log(createPRTemplate(platform, data))
|
|
60
|
+
|
|
61
|
+
module.exports = {createPRTemplate}
|