Compare commits
409 Commits
v0.5.0
...
new-or-upd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03b357393e | ||
![]() |
35863ee6e9 | ||
![]() |
0784a2d4d0 | ||
![]() |
75d5c0e356 | ||
![]() |
a2dd6d76a8 | ||
![]() |
bdc6b59857 | ||
![]() |
34e95f1e89 | ||
![]() |
6a92cfc573 | ||
![]() |
9f759d70b6 | ||
![]() |
43e957e8d3 | ||
![]() |
ae316f60e4 | ||
![]() |
1ac423ba56 | ||
![]() |
b43490dd76 | ||
![]() |
f586e81dd1 | ||
![]() |
8a6d8a7d8c | ||
![]() |
45d607f1a0 | ||
![]() |
d84abaa229 | ||
![]() |
3fd1d4d9b3 | ||
![]() |
078b8efb56 | ||
![]() |
5066995f72 | ||
![]() |
577fe3dba8 | ||
![]() |
d96f4999bc | ||
![]() |
6e80ff4eb6 | ||
![]() |
3f8f022d48 | ||
![]() |
93a2e2151e | ||
![]() |
663a1ed9d4 | ||
![]() |
4f46c55c85 | ||
![]() |
9701c98af9 | ||
![]() |
aabf2a1c79 | ||
![]() |
29539b090e | ||
![]() |
1c80677ac3 | ||
![]() |
ad419855e9 | ||
![]() |
30b75943f3 | ||
![]() |
41a67b402d | ||
![]() |
caa104b1cc | ||
![]() |
94085f2bc8 | ||
![]() |
d39c962314 | ||
![]() |
706fb0f063 | ||
![]() |
b9d89b040f | ||
![]() |
41421b849a | ||
![]() |
324375da93 | ||
![]() |
536446faf6 | ||
![]() |
d026ac09f3 | ||
![]() |
88c93ac992 | ||
![]() |
d540322d8b | ||
![]() |
ad4db5e936 | ||
![]() |
25cb4d90f3 | ||
![]() |
6c14a353ef | ||
![]() |
74d7d1aa98 | ||
![]() |
43b0d9ed29 | ||
![]() |
3572e6f65a | ||
![]() |
d23d5d2da0 | ||
![]() |
183b9b0d88 | ||
![]() |
7a1af268ae | ||
![]() |
f879b3c5b0 | ||
![]() |
40be72cf65 | ||
![]() |
a8886571d1 | ||
![]() |
1fcd51ea26 | ||
![]() |
89752138be | ||
![]() |
f29ccace2a | ||
![]() |
0c8343e76f | ||
![]() |
9776c9f5a4 | ||
![]() |
a5dbac9817 | ||
![]() |
bad5e0b855 | ||
![]() |
8e4ca55560 | ||
![]() |
f52afc1fe0 | ||
![]() |
815e64302e | ||
![]() |
07b2b18a4e | ||
![]() |
69eca33de7 | ||
![]() |
ec76a480d0 | ||
![]() |
a8823c3ed0 | ||
![]() |
1f1b3a341c | ||
![]() |
8c164a3852 | ||
![]() |
dcf526d810 | ||
![]() |
2fc6d680a0 | ||
![]() |
f414972f33 | ||
![]() |
69d192d989 | ||
![]() |
6c8769e598 | ||
![]() |
c12703422c | ||
![]() |
c0171e1cd1 | ||
![]() |
920a983146 | ||
![]() |
7ec86bfef1 | ||
![]() |
d8bc318688 | ||
![]() |
600ea1848f | ||
![]() |
a3ce9c7662 | ||
![]() |
44ce7577c6 | ||
![]() |
8c3e42f7eb | ||
![]() |
b8887c506c | ||
![]() |
6c4228b7b8 | ||
![]() |
9b1da98386 | ||
![]() |
1615169a3d | ||
![]() |
df83aa4d15 | ||
![]() |
142b96beb0 | ||
![]() |
18d07dd3b9 | ||
![]() |
270039d211 | ||
![]() |
fcf3a480be | ||
![]() |
80ee974973 | ||
![]() |
48c6a38205 | ||
![]() |
c9536e58cb | ||
![]() |
a16d783302 | ||
![]() |
b837aecb27 | ||
![]() |
532405048f | ||
![]() |
6cd0427ff8 | ||
![]() |
d2163f180e | ||
![]() |
d1344457dd | ||
![]() |
596be24d92 | ||
![]() |
4e182b49f9 | ||
![]() |
51ac37f1de | ||
![]() |
b578e88d46 | ||
![]() |
9cb4607f69 | ||
![]() |
2c4d602028 | ||
![]() |
a0feb7f309 | ||
![]() |
77e29050c8 | ||
![]() |
df55f746ca | ||
![]() |
2739d2297f | ||
![]() |
dc734b04d8 | ||
![]() |
d4c542168c | ||
![]() |
94a3b66130 | ||
![]() |
c8baf9b0d7 | ||
![]() |
c4dc0509c2 | ||
![]() |
3bfc428dfe | ||
![]() |
026b7da6f8 | ||
![]() |
58352b9f33 | ||
![]() |
59faf593be | ||
![]() |
4aa41773c4 | ||
![]() |
20c5d6aee1 | ||
![]() |
d503dbc103 | ||
![]() |
53624a6379 | ||
![]() |
5b881db19f | ||
![]() |
dece070d28 | ||
![]() |
8be2ed0034 | ||
![]() |
37c6b57a48 | ||
![]() |
8a0b5c24a5 | ||
![]() |
20431da757 | ||
![]() |
f219c87a9e | ||
![]() |
5d2134db56 | ||
![]() |
1dc46dd31c | ||
![]() |
96250ce9a0 | ||
![]() |
691682e09c | ||
![]() |
814c504951 | ||
![]() |
5c2b96a812 | ||
![]() |
3dc1ca8adb | ||
![]() |
a6850f1bc0 | ||
![]() |
5ba6cb9135 | ||
![]() |
500283af6f | ||
![]() |
43184dccda | ||
![]() |
4296a3b5df | ||
![]() |
14ba50f061 | ||
![]() |
9ad7de56a3 | ||
![]() |
5570687957 | ||
![]() |
1406bf3e10 | ||
![]() |
287f299b94 | ||
![]() |
f88f05cd46 | ||
![]() |
c6fb42e2f3 | ||
![]() |
c64ca9d9b7 | ||
![]() |
7d47793afb | ||
![]() |
2840fce856 | ||
![]() |
2791dca412 | ||
![]() |
3e268bf66b | ||
![]() |
f44422a77e | ||
![]() |
4931cbcc34 | ||
![]() |
59e495f7d3 | ||
![]() |
93866d7bc2 | ||
![]() |
ba1cdeaeeb | ||
![]() |
234b27e555 | ||
![]() |
5acfd09819 | ||
![]() |
9923b15ecd | ||
![]() |
def5a6d9d0 | ||
![]() |
17c8a405f5 | ||
![]() |
ff874bfb48 | ||
![]() |
4cbb37b996 | ||
![]() |
f57e35c6b8 | ||
![]() |
312e786e33 | ||
![]() |
e2c75a2daf | ||
![]() |
fce20263ea | ||
![]() |
d841f9cb62 | ||
![]() |
4945240ec2 | ||
![]() |
f1cdc7e422 | ||
![]() |
372cdb10d6 | ||
![]() |
fd24dbee21 | ||
![]() |
7066f7ea76 | ||
![]() |
5ae53c79b6 | ||
![]() |
f3a8ab289f | ||
![]() |
a99609e3da | ||
![]() |
a271189448 | ||
![]() |
251bc28526 | ||
![]() |
05505704e4 | ||
![]() |
4aadcb021e | ||
![]() |
ae9da1b354 | ||
![]() |
a594029541 | ||
![]() |
ddcb894932 | ||
![]() |
708cdbe545 | ||
![]() |
1cbf96dff1 | ||
![]() |
bd55b37d5f | ||
![]() |
7c3a0effee | ||
![]() |
fe3048aab0 | ||
![]() |
9a5a3e879d | ||
![]() |
269902db94 | ||
![]() |
4ba67ea863 | ||
![]() |
3534712478 | ||
![]() |
62b9a8071a | ||
![]() |
cf83c27ca0 | ||
![]() |
8035f81f97 | ||
![]() |
d2375fdc54 | ||
![]() |
f07d9dd813 | ||
![]() |
b5524b18cf | ||
![]() |
310497a5bf | ||
![]() |
47a738d5e6 | ||
![]() |
6ad13c1da0 | ||
![]() |
99454fdc4b | ||
![]() |
799f0ead6c | ||
![]() |
d16d709b72 | ||
![]() |
8e1087b818 | ||
![]() |
139dcb521e | ||
![]() |
b17e431473 | ||
![]() |
b1ee3ef8ba | ||
![]() |
75bbd16b0c | ||
![]() |
71a7943d01 | ||
![]() |
d34785b5b0 | ||
![]() |
af58ef7244 | ||
![]() |
6d3bec8518 | ||
![]() |
0346b157c5 | ||
![]() |
e25aab742b | ||
![]() |
6f2ca00263 | ||
![]() |
e1d26325f3 | ||
![]() |
4202f963c3 | ||
![]() |
d3ef45db1b | ||
![]() |
dec55709a3 | ||
![]() |
b5ed984f05 | ||
![]() |
66d7baa126 | ||
![]() |
a2809a14c5 | ||
![]() |
040ad9edb0 | ||
![]() |
46dbe009f2 | ||
![]() |
3598d43938 | ||
![]() |
f1358c7ad1 | ||
![]() |
40862fcd01 | ||
![]() |
189432c228 | ||
![]() |
280d16f3d9 | ||
![]() |
722c39590f | ||
![]() |
b1138dbf05 | ||
![]() |
08918282a7 | ||
![]() |
5007b0bf1a | ||
![]() |
0a5912eb8e | ||
![]() |
8acd7b03ed | ||
![]() |
ed87df212f | ||
![]() |
56243aa076 | ||
![]() |
41e9f32e1b | ||
![]() |
f7753aa1b4 | ||
![]() |
aebfcc38dd | ||
![]() |
3e0149c058 | ||
![]() |
1e62e09825 | ||
![]() |
956b15a2eb | ||
![]() |
572b457b43 | ||
![]() |
7d40ae009f | ||
![]() |
aec9595dea | ||
![]() |
cc90f19a46 | ||
![]() |
ab486c8ed1 | ||
![]() |
bfb1e817ec | ||
![]() |
ebc7c22388 | ||
![]() |
10b4066c82 | ||
![]() |
42dd67954d | ||
![]() |
d45fdf605f | ||
![]() |
caef9bb8b5 | ||
![]() |
c888934601 | ||
![]() |
95613b595e | ||
![]() |
9247bd9d9e | ||
![]() |
ee3d2489e6 | ||
![]() |
7764c4fbcb | ||
![]() |
a18b524859 | ||
![]() |
9b8ec9b85e | ||
![]() |
7b3f070973 | ||
![]() |
ba27fc12e8 | ||
![]() |
db55912f78 | ||
![]() |
4c4bd267d4 | ||
![]() |
dc1002659b | ||
![]() |
97da370301 | ||
![]() |
571901f333 | ||
![]() |
4d90df9d9a | ||
![]() |
2c18667ffd | ||
![]() |
89157cd606 | ||
![]() |
37e0091ef0 | ||
![]() |
ae3512fecf | ||
![]() |
8b81391e2f | ||
![]() |
54e68f6252 | ||
![]() |
92d1ed65ff | ||
![]() |
8098a7ee5d | ||
![]() |
c24297630c | ||
![]() |
a9d5212602 | ||
![]() |
c81db8ae19 | ||
![]() |
ecd356d42b | ||
![]() |
e67adf87b2 | ||
![]() |
1669708041 | ||
![]() |
12e34013f8 | ||
![]() |
bd2ad1d7a1 | ||
![]() |
934cdb8237 | ||
![]() |
2f6ea8830e | ||
![]() |
b77d08ebbf | ||
![]() |
b735d32cbc | ||
![]() |
472ffd5b5c | ||
![]() |
4567ca8fce | ||
![]() |
07ed24ca7a | ||
![]() |
52575be2a7 | ||
![]() |
c8187e52bb | ||
![]() |
b0b6b72b4c | ||
![]() |
7676bc5836 | ||
![]() |
f98c1725be | ||
![]() |
c6bd599b63 | ||
![]() |
7908779c89 | ||
![]() |
29ad68afab | ||
![]() |
9aaeac6a08 | ||
![]() |
8f074c2131 | ||
![]() |
930653c86d | ||
![]() |
cc31b7c210 | ||
![]() |
bb19e9308c | ||
![]() |
5e7b4bfe45 | ||
![]() |
dbeeb61cc5 | ||
![]() |
26d8e5856a | ||
![]() |
66be6d1e89 | ||
![]() |
677aa232e7 | ||
![]() |
cabbb45031 | ||
![]() |
ba99df645b | ||
![]() |
282e5ba2d8 | ||
![]() |
42d418da58 | ||
![]() |
cbf270fdba | ||
![]() |
bb9abe104f | ||
![]() |
18f0d6dea3 | ||
![]() |
23dc9a1139 | ||
![]() |
5e18ef5830 | ||
![]() |
63f8fc266d | ||
![]() |
4e46b16f7b | ||
![]() |
ba19b50005 | ||
![]() |
fa867387d4 | ||
![]() |
5762cf5dc5 | ||
![]() |
7d9f624805 | ||
![]() |
5b335ccd59 | ||
![]() |
4792853eb6 | ||
![]() |
cc05bc7db8 | ||
![]() |
d198eaa988 | ||
![]() |
f094da6a4b | ||
![]() |
a53961b235 | ||
![]() |
f644113af8 | ||
![]() |
e4a903ec07 | ||
![]() |
9408fe2a07 | ||
![]() |
394e747a88 | ||
![]() |
e91f12729b | ||
![]() |
134e588b14 | ||
![]() |
d061eb7b58 | ||
![]() |
18089a8076 | ||
![]() |
02236e01d9 | ||
![]() |
c1150d50b1 | ||
![]() |
387a849269 | ||
![]() |
399cebda70 | ||
![]() |
72720b3dfe | ||
![]() |
64f7560b3b | ||
![]() |
e06b646f49 | ||
![]() |
b51d9bb17b | ||
![]() |
4e967c5720 | ||
![]() |
179db38fd1 | ||
![]() |
e51930d7e1 | ||
![]() |
74a299dbe6 | ||
![]() |
282863c526 | ||
![]() |
63d794ed3e | ||
![]() |
c6b8f12f9a | ||
![]() |
d16e292231 | ||
![]() |
29a319a850 | ||
![]() |
c11e0db077 | ||
![]() |
b2dafb5dfa | ||
![]() |
e7ccd01427 | ||
![]() |
447f26458a | ||
![]() |
61fb71a080 | ||
![]() |
329fcdf8f4 | ||
![]() |
37cdb34014 | ||
![]() |
5ee7b85cc4 | ||
![]() |
1f7228f95a | ||
![]() |
fa8418adcd | ||
![]() |
d3b1765ffe | ||
![]() |
0a274ebadb | ||
![]() |
0d1b35edc5 | ||
![]() |
d7e4ae53ce | ||
![]() |
61ceffc6f9 | ||
![]() |
0c422bfd21 | ||
![]() |
a0815b06a6 | ||
![]() |
bd02b7574a | ||
![]() |
1048d923d0 | ||
![]() |
9dbfcf4262 | ||
![]() |
8ea176b5f0 | ||
![]() |
90dcbadc52 | ||
![]() |
e4021bf830 | ||
![]() |
b8b453aba0 | ||
![]() |
aeec2377c1 | ||
![]() |
f8b0ffd39b | ||
![]() |
9953c3c823 | ||
![]() |
d227a07fe9 | ||
![]() |
7c394414d8 | ||
![]() |
1dfb22d02e | ||
![]() |
1847ad5622 | ||
![]() |
beb701ceb4 | ||
![]() |
2fbadea821 | ||
![]() |
bac561d8c7 | ||
![]() |
7bd261a02e | ||
![]() |
df99a889f0 | ||
![]() |
16c5892a1d | ||
![]() |
0236bbaf68 | ||
![]() |
2ca5a290c3 | ||
![]() |
66c388a644 | ||
![]() |
74a77ed271 | ||
![]() |
3d98e6cdc0 | ||
![]() |
831ae96e0f | ||
![]() |
113a91a73f |
@@ -8,10 +8,8 @@ echo "Configuring backend environment variables..."
|
||||
cd packages/backend
|
||||
rm -rf .env
|
||||
echo "
|
||||
HOST=localhost
|
||||
PROTOCOL=http
|
||||
PORT=$BACKEND_PORT
|
||||
WEB_APP_URL=https://$CODESPACE_NAME-$WEB_PORT.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN
|
||||
WEB_APP_URL=http://localhost:$WEB_PORT
|
||||
APP_ENV=development
|
||||
POSTGRES_DATABASE=automatisch
|
||||
POSTGRES_PORT=5432
|
||||
@@ -30,8 +28,7 @@ cd packages/web
|
||||
rm -rf .env
|
||||
echo "
|
||||
PORT=$WEB_PORT
|
||||
REACT_APP_GRAPHQL_URL=https://$CODESPACE_NAME-$BACKEND_PORT.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN/graphql
|
||||
REACT_APP_BASE_URL=https://$CODESPACE_NAME-$WEB_PORT.$GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN
|
||||
REACT_APP_GRAPHQL_URL=http://localhost:$BACKEND_PORT/graphql
|
||||
REACT_APP_NOTIFICATIONS_URL=https://notifications.automatisch.io
|
||||
" >> .env
|
||||
cd $CURRENT_DIR
|
||||
|
@@ -21,10 +21,18 @@ services:
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
ports:
|
||||
- '5432:5432'
|
||||
expose:
|
||||
- 5432
|
||||
redis:
|
||||
image: 'redis:7.0.4-alpine'
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
ports:
|
||||
- '6379:6379'
|
||||
expose:
|
||||
- 6379
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
|
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@@ -0,0 +1,8 @@
|
||||
**/node_modules/
|
||||
**/dist/
|
||||
**/logs/
|
||||
**/.devcontainer
|
||||
**/.github
|
||||
**/.vscode
|
||||
packages/docs
|
||||
packages/e2e-test
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -125,3 +125,6 @@ dist
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# MacOS finder preferences
|
||||
.DS_store
|
||||
|
5
CONTRIBUTOR_LICENSE_AGREEMENT.md
Normal file
5
CONTRIBUTOR_LICENSE_AGREEMENT.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Automatisch Contributor License Agreement
|
||||
|
||||
I give Automatisch permission to license my contributions on any terms they like. I am giving them this license in order to make it possible for them to accept my contributions into their project.
|
||||
|
||||
**_As far as the law allows, my contributions come as is, without any warranty or condition, and I will not be liable to anyone for any damages related to this software or this license, under any kind of legal claim._**
|
3
LICENSE
Normal file
3
LICENSE
Normal file
@@ -0,0 +1,3 @@
|
||||
LICENSE.agpl (AGPL-3.0) applies to all files in this
|
||||
repository, except for files that contain ".ee." in their name
|
||||
which are covered by LICENSE.enterprise.
|
35
LICENSE.enterprise
Normal file
35
LICENSE.enterprise
Normal file
@@ -0,0 +1,35 @@
|
||||
The Automatisch Enterprise license (the “Enterprise License”)
|
||||
Copyright (c) 2023-present AB Software GmbH.
|
||||
|
||||
With regard to the Automatisch Software:
|
||||
|
||||
This software and associated documentation files (the "Software") may only be
|
||||
used in production, if you (and any entity that you represent) have a valid
|
||||
Automatisch Enterprise license for the correct number of user seats. Subject
|
||||
to the foregoing sentence, you are free to modify this Software and publish
|
||||
patches to the Software. You agree that Automatisch and/or its licensors
|
||||
(as applicable) retain all right, title and interest in and to all such
|
||||
modifications and/or patches, and all such modifications and/or patches may
|
||||
only be used, copied, modified, displayed, distributed, or otherwise exploited
|
||||
with a valid Automatisch Enterprise license for the correct number of user seats.
|
||||
Notwithstanding the foregoing, you may copy and modify the Software for
|
||||
development and testing purposes, without requiring a subscription. You agree
|
||||
that Automatisch and/or its licensors (as applicable) retain all right, title
|
||||
and interest in and to all such modifications. You are not granted any other
|
||||
rights beyond what is expressly stated herein. Subject to the foregoing, it is
|
||||
forbidden to copy, merge, publish, distribute, sublicense, and/or sell the Software.
|
||||
|
||||
The full text of this Enterprise License shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
For all third party components incorporated into the Automatisch Software, those
|
||||
components are licensed under the original license provided by the owner of the
|
||||
applicable component.
|
14
README.md
14
README.md
@@ -44,10 +44,18 @@ For other installation types, you can check the [installation](https://automatis
|
||||
|
||||
## Support
|
||||
|
||||
If you have any questions or problems, please visit our GitHub discussions page, and we'll try to help you as soon as possible.
|
||||
If you have any questions or problems, please visit our GitHub issues page, and we'll try to help you as soon as possible.
|
||||
|
||||
[https://github.com/automatisch/automatisch/discussions](https://github.com/automatisch/automatisch/discussions)
|
||||
[https://github.com/automatisch/automatisch/issues](https://github.com/automatisch/automatisch/issues)
|
||||
|
||||
## License
|
||||
|
||||
Automatisch is an open-source software with the [AGPL 3.0 license](https://github.com/automatisch/automatisch/blob/main/LICENSE.md).
|
||||
Automatisch Community Edition (Automatisch CE) is an open-source software with the [AGPL-3.0 license](LICENSE.agpl).
|
||||
|
||||
Automatisch Enterprise Edition (Automatisch EE) is a commercial offering with the [Enterprise license](LICENSE.enterprise).
|
||||
|
||||
The Automatisch repository contains both AGPL-licensed and Enterprise-licensed files. We maintain a single repository to make development easier.
|
||||
|
||||
All files that contain ".ee." in their name fall under the [Enterprise license](LICENSE.enterprise). All other files fall under the [AGPL-3.0 license](LICENSE.agpl).
|
||||
|
||||
See the [LICENSE](LICENSE) file for more information.
|
||||
|
@@ -2,13 +2,13 @@
|
||||
FROM node:16-alpine
|
||||
WORKDIR /automatisch
|
||||
|
||||
RUN apk --no-cache add --virtual build-dependencies python3 build-base
|
||||
RUN \
|
||||
apk --no-cache add --virtual build-dependencies python3 build-base && \
|
||||
yarn global add @automatisch/cli@0.7.1 --network-timeout 1000000 && \
|
||||
rm -rf /usr/local/share/.cache/ && \
|
||||
apk del build-dependencies
|
||||
|
||||
COPY ./entrypoint.sh /entrypoint.sh
|
||||
|
||||
RUN yarn global add @automatisch/cli@0.4.0 --network-timeout 1000000
|
||||
|
||||
RUN apk del build-dependencies python3 build-base
|
||||
|
||||
EXPOSE 3000
|
||||
ENTRYPOINT ["sh", "/entrypoint.sh"]
|
||||
|
19
docker/Dockerfile.cloud
Normal file
19
docker/Dockerfile.cloud
Normal file
@@ -0,0 +1,19 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM node:16-alpine
|
||||
WORKDIR /automatisch
|
||||
|
||||
ENV PORT 3000
|
||||
|
||||
RUN ls -lna
|
||||
|
||||
# copy the app, note .dockerignore
|
||||
COPY . ./
|
||||
|
||||
RUN yarn
|
||||
RUN yarn lerna bootstrap
|
||||
RUN yarn lerna run --scope=@*/{web,backend,cli} build
|
||||
|
||||
COPY ./docker/entrypoint-cloud.sh /entrypoint-cloud.sh
|
||||
|
||||
EXPOSE 3000
|
||||
ENTRYPOINT ["sh", "/entrypoint-cloud.sh"]
|
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM automatischio/automatisch:0.4.0
|
||||
FROM automatischio/automatisch:0.7.1
|
||||
WORKDIR /automatisch
|
||||
|
||||
RUN apk add --no-cache openssl dos2unix
|
||||
|
9
docker/entrypoint-cloud.sh
Executable file
9
docker/entrypoint-cloud.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ -n "$WORKER" ]; then
|
||||
yarn automatisch start-worker
|
||||
else
|
||||
yarn automatisch start
|
||||
fi
|
@@ -2,7 +2,7 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.4.0",
|
||||
"version": "0.7.1",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@automatisch/root",
|
||||
"license": "AGPL-3.0",
|
||||
"license": "See LICENSE file",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "lerna run --stream --parallel --scope=@*/{web,backend} dev",
|
||||
|
@@ -12,6 +12,8 @@ export async function createUser(
|
||||
const userParams = {
|
||||
email,
|
||||
password,
|
||||
fullName: 'Initial admin',
|
||||
role: 'admin',
|
||||
};
|
||||
|
||||
try {
|
||||
|
@@ -12,6 +12,7 @@ const knexConfig = {
|
||||
database: appConfig.postgresDatabase,
|
||||
ssl: appConfig.postgresEnableSsl,
|
||||
},
|
||||
searchPath: [appConfig.postgresSchema],
|
||||
pool: { min: 0, max: 20 },
|
||||
migrations: {
|
||||
directory: __dirname + '/src/db/migrations',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@automatisch/backend",
|
||||
"version": "0.4.0",
|
||||
"license": "AGPL-3.0",
|
||||
"version": "0.7.1",
|
||||
"license": "See LICENSE file",
|
||||
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
|
||||
"scripts": {
|
||||
"dev": "ts-node-dev --exit-child src/server.ts",
|
||||
@@ -17,16 +17,18 @@
|
||||
"db:migration:create": "knex migrate:make",
|
||||
"db:rollback": "knex migrate:rollback",
|
||||
"db:migrate": "knex migrate:latest",
|
||||
"copy-statics": "copyfiles src/**/*.{graphql,json,svg} dist",
|
||||
"copy-statics": "copyfiles src/**/*.{graphql,json,svg,hbs} dist",
|
||||
"prepack": "yarn build",
|
||||
"prebuild": "rm -rf ./dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@automatisch/web": "^0.4.0",
|
||||
"@automatisch/web": "^0.7.1",
|
||||
"@bull-board/express": "^3.10.1",
|
||||
"@graphql-tools/graphql-file-loader": "^7.3.4",
|
||||
"@graphql-tools/load": "^7.5.2",
|
||||
"@rudderstack/rudder-sdk-node": "^1.1.2",
|
||||
"@sentry/node": "^7.42.0",
|
||||
"@sentry/tracing": "^7.42.0",
|
||||
"@types/luxon": "^2.3.1",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"axios": "0.24.0",
|
||||
@@ -45,17 +47,21 @@
|
||||
"graphql-shield": "^7.5.0",
|
||||
"graphql-tools": "^8.2.0",
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"handlebars": "^4.7.7",
|
||||
"http-errors": "~1.6.3",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"knex": "^2.4.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"luxon": "2.5.2",
|
||||
"memory-cache": "^0.2.0",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"nodemailer": "6.7.0",
|
||||
"oauth-1.0a": "^2.2.6",
|
||||
"objection": "^3.0.0",
|
||||
"pg": "^8.7.1",
|
||||
"php-serialize": "^4.0.2",
|
||||
"stripe": "^11.13.0",
|
||||
"winston": "^3.7.1"
|
||||
},
|
||||
"contributors": [
|
||||
@@ -94,7 +100,7 @@
|
||||
"url": "https://github.com/automatisch/automatisch/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@automatisch/types": "^0.4.0",
|
||||
"@automatisch/types": "^0.7.1",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/bull": "^3.15.8",
|
||||
"@types/cors": "^2.8.12",
|
||||
@@ -103,6 +109,7 @@
|
||||
"@types/http-errors": "^1.8.1",
|
||||
"@types/jsonwebtoken": "^8.5.8",
|
||||
"@types/lodash.get": "^4.4.6",
|
||||
"@types/memory-cache": "^0.2.2",
|
||||
"@types/morgan": "^1.9.3",
|
||||
"@types/multer": "1.4.7",
|
||||
"@types/node": "^16.10.2",
|
||||
|
@@ -1,9 +1,12 @@
|
||||
import createError from 'http-errors';
|
||||
import express from 'express';
|
||||
import appConfig from './config/app';
|
||||
import cors from 'cors';
|
||||
|
||||
import { IRequest } from '@automatisch/types';
|
||||
import appConfig from './config/app';
|
||||
import corsOptions from './config/cors-options';
|
||||
import morgan from './helpers/morgan';
|
||||
import * as Sentry from './helpers/sentry.ee';
|
||||
import appAssetsHandler from './helpers/app-assets-handler';
|
||||
import webUIHandler from './helpers/web-ui-handler';
|
||||
import errorHandler from './helpers/error-handler';
|
||||
@@ -14,12 +17,16 @@ import {
|
||||
} from './helpers/create-bull-board-handler';
|
||||
import injectBullBoardHandler from './helpers/inject-bull-board-handler';
|
||||
import router from './routes';
|
||||
import { IRequest } from '@automatisch/types';
|
||||
|
||||
createBullBoardHandler(serverAdapter);
|
||||
|
||||
const app = express();
|
||||
|
||||
Sentry.init(app);
|
||||
|
||||
Sentry.attachRequestHandler(app);
|
||||
Sentry.attachTracingHandler(app);
|
||||
|
||||
injectBullBoardHandler(app, serverAdapter);
|
||||
|
||||
appAssetsHandler(app);
|
||||
@@ -33,13 +40,15 @@ app.use(
|
||||
},
|
||||
})
|
||||
);
|
||||
app.use(express.urlencoded({
|
||||
extended: false,
|
||||
limit: appConfig.requestBodySizeLimit,
|
||||
verify(req, res, buf) {
|
||||
(req as IRequest).rawBody = buf;
|
||||
},
|
||||
}));
|
||||
app.use(
|
||||
express.urlencoded({
|
||||
extended: true,
|
||||
limit: appConfig.requestBodySizeLimit,
|
||||
verify(req, res, buf) {
|
||||
(req as IRequest).rawBody = buf;
|
||||
},
|
||||
})
|
||||
);
|
||||
app.use(cors(corsOptions));
|
||||
app.use('/', router);
|
||||
|
||||
@@ -50,6 +59,8 @@ app.use(function (req, res, next) {
|
||||
next(createError(404));
|
||||
});
|
||||
|
||||
Sentry.attachErrorHandler(app);
|
||||
|
||||
app.use(errorHandler);
|
||||
|
||||
export default app;
|
||||
|
@@ -2,7 +2,7 @@ import qs from 'qs';
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Translate Text',
|
||||
name: 'Translate text',
|
||||
key: 'translateText',
|
||||
description: 'Translates text from one language to another.',
|
||||
arguments: [
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Delay For',
|
||||
name: 'Delay for',
|
||||
key: 'delayFor',
|
||||
description:
|
||||
'Delays the execution of the next action by a specified amount of time.',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Delay Until',
|
||||
name: 'Delay until',
|
||||
key: 'delayUntil',
|
||||
description:
|
||||
'Delays the execution of the next action until a specified date.',
|
||||
|
@@ -0,0 +1,36 @@
|
||||
import path from 'node:path';
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create folder',
|
||||
key: 'createFolder',
|
||||
description: 'Create a new folder with the given parent folder and folder name',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Folder',
|
||||
key: 'parentFolder',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Enter the parent folder path, like /TextFiles/ or /Documents/Taxes/',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Folder Name',
|
||||
key: 'folderName',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Enter the name for the new folder',
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const parentFolder = $.step.parameters.parentFolder as string;
|
||||
const folderName = $.step.parameters.folderName as string;
|
||||
const folderPath = path.join(parentFolder, folderName);
|
||||
|
||||
const response = await $.http.post('/2/files/create_folder_v2', { path: folderPath });
|
||||
|
||||
$.setActionItem({ raw: response.data });
|
||||
},
|
||||
});
|
4
packages/backend/src/apps/dropbox/actions/index.ts
Normal file
4
packages/backend/src/apps/dropbox/actions/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import createFolder from "./create-folder";
|
||||
import renameFile from "./rename-file";
|
||||
|
||||
export default [createFolder, renameFile];
|
@@ -0,0 +1,45 @@
|
||||
import path from 'node:path';
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Rename file',
|
||||
key: 'renameFile',
|
||||
description: 'Rename a file with the given file path and new name',
|
||||
arguments: [
|
||||
{
|
||||
label: 'File Path',
|
||||
key: 'filePath',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description:
|
||||
'Write the full path to the file such as /Folder1/File.pdf',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'New Name',
|
||||
key: 'newName',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: "Enter the new name for the file (without the extension, e.g., '.pdf')",
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const filePath = $.step.parameters.filePath as string;
|
||||
const newName = $.step.parameters.newName as string;
|
||||
const fileObject = path.parse(filePath);
|
||||
const newPath = path.format({
|
||||
dir: fileObject.dir,
|
||||
ext: fileObject.ext,
|
||||
name: newName,
|
||||
});
|
||||
|
||||
const response = await $.http.post('/2/files/move_v2', {
|
||||
from_path: filePath,
|
||||
to_path: newPath,
|
||||
});
|
||||
|
||||
$.setActionItem({ raw: response.data.metadata });
|
||||
},
|
||||
});
|
3
packages/backend/src/apps/dropbox/assets/favicon.svg
Normal file
3
packages/backend/src/apps/dropbox/assets/favicon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Dropbox" role="img" viewBox="0 0 512 512" fill="#0061ff">
|
||||
<path d="M158 101l-99 63 295 188 99-63m-99-188l99 63-295 188-99-63m99 83l98 63 98-63-98-62z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 213 B |
22
packages/backend/src/apps/dropbox/auth/generate-auth-url.ts
Normal file
22
packages/backend/src/apps/dropbox/auth/generate-auth-url.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { URLSearchParams } from 'url';
|
||||
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||
import scopes from '../common/scopes';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const callbackUrl = oauthRedirectUrlField.value as string;
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: callbackUrl,
|
||||
response_type: 'code',
|
||||
scope: scopes.join(' '),
|
||||
token_access_type: 'offline',
|
||||
});
|
||||
|
||||
const url = `${$.app.baseUrl}/oauth2/authorize?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({ url });
|
||||
}
|
48
packages/backend/src/apps/dropbox/auth/index.ts
Normal file
48
packages/backend/src/apps/dropbox/auth/index.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
import refreshToken from './refresh-token';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'oAuthRedirectUrl',
|
||||
label: 'OAuth Redirect URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: true,
|
||||
value: '{WEB_APP_URL}/app/dropbox/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input an OAuth callback or redirect URL in Dropbox OAuth, enter the URL above.',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'clientId',
|
||||
label: 'App Key',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'clientSecret',
|
||||
label: 'App Secret',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
generateAuthUrl,
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
refreshToken,
|
||||
};
|
@@ -0,0 +1,9 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentAccount from '../common/get-current-account';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
const account = await getCurrentAccount($);
|
||||
return !!account;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
41
packages/backend/src/apps/dropbox/auth/refresh-token.ts
Normal file
41
packages/backend/src/apps/dropbox/auth/refresh-token.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Buffer } from 'node:buffer';
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const refreshToken = async ($: IGlobalVariable) => {
|
||||
const params = {
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: $.auth.data.refreshToken as string,
|
||||
};
|
||||
|
||||
const basicAuthToken = Buffer
|
||||
.from(`${$.auth.data.clientId}:${$.auth.data.clientSecret}`)
|
||||
.toString('base64');
|
||||
|
||||
const { data } = await $.http.post(
|
||||
'oauth2/token',
|
||||
null,
|
||||
{
|
||||
params,
|
||||
headers: {
|
||||
Authorization: `Basic ${basicAuthToken}`
|
||||
},
|
||||
additionalProperties: {
|
||||
skipAddingAuthHeader: true
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const {
|
||||
access_token: accessToken,
|
||||
expires_in: expiresIn,
|
||||
token_type: tokenType,
|
||||
} = data;
|
||||
|
||||
await $.auth.set({
|
||||
accessToken,
|
||||
expiresIn,
|
||||
tokenType,
|
||||
});
|
||||
};
|
||||
|
||||
export default refreshToken;
|
102
packages/backend/src/apps/dropbox/auth/verify-credentials.ts
Normal file
102
packages/backend/src/apps/dropbox/auth/verify-credentials.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { IGlobalVariable, IField } from '@automatisch/types';
|
||||
import getCurrentAccount from '../common/get-current-account';
|
||||
|
||||
type TAccount = {
|
||||
account_id: string,
|
||||
name: {
|
||||
given_name: string,
|
||||
surname: string,
|
||||
familiar_name: string,
|
||||
display_name: string,
|
||||
abbreviated_name: string,
|
||||
},
|
||||
email: string,
|
||||
email_verified: boolean,
|
||||
disabled: boolean,
|
||||
country: string,
|
||||
locale: string,
|
||||
referral_link: string,
|
||||
is_paired: boolean,
|
||||
account_type: {
|
||||
".tag": string,
|
||||
},
|
||||
root_info: {
|
||||
".tag": string,
|
||||
root_namespace_id: string,
|
||||
home_namespace_id: string,
|
||||
},
|
||||
}
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const redirectUrl = oauthRedirectUrlField.value as string;
|
||||
const params = {
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: redirectUrl,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
code: $.auth.data.code as string,
|
||||
grant_type: 'authorization_code',
|
||||
}
|
||||
const { data: verifiedCredentials } = await $.http.post(
|
||||
'/oauth2/token',
|
||||
null,
|
||||
{ params }
|
||||
);
|
||||
|
||||
const {
|
||||
access_token: accessToken,
|
||||
refresh_token: refreshToken,
|
||||
expires_in: expiresIn,
|
||||
scope: scope,
|
||||
token_type: tokenType,
|
||||
account_id: accountId,
|
||||
team_id: teamId,
|
||||
id_token: idToken,
|
||||
uid,
|
||||
} = verifiedCredentials;
|
||||
|
||||
await $.auth.set({
|
||||
accessToken,
|
||||
refreshToken,
|
||||
expiresIn,
|
||||
scope,
|
||||
tokenType,
|
||||
accountId,
|
||||
teamId,
|
||||
idToken,
|
||||
uid
|
||||
});
|
||||
|
||||
const account = await getCurrentAccount($) as TAccount;
|
||||
|
||||
await $.auth.set({
|
||||
accountId: account.account_id,
|
||||
name: {
|
||||
givenName: account.name.given_name,
|
||||
surname: account.name.surname,
|
||||
familiarName: account.name.familiar_name,
|
||||
displayName: account.name.display_name,
|
||||
abbreviatedName: account.name.abbreviated_name,
|
||||
},
|
||||
email: account.email,
|
||||
emailVerified: account.email_verified,
|
||||
disabled: account.disabled,
|
||||
country: account.country,
|
||||
locale: account.locale,
|
||||
referralLink: account.referral_link,
|
||||
isPaired: account.is_paired,
|
||||
accountType: {
|
||||
".tag": account.account_type['.tag'],
|
||||
},
|
||||
rootInfo: {
|
||||
".tag": account.root_info['.tag'],
|
||||
rootNamespaceId: account.root_info.root_namespace_id,
|
||||
homeNamespaceId: account.root_info.home_namespace_id,
|
||||
},
|
||||
screenName: `${account.name.display_name} - ${account.email}`,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
13
packages/backend/src/apps/dropbox/common/add-auth-header.ts
Normal file
13
packages/backend/src/apps/dropbox/common/add-auth-header.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
requestConfig.headers['Content-Type'] = 'application/json';
|
||||
|
||||
if (!requestConfig.additionalProperties?.skipAddingAuthHeader && $.auth.data?.accessToken) {
|
||||
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
@@ -0,0 +1,8 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
const getCurrentAccount = async ($: IGlobalVariable): Promise<IJSONObject> => {
|
||||
const response = await $.http.post('/2/users/get_current_account', null);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default getCurrentAccount;
|
8
packages/backend/src/apps/dropbox/common/scopes.ts
Normal file
8
packages/backend/src/apps/dropbox/common/scopes.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
const scopes = [
|
||||
'account_info.read',
|
||||
'files.metadata.read',
|
||||
'files.content.write',
|
||||
'files.content.read',
|
||||
];
|
||||
|
||||
export default scopes;
|
0
packages/backend/src/apps/dropbox/index.d.ts
vendored
Normal file
0
packages/backend/src/apps/dropbox/index.d.ts
vendored
Normal file
18
packages/backend/src/apps/dropbox/index.ts
Normal file
18
packages/backend/src/apps/dropbox/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import auth from './auth';
|
||||
import actions from './actions';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Dropbox',
|
||||
key: 'dropbox',
|
||||
iconUrl: '{BASE_URL}/apps/dropbox/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/dropbox/connection',
|
||||
supportsConnections: true,
|
||||
baseUrl: 'https://dropbox.com',
|
||||
apiBaseUrl: 'https://api.dropboxapi.com',
|
||||
primaryColor: '0061ff',
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
actions,
|
||||
});
|
109
packages/backend/src/apps/filter/actions/continue/index.ts
Normal file
109
packages/backend/src/apps/filter/actions/continue/index.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
type TGroupItem = {
|
||||
key: string;
|
||||
operator: keyof TOperators;
|
||||
value: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
type TGroup = Record<'and', TGroupItem[]>;
|
||||
|
||||
const isEqual = (a: string, b: string) => a === b;
|
||||
const isNotEqual = (a: string, b: string) => !isEqual(a, b);
|
||||
const isGreaterThan = (a: string, b: string) => Number(a) > Number(b);
|
||||
const isLessThan = (a: string, b: string) => Number(a) < Number(b);
|
||||
const isGreaterThanOrEqual = (a: string, b: string) => Number(a) >= Number(b);
|
||||
const isLessThanOrEqual = (a: string, b: string) => Number(a) <= Number(b);
|
||||
const contains = (a: string, b: string) => a.includes(b);
|
||||
const doesNotContain = (a: string, b: string) => !contains(a, b);
|
||||
|
||||
const shouldContinue = (orGroups: TGroup[]) => {
|
||||
let atLeastOneGroupMatches = false;
|
||||
|
||||
for (const group of orGroups) {
|
||||
let groupMatches = true;
|
||||
|
||||
for (const condition of group.and) {
|
||||
const conditionMatches = operate(
|
||||
condition.operator,
|
||||
condition.key,
|
||||
condition.value
|
||||
);
|
||||
|
||||
if (!conditionMatches) {
|
||||
groupMatches = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (groupMatches) {
|
||||
atLeastOneGroupMatches = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return atLeastOneGroupMatches;
|
||||
}
|
||||
|
||||
type TOperatorFunc = (a: string, b: string) => boolean;
|
||||
|
||||
type TOperators = {
|
||||
equal: TOperatorFunc;
|
||||
not_equal: TOperatorFunc;
|
||||
greater_than: TOperatorFunc;
|
||||
less_than: TOperatorFunc;
|
||||
greater_than_or_equal: TOperatorFunc;
|
||||
less_than_or_equal: TOperatorFunc;
|
||||
contains: TOperatorFunc;
|
||||
not_contains: TOperatorFunc;
|
||||
};
|
||||
|
||||
const operators: TOperators = {
|
||||
'equal': isEqual,
|
||||
'not_equal': isNotEqual,
|
||||
'greater_than': isGreaterThan,
|
||||
'less_than': isLessThan,
|
||||
'greater_than_or_equal': isGreaterThanOrEqual,
|
||||
'less_than_or_equal': isLessThanOrEqual,
|
||||
'contains': contains,
|
||||
'not_contains': doesNotContain,
|
||||
};
|
||||
|
||||
const operate = (operation: keyof TOperators, a: string, b: string) => {
|
||||
return operators[operation](a, b);
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Continue if conditions match',
|
||||
key: 'continueIfMatches',
|
||||
description: 'Let the execution continue if the conditions match',
|
||||
arguments: [],
|
||||
|
||||
async run($) {
|
||||
const orGroups = $.step.parameters.or as TGroup[];
|
||||
|
||||
const matchingGroups = orGroups.reduce((groups, group) => {
|
||||
const matchingConditions = group.and
|
||||
.filter((condition) => operate(condition.operator, condition.key, condition.value));
|
||||
|
||||
if (matchingConditions.length) {
|
||||
return groups.concat([{ and: matchingConditions }]);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}, []);
|
||||
|
||||
if (!shouldContinue(orGroups)) {
|
||||
$.execution.exit();
|
||||
}
|
||||
|
||||
$.setActionItem({
|
||||
raw: {
|
||||
or: matchingGroups,
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
3
packages/backend/src/apps/filter/actions/index.ts
Normal file
3
packages/backend/src/apps/filter/actions/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import continueIfMatches from './continue';
|
||||
|
||||
export default [continueIfMatches];
|
8
packages/backend/src/apps/filter/assets/favicon.svg
Normal file
8
packages/backend/src/apps/filter/assets/favicon.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="800px" height="800px" viewBox="0 0 512 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Shape" fill="#000000" transform="translate(42.666667, 85.333333)">
|
||||
<path d="M3.55271368e-14,1.42108547e-14 L191.565013,234.666667 L192,234.666667 L192,384 L234.666667,384 L234.666667,234.666667 L426.666667,1.42108547e-14 L3.55271368e-14,1.42108547e-14 Z M214.448,192 L211.81248,192 L89.9076267,42.6666667 L336.630187,42.6666667 L214.448,192 Z">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 628 B |
0
packages/backend/src/apps/filter/index.d.ts
vendored
Normal file
0
packages/backend/src/apps/filter/index.d.ts
vendored
Normal file
14
packages/backend/src/apps/filter/index.ts
Normal file
14
packages/backend/src/apps/filter/index.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import actions from './actions';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Filter',
|
||||
key: 'filter',
|
||||
iconUrl: '{BASE_URL}/apps/filter/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/filter/connection',
|
||||
supportsConnections: false,
|
||||
baseUrl: '',
|
||||
apiBaseUrl: '',
|
||||
primaryColor: '001F52',
|
||||
actions,
|
||||
});
|
@@ -20,12 +20,14 @@ export default defineTrigger({
|
||||
],
|
||||
|
||||
async testRun($) {
|
||||
if (!isEmpty($.lastExecutionStep?.dataOut)) {
|
||||
const lastExecutionStep = await $.getLastExecutionStep();
|
||||
|
||||
if (!isEmpty(lastExecutionStep?.dataOut)) {
|
||||
$.pushTriggerItem({
|
||||
raw: $.lastExecutionStep.dataOut,
|
||||
raw: lastExecutionStep.dataOut,
|
||||
meta: {
|
||||
internalId: '',
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -35,20 +37,15 @@ export default defineTrigger({
|
||||
name: $.flow.id,
|
||||
type: 'POST',
|
||||
url: $.webhookUrl,
|
||||
filters: [$.step.parameters.filters]
|
||||
filters: [$.step.parameters.filters],
|
||||
};
|
||||
|
||||
const { data } = await $.http.post(
|
||||
`/v2/public/api/webhooks`,
|
||||
payload
|
||||
);
|
||||
const { data } = await $.http.post(`/v2/public/api/webhooks`, payload);
|
||||
|
||||
await $.flow.setRemoteWebhookId(data.id);
|
||||
},
|
||||
|
||||
async unregisterHook($) {
|
||||
await $.http.delete(
|
||||
`/v2/public/api/webhooks/${$.flow.remoteWebhookId}`
|
||||
);
|
||||
await $.http.delete(`/v2/public/api/webhooks/${$.flow.remoteWebhookId}`);
|
||||
},
|
||||
});
|
||||
|
2
packages/backend/src/apps/gitlab/assets/favicon.svg
Normal file
2
packages/backend/src/apps/gitlab/assets/favicon.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<!-- https://about.gitlab.com/images/press/logo/svg/gitlab-logo-500.svg -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380"><defs><style>.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style></defs><g id="LOGO"><path class="cls-1" d="M282.83,170.73l-.27-.69-26.14-68.22a6.81,6.81,0,0,0-2.69-3.24,7,7,0,0,0-8,.43,7,7,0,0,0-2.32,3.52l-17.65,54H154.29l-17.65-54A6.86,6.86,0,0,0,134.32,99a7,7,0,0,0-8-.43,6.87,6.87,0,0,0-2.69,3.24L97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82,19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91,40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-2" d="M282.83,170.73l-.27-.69a88.3,88.3,0,0,0-35.15,15.8L190,229.25c19.55,14.79,36.57,27.64,36.57,27.64l40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-3" d="M153.43,256.89l19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91S209.55,244,190,229.25C170.45,244,153.43,256.89,153.43,256.89Z"/><path class="cls-2" d="M132.58,185.84A88.19,88.19,0,0,0,97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82s17-12.85,36.57-27.64Z"/></g></svg>
|
After Width: | Height: | Size: 1.1 KiB |
24
packages/backend/src/apps/gitlab/auth/generate-auth-url.ts
Normal file
24
packages/backend/src/apps/gitlab/auth/generate-auth-url.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { URL, URLSearchParams } from 'url';
|
||||
import getBaseUrl from '../common/get-base-url';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const scopes = ['api', 'read_user'];
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: $.auth.data.oAuthRedirectUrl as string,
|
||||
scope: scopes.join(' '),
|
||||
response_type: 'code',
|
||||
state: Date.now().toString(),
|
||||
});
|
||||
|
||||
const baseUrl = getBaseUrl($);
|
||||
const path = `/oauth/authorize?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({
|
||||
url: new URL(path, baseUrl).toString(),
|
||||
});
|
||||
}
|
63
packages/backend/src/apps/gitlab/auth/index.ts
Normal file
63
packages/backend/src/apps/gitlab/auth/index.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
import refreshToken from './refresh-token';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'oAuthRedirectUrl',
|
||||
label: 'OAuth Redirect URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: true,
|
||||
value: '{WEB_APP_URL}/app/gitlab/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input an OAuth callback or redirect URL in Gitlab OAuth, enter the URL above.',
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'instanceUrl',
|
||||
label: 'Gitlab instance URL',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
value: 'https://gitlab.com',
|
||||
placeholder: 'https://gitlab.com',
|
||||
description: 'Your Gitlab instance URL. Default is https://gitlab.com.',
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'clientId',
|
||||
label: 'Client ID',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#client-id',
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'clientSecret',
|
||||
label: 'Client Secret',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
docUrl: 'https://automatisch.io/docs/gitlab#client-secret',
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
generateAuthUrl,
|
||||
refreshToken,
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
};
|
@@ -0,0 +1,9 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
const user = await getCurrentUser($);
|
||||
return !!user.id;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
24
packages/backend/src/apps/gitlab/auth/refresh-token.ts
Normal file
24
packages/backend/src/apps/gitlab/auth/refresh-token.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
|
||||
const refreshToken = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const params = new URLSearchParams({
|
||||
grant_type: 'refresh_token',
|
||||
client_id: $.auth.data.clientId as string,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
refresh_token: $.auth.data.refreshToken as string,
|
||||
});
|
||||
|
||||
const { data } = await $.http.post('/oauth/token', params.toString());
|
||||
|
||||
await $.auth.set({
|
||||
accessToken: data.access_token,
|
||||
expiresIn: data.expires_in,
|
||||
tokenType: data.token_type,
|
||||
refreshToken: data.refresh_token,
|
||||
});
|
||||
};
|
||||
|
||||
export default refreshToken;
|
41
packages/backend/src/apps/gitlab/auth/verify-credentials.ts
Normal file
41
packages/backend/src/apps/gitlab/auth/verify-credentials.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
|
||||
|
||||
const response = await $.http.post(
|
||||
'/oauth/token',
|
||||
{
|
||||
client_id: $.auth.data.clientId,
|
||||
client_secret: $.auth.data.clientSecret,
|
||||
code: $.auth.data.code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: $.auth.data.oAuthRedirectUrl,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = response.data;
|
||||
|
||||
$.auth.data.accessToken = data.access_token;
|
||||
|
||||
const currentUser = await getCurrentUser($);
|
||||
|
||||
await $.auth.set({
|
||||
clientId: $.auth.data.clientId,
|
||||
clientSecret: $.auth.data.clientSecret,
|
||||
accessToken: data.access_token,
|
||||
refreshToken: data.refresh_token,
|
||||
scope: data.scope,
|
||||
tokenType: data.token_type,
|
||||
userId: currentUser.id,
|
||||
screenName: `${currentUser.username} @ ${$.auth.data.instanceUrl}`,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
11
packages/backend/src/apps/gitlab/common/add-auth-header.ts
Normal file
11
packages/backend/src/apps/gitlab/common/add-auth-header.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data?.accessToken) {
|
||||
requestConfig.headers = requestConfig.headers || {};
|
||||
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`;
|
||||
}
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
15
packages/backend/src/apps/gitlab/common/get-base-url.ts
Normal file
15
packages/backend/src/apps/gitlab/common/get-base-url.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const getBaseUrl = ($: IGlobalVariable): string => {
|
||||
if ($.auth.data.instanceUrl) {
|
||||
return $.auth.data.instanceUrl as string;
|
||||
}
|
||||
|
||||
if ($.app.apiBaseUrl) {
|
||||
return $.app.apiBaseUrl;
|
||||
}
|
||||
|
||||
return $.app.baseUrl;
|
||||
};
|
||||
|
||||
export default getBaseUrl;
|
11
packages/backend/src/apps/gitlab/common/get-current-user.ts
Normal file
11
packages/backend/src/apps/gitlab/common/get-current-user.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
const getCurrentUser = async ($: IGlobalVariable): Promise<IJSONObject> => {
|
||||
// ref: https://docs.gitlab.com/ee/api/users.html#list-current-user
|
||||
|
||||
const response = await $.http.get('/api/v4/user');
|
||||
const currentUser = response.data;
|
||||
return currentUser;
|
||||
};
|
||||
|
||||
export default getCurrentUser;
|
33
packages/backend/src/apps/gitlab/common/paginate-all.ts
Normal file
33
packages/backend/src/apps/gitlab/common/paginate-all.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import parseLinkHeader from '../../../helpers/parse-header-link';
|
||||
|
||||
type TResponse = {
|
||||
data: IJSONObject[];
|
||||
error?: IJSONObject;
|
||||
};
|
||||
|
||||
export default async function paginateAll(
|
||||
$: IGlobalVariable,
|
||||
request: Promise<AxiosResponse>
|
||||
) {
|
||||
const response = await request;
|
||||
|
||||
const aggregatedResponse: TResponse = {
|
||||
data: [...response.data],
|
||||
};
|
||||
|
||||
let links = parseLinkHeader(response.headers.link);
|
||||
|
||||
while (links.next) {
|
||||
const nextPageResponse = await $.http.request({
|
||||
...response.config,
|
||||
url: links.next.uri,
|
||||
});
|
||||
|
||||
aggregatedResponse.data.push(...nextPageResponse.data);
|
||||
links = parseLinkHeader(nextPageResponse.headers.link);
|
||||
}
|
||||
|
||||
return aggregatedResponse;
|
||||
}
|
13
packages/backend/src/apps/gitlab/common/set-base-url.ts
Normal file
13
packages/backend/src/apps/gitlab/common/set-base-url.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const setBaseUrl: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data.instanceUrl) {
|
||||
requestConfig.baseURL = $.auth.data.instanceUrl as string;
|
||||
} else if ($.app.apiBaseUrl) {
|
||||
requestConfig.baseURL = $.app.apiBaseUrl as string;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default setBaseUrl;
|
3
packages/backend/src/apps/gitlab/dynamic-data/index.ts
Normal file
3
packages/backend/src/apps/gitlab/dynamic-data/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import listProjects from './list-projects';
|
||||
|
||||
export default [listProjects];
|
@@ -0,0 +1,33 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import paginateAll from '../../common/paginate-all';
|
||||
|
||||
export default {
|
||||
name: 'List projects',
|
||||
key: 'listProjects',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
// ref:
|
||||
// - https://docs.gitlab.com/ee/api/projects.html#list-all-projects
|
||||
// - https://docs.gitlab.com/ee/api/rest/index.html#keyset-based-pagination
|
||||
|
||||
const firstPageRequest = $.http.get('/api/v4/projects', {
|
||||
params: {
|
||||
simple: true,
|
||||
pagination: 'keyset',
|
||||
order_by: 'id',
|
||||
sort: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
const response = await paginateAll($, firstPageRequest);
|
||||
|
||||
response.data = response.data.map((repo: { name: string; id: number }) => {
|
||||
return {
|
||||
value: repo.id,
|
||||
name: repo.name,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
};
|
1
packages/backend/src/apps/gitlab/index.d.ts
vendored
Normal file
1
packages/backend/src/apps/gitlab/index.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
|
21
packages/backend/src/apps/gitlab/index.ts
Normal file
21
packages/backend/src/apps/gitlab/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import setBaseUrl from './common/set-base-url';
|
||||
import auth from './auth';
|
||||
import triggers from './triggers';
|
||||
import dynamicData from './dynamic-data';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Gitlab',
|
||||
key: 'gitlab',
|
||||
baseUrl: 'https://gitlab.com',
|
||||
apiBaseUrl: 'https://gitlab.com',
|
||||
iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/gitlab/connection',
|
||||
primaryColor: 'FC6D26',
|
||||
supportsConnections: true,
|
||||
beforeRequest: [setBaseUrl, addAuthHeader],
|
||||
auth,
|
||||
triggers,
|
||||
dynamicData,
|
||||
});
|
@@ -0,0 +1,27 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
// confidential_issues_events has the same event data as issues_events
|
||||
import data from './issue_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Confidential issue event',
|
||||
description:
|
||||
'Confidential issue event (triggered when a new confidential issue is created or an existing issue is updated, closed, or reopened)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
|
||||
key: GITLAB_EVENT_TYPE.confidential_issues_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_issues_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,159 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
|
||||
|
||||
export default {
|
||||
object_kind: 'issue',
|
||||
event_type: 'issue',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 301,
|
||||
title: 'New API: create/update/delete file',
|
||||
assignee_ids: [51],
|
||||
assignee_id: 51,
|
||||
author_id: 51,
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
updated_by_id: 1,
|
||||
last_edited_at: null,
|
||||
last_edited_by_id: null,
|
||||
relative_position: 0,
|
||||
description: 'Create new API for manipulations with repository',
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
confidential: false,
|
||||
discussion_locked: true,
|
||||
due_date: null,
|
||||
moved_to_id: null,
|
||||
duplicated_to_id: null,
|
||||
time_estimate: 0,
|
||||
total_time_spent: 0,
|
||||
time_change: 0,
|
||||
human_total_time_spent: null,
|
||||
human_time_estimate: null,
|
||||
human_time_change: null,
|
||||
weight: null,
|
||||
iid: 23,
|
||||
url: 'http://example.com/diaspora/issues/23',
|
||||
state: 'opened',
|
||||
action: 'open',
|
||||
severity: 'high',
|
||||
escalation_status: 'triggered',
|
||||
escalation_policy: {
|
||||
id: 18,
|
||||
name: 'Engineering On-call',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
assignee: {
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,27 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
// confidential_note_events has the same event data as note_events
|
||||
import data from './note_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Confidential comment event',
|
||||
description:
|
||||
'Confidential comment event (triggered when a new confidential comment is made on commits, merge requests, issues, and code snippets)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events',
|
||||
key: GITLAB_EVENT_TYPE.confidential_note_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_note_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,74 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'note',
|
||||
event_type: 'note',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project_id: 5,
|
||||
project: {
|
||||
id: 5,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlab-org/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 1243,
|
||||
note: 'This is a commit comment. How does this work?',
|
||||
noteable_type: 'Commit',
|
||||
author_id: 1,
|
||||
created_at: '2015-05-17 18:08:09 UTC',
|
||||
updated_at: '2015-05-17 18:08:09 UTC',
|
||||
project_id: 5,
|
||||
attachment: null,
|
||||
line_code: 'bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1',
|
||||
commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
noteable_id: null,
|
||||
system: false,
|
||||
st_diff: {
|
||||
diff: '--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n',
|
||||
new_path: 'six',
|
||||
old_path: 'six',
|
||||
a_mode: '0',
|
||||
b_mode: '160000',
|
||||
new_file: true,
|
||||
renamed_file: false,
|
||||
deleted_file: false,
|
||||
},
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243',
|
||||
},
|
||||
commit: {
|
||||
id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
message:
|
||||
'Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n',
|
||||
timestamp: '2014-02-27T10:06:20+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,45 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'deployment',
|
||||
status: 'success',
|
||||
status_changed_at: '2021-04-28 21:50:00 +0200',
|
||||
deployment_id: 15,
|
||||
deployable_id: 796,
|
||||
deployable_url:
|
||||
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796',
|
||||
environment: 'staging',
|
||||
environment_slug: 'staging',
|
||||
environment_external_url: 'https://staging.example.com',
|
||||
project: {
|
||||
id: 30,
|
||||
name: 'test-deployment-webhooks',
|
||||
description: '',
|
||||
web_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
git_http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
|
||||
namespace: 'Administrator',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'root/test-deployment-webhooks',
|
||||
default_branch: 'master',
|
||||
ci_config_path: '',
|
||||
homepage: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
|
||||
url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
|
||||
http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
|
||||
},
|
||||
short_sha: '279484c0',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
user_url: 'http://10.126.0.2:3000/root',
|
||||
commit_url:
|
||||
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/commit/279484c09fbe69ededfced8c1bb6e6d24616b468',
|
||||
commit_title: 'Add new file',
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './deployment_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Deployment event',
|
||||
description:
|
||||
'Deployment event (triggered when a deployment starts, succeeds, fails or is canceled)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events',
|
||||
key: GITLAB_EVENT_TYPE.deployment_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.deployment_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,38 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events
|
||||
|
||||
export default {
|
||||
object_kind: 'feature_flag',
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
user_url: 'http://example.com/root',
|
||||
object_attributes: {
|
||||
id: 6,
|
||||
name: 'test-feature-flag',
|
||||
description: 'test-feature-flag-description',
|
||||
active: true,
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './feature_flag_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Feature flag event',
|
||||
description:
|
||||
'Feature flag event (triggered when a feature flag is turned on or off)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events',
|
||||
key: GITLAB_EVENT_TYPE.feature_flag_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.feature_flag_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
29
packages/backend/src/apps/gitlab/triggers/index.ts
Normal file
29
packages/backend/src/apps/gitlab/triggers/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import confidentialIssueEvent from './confidential-issue-event';
|
||||
import confidentialNoteEvent from './confidential-note-event';
|
||||
import deploymentEvent from './deployment-event';
|
||||
import featureFlagEvent from './feature-flag-event';
|
||||
import issueEvent from './issue-event';
|
||||
import jobEvent from './job-event';
|
||||
import mergeRequestEvent from './merge-request-event';
|
||||
import noteEvent from './note-event';
|
||||
import pipelineEvent from './pipeline-event';
|
||||
import pushEvent from './push-event';
|
||||
import releaseEvent from './release-event';
|
||||
import tagPushEvent from './tag-push-event';
|
||||
import wikiPageEvent from './wiki-page-event';
|
||||
|
||||
export default [
|
||||
confidentialIssueEvent,
|
||||
confidentialNoteEvent,
|
||||
deploymentEvent,
|
||||
featureFlagEvent,
|
||||
issueEvent,
|
||||
jobEvent,
|
||||
mergeRequestEvent,
|
||||
noteEvent,
|
||||
pipelineEvent,
|
||||
pushEvent,
|
||||
releaseEvent,
|
||||
tagPushEvent,
|
||||
wikiPageEvent,
|
||||
];
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './issue_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Issue event',
|
||||
description:
|
||||
'Issue event (triggered when a new issue is created or an existing issue is updated, closed, or reopened)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
|
||||
key: GITLAB_EVENT_TYPE.issues_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.issues_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,159 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
|
||||
|
||||
export default {
|
||||
object_kind: 'issue',
|
||||
event_type: 'issue',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 301,
|
||||
title: 'New API: create/update/delete file',
|
||||
assignee_ids: [51],
|
||||
assignee_id: 51,
|
||||
author_id: 51,
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
updated_by_id: 1,
|
||||
last_edited_at: null,
|
||||
last_edited_by_id: null,
|
||||
relative_position: 0,
|
||||
description: 'Create new API for manipulations with repository',
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
confidential: false,
|
||||
discussion_locked: true,
|
||||
due_date: null,
|
||||
moved_to_id: null,
|
||||
duplicated_to_id: null,
|
||||
time_estimate: 0,
|
||||
total_time_spent: 0,
|
||||
time_change: 0,
|
||||
human_total_time_spent: null,
|
||||
human_time_estimate: null,
|
||||
human_time_change: null,
|
||||
weight: null,
|
||||
iid: 23,
|
||||
url: 'http://example.com/diaspora/issues/23',
|
||||
state: 'opened',
|
||||
action: 'open',
|
||||
severity: 'high',
|
||||
escalation_status: 'triggered',
|
||||
escalation_policy: {
|
||||
id: 18,
|
||||
name: 'Engineering On-call',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
assignee: {
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
25
packages/backend/src/apps/gitlab/triggers/job-event/index.ts
Normal file
25
packages/backend/src/apps/gitlab/triggers/job-event/index.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './job_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Job event',
|
||||
description: 'Job event (triggered when the status of a job changes)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events',
|
||||
key: GITLAB_EVENT_TYPE.job_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.job_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,60 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events
|
||||
|
||||
export default {
|
||||
object_kind: 'build',
|
||||
ref: 'gitlab-script-trigger',
|
||||
tag: false,
|
||||
before_sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
build_id: 1977,
|
||||
build_name: 'test',
|
||||
build_stage: 'test',
|
||||
build_status: 'created',
|
||||
build_created_at: '2021-02-23T02:41:37.886Z',
|
||||
build_started_at: null,
|
||||
build_finished_at: null,
|
||||
build_duration: null,
|
||||
build_queued_duration: 1095.588715, // duration in seconds
|
||||
build_allow_failure: false,
|
||||
build_failure_reason: 'script_failure',
|
||||
retries_count: 2, // the second retry of this job
|
||||
pipeline_id: 2366,
|
||||
project_id: 380,
|
||||
project_name: 'gitlab-org/gitlab-test',
|
||||
user: {
|
||||
id: 3,
|
||||
name: 'User',
|
||||
email: 'user@gitlab.com',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
},
|
||||
commit: {
|
||||
id: 2366,
|
||||
name: 'Build pipeline',
|
||||
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
|
||||
message: 'test\n',
|
||||
author_name: 'User',
|
||||
author_email: 'user@gitlab.com',
|
||||
status: 'created',
|
||||
duration: null,
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
},
|
||||
repository: {
|
||||
name: 'gitlab_test',
|
||||
description: 'Atque in sunt eos similique dolores voluptatem.',
|
||||
homepage: 'http://192.168.64.1:3005/gitlab-org/gitlab-test',
|
||||
git_ssh_url: 'git@192.168.64.1:gitlab-org/gitlab-test.git',
|
||||
git_http_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test.git',
|
||||
visibility_level: 20,
|
||||
},
|
||||
runner: {
|
||||
active: true,
|
||||
runner_type: 'project_type',
|
||||
is_shared: false,
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
environment: null,
|
||||
};
|
89
packages/backend/src/apps/gitlab/triggers/lib.ts
Normal file
89
packages/backend/src/apps/gitlab/triggers/lib.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
import Crypto from 'crypto';
|
||||
import { GITLAB_EVENT_TYPE } from './types';
|
||||
import appConfig from '../../../config/app';
|
||||
|
||||
export const projectArgumentDescriptor = {
|
||||
label: 'Project',
|
||||
key: 'projectId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Pick a project to receive events from',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listProjects',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const getTestRunFn =
|
||||
(eventData: IJSONObject) => ($: IGlobalVariable) => {
|
||||
/*
|
||||
Not fetching actual events from gitlab and using static event data from documentation
|
||||
as there is no way to filter out events of one category using gitlab event types,
|
||||
filtering is very limited and uses different grouping than what is applicable when creating a webhook.
|
||||
|
||||
ref:
|
||||
- https://docs.gitlab.com/ee/api/events.html#target-types
|
||||
- https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
*/
|
||||
|
||||
if (!eventData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dataItem = {
|
||||
raw: eventData,
|
||||
meta: {
|
||||
// there is no distinct id on gitlab event object thus creating it
|
||||
internalId: Crypto.randomUUID(),
|
||||
},
|
||||
};
|
||||
|
||||
$.pushTriggerItem(dataItem);
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
export const getRegisterHookFn =
|
||||
(eventType: GITLAB_EVENT_TYPE) => async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
|
||||
const subscriptionPayload = {
|
||||
url: $.webhookUrl,
|
||||
token: appConfig.webhookSecretKey,
|
||||
enable_ssl_verification: true,
|
||||
[eventType]: true,
|
||||
};
|
||||
|
||||
if (
|
||||
['wildcard', 'regex'].includes(
|
||||
$.step.parameters.branch_filter_strategy as string
|
||||
)
|
||||
) {
|
||||
subscriptionPayload.branch_filter_strategy = $.step.parameters
|
||||
.branch_filter_strategy as string;
|
||||
subscriptionPayload.push_events_branch_filter = $.step.parameters
|
||||
.push_events_branch_filter as string;
|
||||
}
|
||||
|
||||
const { data } = await $.http.post(
|
||||
`/api/v4/projects/${$.step.parameters.projectId}/hooks`,
|
||||
subscriptionPayload
|
||||
);
|
||||
|
||||
await $.flow.setRemoteWebhookId(data.id.toString());
|
||||
};
|
||||
|
||||
export const unregisterHook = async ($: IGlobalVariable) => {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#delete-project-hook
|
||||
await $.http.delete(
|
||||
`/api/v4/projects/${$.step.parameters.projectId}/hooks/${$.flow.remoteWebhookId}`
|
||||
);
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './merge_request_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Merge request event',
|
||||
description:
|
||||
'Merge request event (triggered when merge request is created, updated, or closed)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events',
|
||||
key: GITLAB_EVENT_TYPE.merge_requests_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.merge_requests_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,208 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events
|
||||
|
||||
export default {
|
||||
object_kind: 'merge_request',
|
||||
event_type: 'merge_request',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
ci_config_path: '',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 99,
|
||||
iid: 1,
|
||||
target_branch: 'master',
|
||||
source_branch: 'ms-viewport',
|
||||
source_project_id: 14,
|
||||
author_id: 51,
|
||||
assignee_ids: [6],
|
||||
assignee_id: 6,
|
||||
reviewer_ids: [6],
|
||||
title: 'MS-Viewport',
|
||||
created_at: '2013-12-03T17:23:34Z',
|
||||
updated_at: '2013-12-03T17:23:34Z',
|
||||
last_edited_at: '2013-12-03T17:23:34Z',
|
||||
last_edited_by_id: 1,
|
||||
milestone_id: null,
|
||||
state_id: 1,
|
||||
state: 'opened',
|
||||
blocking_discussions_resolved: true,
|
||||
work_in_progress: false,
|
||||
first_contribution: true,
|
||||
merge_status: 'unchecked',
|
||||
target_project_id: 14,
|
||||
description: '',
|
||||
total_time_spent: 1800,
|
||||
time_change: 30,
|
||||
human_total_time_spent: '30m',
|
||||
human_time_change: '30s',
|
||||
human_time_estimate: '30m',
|
||||
url: 'http://example.com/diaspora/merge_requests/1',
|
||||
source: {
|
||||
name: 'Awesome Project',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/awesome_space/awesome_project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
namespace: 'Awesome Space',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'awesome_space/awesome_project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/awesome_space/awesome_project',
|
||||
url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
},
|
||||
target: {
|
||||
name: 'Awesome Project',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/awesome_space/awesome_project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
namespace: 'Awesome Space',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'awesome_space/awesome_project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/awesome_space/awesome_project',
|
||||
url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
|
||||
http_url: 'http://example.com/awesome_space/awesome_project.git',
|
||||
},
|
||||
last_commit: {
|
||||
id: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
message: 'fixed readme',
|
||||
title: 'Update file README.md',
|
||||
timestamp: '2012-01-03T23:36:29+02:00',
|
||||
url: 'http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
author: {
|
||||
name: 'GitLab dev user',
|
||||
email: 'gitlabdev@dv6700.(none)',
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
action: 'open',
|
||||
detailed_merge_status: 'mergeable',
|
||||
},
|
||||
labels: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
changes: {
|
||||
updated_by_id: {
|
||||
previous: null,
|
||||
current: 1,
|
||||
},
|
||||
updated_at: {
|
||||
previous: '2017-09-15 16:50:55 UTC',
|
||||
current: '2017-09-15 16:52:00 UTC',
|
||||
},
|
||||
labels: {
|
||||
previous: [
|
||||
{
|
||||
id: 206,
|
||||
title: 'API',
|
||||
color: '#ffffff',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'API related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
current: [
|
||||
{
|
||||
id: 205,
|
||||
title: 'Platform',
|
||||
color: '#123123',
|
||||
project_id: 14,
|
||||
created_at: '2013-12-03T17:15:43Z',
|
||||
updated_at: '2013-12-03T17:15:43Z',
|
||||
template: false,
|
||||
description: 'Platform related issues',
|
||||
type: 'ProjectLabel',
|
||||
group_id: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
last_edited_at: {
|
||||
previous: null,
|
||||
current: '2023-03-15 00:00:10 UTC',
|
||||
},
|
||||
last_edited_by_id: {
|
||||
previous: null,
|
||||
current: 3278533,
|
||||
},
|
||||
},
|
||||
assignees: [
|
||||
{
|
||||
id: 6,
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
reviewers: [
|
||||
{
|
||||
id: 6,
|
||||
name: 'User1',
|
||||
username: 'user1',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
},
|
||||
],
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './note_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Comment event',
|
||||
description:
|
||||
'Comment event (triggered when a new comment is made on commits, merge requests, issues, and code snippets)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events',
|
||||
key: GITLAB_EVENT_TYPE.note_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.note_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,74 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events
|
||||
|
||||
export default {
|
||||
object_kind: 'note',
|
||||
event_type: 'note',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project_id: 5,
|
||||
project: {
|
||||
id: 5,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
web_url: 'http://example.com/gitlabhq/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
namespace: 'GitlabHQ',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlabhq/gitlab-test',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/gitlabhq/gitlab-test',
|
||||
url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
|
||||
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Gitlab Test',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test.git',
|
||||
description: 'Aut reprehenderit ut est.',
|
||||
homepage: 'http://example.com/gitlab-org/gitlab-test',
|
||||
},
|
||||
object_attributes: {
|
||||
id: 1243,
|
||||
note: 'This is a commit comment. How does this work?',
|
||||
noteable_type: 'Commit',
|
||||
author_id: 1,
|
||||
created_at: '2015-05-17 18:08:09 UTC',
|
||||
updated_at: '2015-05-17 18:08:09 UTC',
|
||||
project_id: 5,
|
||||
attachment: null,
|
||||
line_code: 'bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1',
|
||||
commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
noteable_id: null,
|
||||
system: false,
|
||||
st_diff: {
|
||||
diff: '--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n',
|
||||
new_path: 'six',
|
||||
old_path: 'six',
|
||||
a_mode: '0',
|
||||
b_mode: '160000',
|
||||
new_file: true,
|
||||
renamed_file: false,
|
||||
deleted_file: false,
|
||||
},
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243',
|
||||
},
|
||||
commit: {
|
||||
id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
message:
|
||||
'Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n',
|
||||
timestamp: '2014-02-27T10:06:20+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './pipeline_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Pipeline event',
|
||||
description:
|
||||
'Pipeline event (triggered when the status of a pipeline changes)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#pipeline-events',
|
||||
key: GITLAB_EVENT_TYPE.pipeline_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.pipeline_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,254 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#pipeline-events
|
||||
|
||||
export default {
|
||||
object_kind: 'pipeline',
|
||||
object_attributes: {
|
||||
id: 31,
|
||||
iid: 3,
|
||||
ref: 'master',
|
||||
tag: false,
|
||||
sha: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
before_sha: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
source: 'merge_request_event',
|
||||
status: 'success',
|
||||
stages: ['build', 'test', 'deploy'],
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 63,
|
||||
variables: [
|
||||
{
|
||||
key: 'NESTOR_PROD_ENVIRONMENT',
|
||||
value: 'us-west-1',
|
||||
},
|
||||
],
|
||||
},
|
||||
merge_request: {
|
||||
id: 1,
|
||||
iid: 1,
|
||||
title: 'Test',
|
||||
source_branch: 'test',
|
||||
source_project_id: 1,
|
||||
target_branch: 'master',
|
||||
target_project_id: 1,
|
||||
state: 'opened',
|
||||
merge_status: 'can_be_merged',
|
||||
detailed_merge_status: 'mergeable',
|
||||
url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test/merge_requests/1',
|
||||
},
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'user_email@gitlab.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Gitlab Test',
|
||||
description: 'Atque in sunt eos similique dolores voluptatem.',
|
||||
web_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@192.168.64.1:gitlab-org/gitlab-test.git',
|
||||
git_http_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test.git',
|
||||
namespace: 'Gitlab Org',
|
||||
visibility_level: 20,
|
||||
path_with_namespace: 'gitlab-org/gitlab-test',
|
||||
default_branch: 'master',
|
||||
},
|
||||
commit: {
|
||||
id: 'bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
message: 'test\n',
|
||||
timestamp: '2016-08-12T17:23:21+02:00',
|
||||
url: 'http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2',
|
||||
author: {
|
||||
name: 'User',
|
||||
email: 'user@gitlab.com',
|
||||
},
|
||||
},
|
||||
source_pipeline: {
|
||||
project: {
|
||||
id: 41,
|
||||
web_url: 'https://gitlab.example.com/gitlab-org/upstream-project',
|
||||
path_with_namespace: 'gitlab-org/upstream-project',
|
||||
},
|
||||
pipeline_id: 30,
|
||||
job_id: 3401,
|
||||
},
|
||||
builds: [
|
||||
{
|
||||
id: 380,
|
||||
stage: 'deploy',
|
||||
name: 'production',
|
||||
status: 'skipped',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
duration: null,
|
||||
queued_duration: null,
|
||||
failure_reason: null,
|
||||
when: 'manual',
|
||||
manual: true,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: null,
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: {
|
||||
name: 'production',
|
||||
action: 'start',
|
||||
deployment_tier: 'production',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 377,
|
||||
stage: 'test',
|
||||
name: 'test-image',
|
||||
status: 'success',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:26:12 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker', 'shared-runner'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 378,
|
||||
stage: 'test',
|
||||
name: 'test-build',
|
||||
status: 'failed',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:26:12 UTC',
|
||||
finished_at: '2016-08-12 15:26:29 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: 'script_failure',
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 376,
|
||||
stage: 'build',
|
||||
name: 'build-image',
|
||||
status: 'success',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: '2016-08-12 15:24:56 UTC',
|
||||
finished_at: '2016-08-12 15:25:26 UTC',
|
||||
duration: 17.0,
|
||||
queued_duration: 196.0,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: {
|
||||
id: 380987,
|
||||
description: 'shared-runners-manager-6.gitlab.com',
|
||||
active: true,
|
||||
runner_type: 'instance_type',
|
||||
is_shared: true,
|
||||
tags: ['linux', 'docker'],
|
||||
},
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: null,
|
||||
},
|
||||
{
|
||||
id: 379,
|
||||
stage: 'deploy',
|
||||
name: 'staging',
|
||||
status: 'created',
|
||||
created_at: '2016-08-12 15:23:28 UTC',
|
||||
started_at: null,
|
||||
finished_at: null,
|
||||
duration: null,
|
||||
queued_duration: null,
|
||||
failure_reason: null,
|
||||
when: 'on_success',
|
||||
manual: false,
|
||||
allow_failure: false,
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
runner: null,
|
||||
artifacts_file: {
|
||||
filename: null,
|
||||
size: null,
|
||||
},
|
||||
environment: {
|
||||
name: 'staging',
|
||||
action: 'start',
|
||||
deployment_tier: 'staging',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
@@ -0,0 +1,62 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './push_event';
|
||||
|
||||
export const branchFilterStrategyArgumentDescriptor = {
|
||||
label: 'What type of filter to use?',
|
||||
key: 'branch_filter_strategy',
|
||||
type: 'dropdown' as const,
|
||||
description: 'Defaults to including all branches',
|
||||
required: true,
|
||||
variables: false,
|
||||
value: 'all_branches',
|
||||
options: [
|
||||
{
|
||||
label: 'All branches',
|
||||
value: 'all_branches',
|
||||
},
|
||||
{
|
||||
label: 'Wildcard pattern (ex: *-stable)',
|
||||
value: 'wildcard',
|
||||
},
|
||||
{
|
||||
label: 'Regular expression (ex: ^(feature|hotfix)/)',
|
||||
value: 'regex',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const pushEventsBranchFilterArgumentDescriptor = {
|
||||
label: 'Filter value',
|
||||
key: 'push_events_branch_filter',
|
||||
description: 'Leave empty when using "all branches"',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: false,
|
||||
};
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Push event',
|
||||
description: 'Push event (triggered when you push to the repository)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events',
|
||||
key: GITLAB_EVENT_TYPE.push_events,
|
||||
type: 'webhook',
|
||||
arguments: [
|
||||
projectArgumentDescriptor,
|
||||
branchFilterStrategyArgumentDescriptor,
|
||||
pushEventsBranchFilterArgumentDescriptor,
|
||||
],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.push_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,75 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#push-events
|
||||
|
||||
export default {
|
||||
object_kind: 'push',
|
||||
event_name: 'push',
|
||||
before: '95790bf891e76fee5e1747ab589903a6a1f80f22',
|
||||
after: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
ref: 'refs/heads/master',
|
||||
checkout_sha: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
user_id: 4,
|
||||
user_name: 'John Smith',
|
||||
user_username: 'jsmith',
|
||||
user_email: 'john@example.com',
|
||||
user_avatar:
|
||||
'https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80',
|
||||
project_id: 15,
|
||||
project: {
|
||||
id: 15,
|
||||
name: 'Diaspora',
|
||||
description: '',
|
||||
web_url: 'http://example.com/mike/diaspora',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
git_http_url: 'http://example.com/mike/diaspora.git',
|
||||
namespace: 'Mike',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'mike/diaspora',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/mike/diaspora',
|
||||
url: 'git@example.com:mike/diaspora.git',
|
||||
ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
http_url: 'http://example.com/mike/diaspora.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Diaspora',
|
||||
url: 'git@example.com:mike/diaspora.git',
|
||||
description: '',
|
||||
homepage: 'http://example.com/mike/diaspora',
|
||||
git_http_url: 'http://example.com/mike/diaspora.git',
|
||||
git_ssh_url: 'git@example.com:mike/diaspora.git',
|
||||
visibility_level: 0,
|
||||
},
|
||||
commits: [
|
||||
{
|
||||
id: 'b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327',
|
||||
message:
|
||||
'Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information',
|
||||
title: 'Update Catalan translation to e38cb41.',
|
||||
timestamp: '2011-12-12T14:27:31+02:00',
|
||||
url: 'http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327',
|
||||
author: {
|
||||
name: 'Jordi Mallach',
|
||||
email: 'jordi@softcatala.org',
|
||||
},
|
||||
added: ['CHANGELOG'],
|
||||
modified: ['app/controller/application.rb'],
|
||||
removed: [],
|
||||
},
|
||||
{
|
||||
id: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
message: 'fixed readme',
|
||||
title: 'fixed readme',
|
||||
timestamp: '2012-01-03T23:36:29+02:00',
|
||||
url: 'http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
|
||||
author: {
|
||||
name: 'GitLab dev user',
|
||||
email: 'gitlabdev@dv6700.(none)',
|
||||
},
|
||||
added: ['CHANGELOG'],
|
||||
modified: ['app/controller/application.rb'],
|
||||
removed: [],
|
||||
},
|
||||
],
|
||||
total_commits_count: 4,
|
||||
};
|
@@ -0,0 +1,25 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './release_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Release event',
|
||||
description: 'Release event (triggered when a release is created or updated)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#release-events',
|
||||
key: GITLAB_EVENT_TYPE.releases_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.releases_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,72 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#release-events
|
||||
|
||||
export default {
|
||||
object_kind: 'release',
|
||||
id: 1,
|
||||
created_at: '2020-11-02 12:55:12 UTC',
|
||||
description: 'v1.1 has been released',
|
||||
name: 'v1.1',
|
||||
released_at: '2020-11-02 12:55:12 UTC',
|
||||
tag: 'v1.1',
|
||||
project: {
|
||||
id: 2,
|
||||
name: 'release-webhook-example',
|
||||
description: '',
|
||||
web_url: 'https://example.com/gitlab-org/release-webhook-example',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
git_http_url: 'https://example.com/gitlab-org/release-webhook-example.git',
|
||||
namespace: 'Gitlab',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'gitlab-org/release-webhook-example',
|
||||
default_branch: 'master',
|
||||
ci_config_path: null,
|
||||
homepage: 'https://example.com/gitlab-org/release-webhook-example',
|
||||
url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
ssh_url: 'ssh://git@example.com/gitlab-org/release-webhook-example.git',
|
||||
http_url: 'https://example.com/gitlab-org/release-webhook-example.git',
|
||||
},
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/releases/v1.1',
|
||||
action: 'create',
|
||||
assets: {
|
||||
count: 5,
|
||||
links: [
|
||||
{
|
||||
id: 1,
|
||||
external: true, // deprecated in GitLab 15.9, will be removed in GitLab 16.0.
|
||||
link_type: 'other',
|
||||
name: 'Changelog',
|
||||
url: 'https://example.net/changelog',
|
||||
},
|
||||
],
|
||||
sources: [
|
||||
{
|
||||
format: 'zip',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.zip',
|
||||
},
|
||||
{
|
||||
format: 'tar.gz',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.gz',
|
||||
},
|
||||
{
|
||||
format: 'tar.bz2',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar.bz2',
|
||||
},
|
||||
{
|
||||
format: 'tar',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/archive/v1.1/release-webhook-example-v1.1.tar',
|
||||
},
|
||||
],
|
||||
},
|
||||
commit: {
|
||||
id: 'ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8',
|
||||
message: 'Release v1.1',
|
||||
title: 'Release v1.1',
|
||||
timestamp: '2020-10-31T14:58:32+11:00',
|
||||
url: 'https://example.com/gitlab-org/release-webhook-example/-/commit/ee0a3fb31ac16e11b9dbb596ad16d4af654d08f8',
|
||||
author: {
|
||||
name: 'Example User',
|
||||
email: 'user@example.com',
|
||||
},
|
||||
},
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './tag_push_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Tag event',
|
||||
description:
|
||||
'Tag event (triggered when you create or delete tags in the repository)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#tag-events',
|
||||
key: GITLAB_EVENT_TYPE.tag_push_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.tag_push_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,43 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#tag-events
|
||||
|
||||
export default {
|
||||
object_kind: 'tag_push',
|
||||
event_name: 'tag_push',
|
||||
before: '0000000000000000000000000000000000000000',
|
||||
after: '82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
ref: 'refs/tags/v1.0.0',
|
||||
checkout_sha: '82b3d5ae55f7080f1e6022629cdb57bfae7cccc7',
|
||||
user_id: 1,
|
||||
user_name: 'John Smith',
|
||||
user_avatar:
|
||||
'https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80',
|
||||
project_id: 1,
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'Example',
|
||||
description: '',
|
||||
web_url: 'http://example.com/jsmith/example',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:jsmith/example.git',
|
||||
git_http_url: 'http://example.com/jsmith/example.git',
|
||||
namespace: 'Jsmith',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'jsmith/example',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/jsmith/example',
|
||||
url: 'git@example.com:jsmith/example.git',
|
||||
ssh_url: 'git@example.com:jsmith/example.git',
|
||||
http_url: 'http://example.com/jsmith/example.git',
|
||||
},
|
||||
repository: {
|
||||
name: 'Example',
|
||||
url: 'ssh://git@example.com/jsmith/example.git',
|
||||
description: '',
|
||||
homepage: 'http://example.com/jsmith/example',
|
||||
git_http_url: 'http://example.com/jsmith/example.git',
|
||||
git_ssh_url: 'git@example.com:jsmith/example.git',
|
||||
visibility_level: 0,
|
||||
},
|
||||
commits: [],
|
||||
total_commits_count: 0,
|
||||
};
|
24
packages/backend/src/apps/gitlab/triggers/types.ts
Normal file
24
packages/backend/src/apps/gitlab/triggers/types.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export enum GITLAB_EVENT_TYPE {
|
||||
// ref: https://docs.gitlab.com/ee/api/projects.html#add-project-hook
|
||||
confidential_issues_events = 'confidential_issues_events',
|
||||
confidential_note_events = 'confidential_note_events',
|
||||
deployment_events = 'deployment_events',
|
||||
feature_flag_events = 'feature_flag_events',
|
||||
issues_events = 'issues_events',
|
||||
job_events = 'job_events',
|
||||
merge_requests_events = 'merge_requests_events',
|
||||
note_events = 'note_events',
|
||||
pipeline_events = 'pipeline_events',
|
||||
push_events = 'push_events',
|
||||
releases_events = 'releases_events',
|
||||
tag_push_events = 'tag_push_events',
|
||||
wiki_page_events = 'wiki_page_events',
|
||||
}
|
||||
|
||||
export type EventDescriptor = {
|
||||
name: string;
|
||||
description: string;
|
||||
info?: string;
|
||||
type: GITLAB_EVENT_TYPE;
|
||||
data: any;
|
||||
};
|
@@ -0,0 +1,26 @@
|
||||
import { IRawTrigger } from '@automatisch/types';
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import { GITLAB_EVENT_TYPE } from '../types';
|
||||
import {
|
||||
getRegisterHookFn,
|
||||
getTestRunFn,
|
||||
projectArgumentDescriptor,
|
||||
unregisterHook,
|
||||
} from '../lib';
|
||||
|
||||
import data from './wiki_page_event';
|
||||
|
||||
export const triggerDescriptor: IRawTrigger = {
|
||||
name: 'Wiki page event',
|
||||
description:
|
||||
'Wiki page event (triggered when a wiki page is created, updated, or deleted)',
|
||||
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#wiki-page-events',
|
||||
key: GITLAB_EVENT_TYPE.wiki_page_events,
|
||||
type: 'webhook',
|
||||
arguments: [projectArgumentDescriptor],
|
||||
testRun: getTestRunFn(data),
|
||||
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.wiki_page_events),
|
||||
unregisterHook,
|
||||
};
|
||||
|
||||
export default defineTrigger(triggerDescriptor);
|
@@ -0,0 +1,48 @@
|
||||
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#wiki-page-events
|
||||
|
||||
export default {
|
||||
object_kind: 'wiki_page',
|
||||
user: {
|
||||
id: 1,
|
||||
name: 'Administrator',
|
||||
username: 'root',
|
||||
avatar_url:
|
||||
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
|
||||
email: 'admin@example.com',
|
||||
},
|
||||
project: {
|
||||
id: 1,
|
||||
name: 'awesome-project',
|
||||
description: 'This is awesome',
|
||||
web_url: 'http://example.com/root/awesome-project',
|
||||
avatar_url: null,
|
||||
git_ssh_url: 'git@example.com:root/awesome-project.git',
|
||||
git_http_url: 'http://example.com/root/awesome-project.git',
|
||||
namespace: 'root',
|
||||
visibility_level: 0,
|
||||
path_with_namespace: 'root/awesome-project',
|
||||
default_branch: 'master',
|
||||
homepage: 'http://example.com/root/awesome-project',
|
||||
url: 'git@example.com:root/awesome-project.git',
|
||||
ssh_url: 'git@example.com:root/awesome-project.git',
|
||||
http_url: 'http://example.com/root/awesome-project.git',
|
||||
},
|
||||
wiki: {
|
||||
web_url: 'http://example.com/root/awesome-project/-/wikis/home',
|
||||
git_ssh_url: 'git@example.com:root/awesome-project.wiki.git',
|
||||
git_http_url: 'http://example.com/root/awesome-project.wiki.git',
|
||||
path_with_namespace: 'root/awesome-project.wiki',
|
||||
default_branch: 'master',
|
||||
},
|
||||
object_attributes: {
|
||||
title: 'Awesome',
|
||||
content: 'awesome content goes here',
|
||||
format: 'markdown',
|
||||
message: 'adding an awesome page to the wiki',
|
||||
slug: 'awesome',
|
||||
url: 'http://example.com/root/awesome-project/-/wikis/awesome',
|
||||
action: 'create',
|
||||
diff_url:
|
||||
'http://example.com/root/awesome-project/-/wikis/home/diff?version_id=78ee4a6705abfbff4f4132c6646dbaae9c8fb6ec',
|
||||
},
|
||||
};
|
@@ -0,0 +1,8 @@
|
||||
<svg viewBox="0 0 87.3 78" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m6.6 66.85 3.85 6.65c.8 1.4 1.95 2.5 3.3 3.3l13.75-23.8h-27.5c0 1.55.4 3.1 1.2 4.5z" fill="#0066da"/>
|
||||
<path d="m43.65 25-13.75-23.8c-1.35.8-2.5 1.9-3.3 3.3l-25.4 44a9.06 9.06 0 0 0 -1.2 4.5h27.5z" fill="#00ac47"/>
|
||||
<path d="m73.55 76.8c1.35-.8 2.5-1.9 3.3-3.3l1.6-2.75 7.65-13.25c.8-1.4 1.2-2.95 1.2-4.5h-27.502l5.852 11.5z" fill="#ea4335"/>
|
||||
<path d="m43.65 25 13.75-23.8c-1.35-.8-2.9-1.2-4.5-1.2h-18.5c-1.6 0-3.15.45-4.5 1.2z" fill="#00832d"/>
|
||||
<path d="m59.8 53h-32.3l-13.75 23.8c1.35.8 2.9 1.2 4.5 1.2h50.8c1.6 0 3.15-.45 4.5-1.2z" fill="#2684fc"/>
|
||||
<path d="m73.4 26.5-12.7-22c-.8-1.4-1.95-2.5-3.3-3.3l-13.75 23.8 16.15 28h27.45c0-1.55-.4-3.1-1.2-4.5z" fill="#ffba00"/>
|
||||
</svg>
|
After Width: | Height: | Size: 755 B |
@@ -0,0 +1,24 @@
|
||||
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
import authScope from '../common/auth-scope';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const redirectUri = oauthRedirectUrlField.value as string;
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: redirectUri,
|
||||
prompt: 'select_account',
|
||||
scope: authScope.join(' '),
|
||||
response_type: 'code',
|
||||
access_type: 'offline',
|
||||
});
|
||||
|
||||
const url = `https://accounts.google.com/o/oauth2/v2/auth?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({
|
||||
url,
|
||||
});
|
||||
}
|
48
packages/backend/src/apps/google-drive/auth/index.ts
Normal file
48
packages/backend/src/apps/google-drive/auth/index.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import refreshToken from './refresh-token';
|
||||
import isStillVerified from './is-still-verified';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'oAuthRedirectUrl',
|
||||
label: 'OAuth Redirect URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: true,
|
||||
value: '{WEB_APP_URL}/app/google-drive/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input a redirect URL in Google Cloud, enter the URL above.',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'clientId',
|
||||
label: 'Client ID',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'clientSecret',
|
||||
label: 'Client Secret',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
generateAuthUrl,
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
refreshToken,
|
||||
};
|
@@ -0,0 +1,9 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
const currentUser = await getCurrentUser($);
|
||||
return !!currentUser.resourceName;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
26
packages/backend/src/apps/google-drive/auth/refresh-token.ts
Normal file
26
packages/backend/src/apps/google-drive/auth/refresh-token.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { URLSearchParams } from 'node:url';
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import authScope from '../common/auth-scope';
|
||||
|
||||
const refreshToken = async ($: IGlobalVariable) => {
|
||||
const params = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: $.auth.data.refreshToken as string,
|
||||
});
|
||||
|
||||
const { data } = await $.http.post(
|
||||
'https://oauth2.googleapis.com/token',
|
||||
params.toString()
|
||||
);
|
||||
|
||||
await $.auth.set({
|
||||
accessToken: data.access_token,
|
||||
expiresIn: data.expires_in,
|
||||
scope: authScope.join(' '),
|
||||
tokenType: data.token_type,
|
||||
});
|
||||
};
|
||||
|
||||
export default refreshToken;
|
@@ -0,0 +1,57 @@
|
||||
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
type TUser = {
|
||||
displayName: string;
|
||||
metadata: {
|
||||
primary: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
type TEmailAddress = {
|
||||
value: string;
|
||||
metadata: {
|
||||
primary: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const redirectUri = oauthRedirectUrlField.value as string;
|
||||
const { data } = await $.http.post(`https://oauth2.googleapis.com/token`, {
|
||||
client_id: $.auth.data.clientId,
|
||||
client_secret: $.auth.data.clientSecret,
|
||||
code: $.auth.data.code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: redirectUri,
|
||||
});
|
||||
|
||||
await $.auth.set({
|
||||
accessToken: data.access_token,
|
||||
tokenType: data.token_type,
|
||||
});
|
||||
|
||||
const currentUser = await getCurrentUser($);
|
||||
|
||||
const { displayName } = currentUser.names.find(
|
||||
(name: TUser) => name.metadata.primary
|
||||
);
|
||||
const { value: email } = currentUser.emailAddresses.find(
|
||||
(emailAddress: TEmailAddress) => emailAddress.metadata.primary
|
||||
);
|
||||
|
||||
await $.auth.set({
|
||||
clientId: $.auth.data.clientId,
|
||||
clientSecret: $.auth.data.clientSecret,
|
||||
scope: $.auth.data.scope,
|
||||
idToken: data.id_token,
|
||||
expiresIn: data.expires_in,
|
||||
refreshToken: data.refresh_token,
|
||||
resourceName: currentUser.resourceName,
|
||||
screenName: `${displayName} - ${email}`,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
@@ -0,0 +1,11 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data?.accessToken) {
|
||||
requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
@@ -0,0 +1,7 @@
|
||||
const authScope: string[] = [
|
||||
'https://www.googleapis.com/auth/drive',
|
||||
'https://www.googleapis.com/auth/userinfo.email',
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
];
|
||||
|
||||
export default authScope;
|
@@ -0,0 +1,10 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const getCurrentUser = async ($: IGlobalVariable) => {
|
||||
const { data: currentUser } = await $.http.get(
|
||||
'https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses'
|
||||
);
|
||||
return currentUser;
|
||||
};
|
||||
|
||||
export default getCurrentUser;
|
@@ -0,0 +1,4 @@
|
||||
import listFolders from './list-folders';
|
||||
import listDrives from './list-drives';
|
||||
|
||||
export default [listFolders, listDrives];
|
@@ -0,0 +1,35 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
export default {
|
||||
name: 'List drives',
|
||||
key: 'listDrives',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
const drives: {
|
||||
data: IJSONObject[];
|
||||
} = {
|
||||
data: [{ value: null, name: 'My Google Drive' }],
|
||||
};
|
||||
|
||||
const params = {
|
||||
pageSize: 100,
|
||||
pageToken: undefined as unknown as string,
|
||||
};
|
||||
|
||||
do {
|
||||
const { data } = await $.http.get(`/v3/drives`, { params });
|
||||
params.pageToken = data.nextPageToken;
|
||||
|
||||
if (data.drives) {
|
||||
for (const drive of data.drives) {
|
||||
drives.data.push({
|
||||
value: drive.id,
|
||||
name: drive.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
} while (params.pageToken);
|
||||
|
||||
return drives;
|
||||
},
|
||||
};
|
@@ -0,0 +1,47 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
export default {
|
||||
name: 'List folders',
|
||||
key: 'listFolders',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
const folders: {
|
||||
data: IJSONObject[];
|
||||
} = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
const params: Record<string, unknown> = {
|
||||
q: `mimeType='application/vnd.google-apps.folder'`,
|
||||
orderBy: 'createdTime desc',
|
||||
pageToken: undefined as unknown as string,
|
||||
pageSize: 1000,
|
||||
driveId: $.step.parameters.driveId,
|
||||
supportsAllDrives: true,
|
||||
};
|
||||
|
||||
if ($.step.parameters.driveId) {
|
||||
params.includeItemsFromAllDrives = true;
|
||||
params.corpora = 'drive';
|
||||
}
|
||||
|
||||
do {
|
||||
const { data } = await $.http.get(
|
||||
`https://www.googleapis.com/drive/v3/files`,
|
||||
{
|
||||
params,
|
||||
}
|
||||
);
|
||||
params.pageToken = data.nextPageToken;
|
||||
|
||||
for (const file of data.files) {
|
||||
folders.data.push({
|
||||
value: file.id,
|
||||
name: file.name,
|
||||
});
|
||||
}
|
||||
} while (params.pageToken);
|
||||
|
||||
return folders;
|
||||
},
|
||||
};
|
0
packages/backend/src/apps/google-drive/index.d.ts
vendored
Normal file
0
packages/backend/src/apps/google-drive/index.d.ts
vendored
Normal file
20
packages/backend/src/apps/google-drive/index.ts
Normal file
20
packages/backend/src/apps/google-drive/index.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import auth from './auth';
|
||||
import triggers from './triggers';
|
||||
import dynamicData from './dynamic-data';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Google Drive',
|
||||
key: 'google-drive',
|
||||
baseUrl: 'https://drive.google.com',
|
||||
apiBaseUrl: 'https://www.googleapis.com/drive',
|
||||
iconUrl: '{BASE_URL}/apps/google-drive/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/google-drive/connection',
|
||||
primaryColor: '1FA463',
|
||||
supportsConnections: true,
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
triggers,
|
||||
dynamicData,
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user