Compare commits
452 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
321a0e8540 | ||
|
|
cb8f769e34 | ||
|
|
38ff77a04e | ||
|
|
292cd8dd94 | ||
|
|
3878059314 | ||
|
|
7a7e50c7ba | ||
|
|
564dd536fc | ||
|
|
0e29805351 | ||
| dc76267da3 | |||
| 147b11b22d | |||
|
|
b992e4ff01 | ||
|
|
b46a922464 | ||
| d4abc705a0 | |||
| 454d13c608 | |||
|
|
6086dbbad2 | ||
|
|
b9607dddce | ||
|
|
1a7aeb4450 | ||
|
|
d973af6a8d | ||
|
2dae279f93
|
|||
|
09d17717ab
|
|||
|
bf4454f635
|
|||
|
9e531d823f
|
|||
| d17aa23e98 | |||
| 63f7c1d665 | |||
|
c5c2f741f0
|
|||
|
ec24c51eea
|
|||
|
fa2c4073e3
|
|||
|
255d093269
|
|||
|
73a264b1c2
|
|||
|
|
c112230e05 | ||
|
|
02dd911e93 | ||
|
9c3ee3d146
|
|||
|
4c8d5d03d9
|
|||
|
c729594864
|
|||
|
713626810b
|
|||
|
6e5c261065
|
|||
|
2f1027e068
|
|||
|
739f547731
|
|||
|
3f7ecdb84e
|
|||
|
e037764c3f
|
|||
|
c8aa866dfd
|
|||
|
84b1199878
|
|||
|
04150d5320
|
|||
|
11ccf2909f
|
|||
|
631942ca75
|
|||
|
4ee603d7a2
|
|||
|
7cfe22b72e
|
|||
|
e6701cda95
|
|||
|
865a2fd645
|
|||
|
05f362153f
|
|||
|
997eb72378
|
|||
|
69805151c8
|
|||
|
47ec5267ec
|
|||
|
3a87b51f41
|
|||
|
ffc8cfe68e
|
|||
|
7f5fffa5e6
|
|||
|
b16f4a9fb3
|
|||
|
ebf0b84a05
|
|||
|
b724930c6a
|
|||
|
603e444d35
|
|||
|
f274b807f2
|
|||
|
d0c8920b98
|
|||
|
4c0d49508f
|
|||
|
2a09bc1ea3
|
|||
|
259d27a2ce
|
|||
|
|
8aefbb39e0 | ||
|
|
e417b9f5d8 | ||
|
|
9458587d59 | ||
|
|
468c8c10fc | ||
|
|
6d90a88b60 | ||
|
|
7231199f9e | ||
|
|
41c0c9f685 | ||
|
|
79c5c648c9 | ||
|
|
0ba2e23171 | ||
|
|
b0f3869621 | ||
|
|
b709d53e40 | ||
|
|
b198168d75 | ||
|
bd41ab603d
|
|||
|
0059431fbb
|
|||
|
863addce39
|
|||
|
07b7272eb1
|
|||
|
c59de1fcf9
|
|||
|
2d24d8e379
|
|||
|
60fd32e4d5
|
|||
|
f32504e76b
|
|||
|
8eed126fa4
|
|||
| 9242cbccc4 | |||
|
|
a7d209b370 | ||
|
29c1b6286f
|
|||
|
|
1ae4ab46d4 | ||
| cd33470b12 | |||
| 083feeef90 | |||
| 42f6267539 | |||
|
|
5f669092c2 | ||
| 9a36aad9cb | |||
| 898983f724 | |||
|
c35a726e93
|
|||
|
9cda4061d5
|
|||
|
1462dffb3e
|
|||
|
d314242b3b
|
|||
|
e6daa0bb20
|
|||
|
3b357881ae
|
|||
|
20efc2b0e2
|
|||
|
6a9ca9993a
|
|||
|
0c0c3f4671
|
|||
|
5a21488e6b
|
|||
|
e5c7c3df7b
|
|||
|
78015e1364
|
|||
|
ffcb30cdbd
|
|||
|
4ff15c7613
|
|||
|
db78571c25
|
|||
|
590aa9a1ff
|
|||
|
ccab0685d0
|
|||
|
34cc9789eb
|
|||
|
82ac23c63c
|
|||
|
7065aeba69
|
|||
|
bf23c998a0
|
|||
|
35e0f97b0a
|
|||
|
3fe80a12e0
|
|||
|
03f53d9f11
|
|||
|
c58f6dd883
|
|||
|
9a2b76b887
|
|||
|
3d380851ab
|
|||
|
5b2b76b772
|
|||
|
80b22d23b7
|
|||
|
c3d2b9efc1
|
|||
|
25c4569639
|
|||
|
78a512b8f6
|
|||
|
3d5d11523e
|
|||
|
d2ffa5e381
|
|||
|
b4eb11818f
|
|||
|
a6032241e1
|
|||
|
b1e2c48075
|
|||
|
a77087a081
|
|||
|
05319b3860
|
|||
|
fb106a1499
|
|||
|
9eaa896b2d
|
|||
|
ed7abff25a
|
|||
|
4a8f35c0eb
|
|||
|
1debab8452
|
|||
|
53cfd4789e
|
|||
|
d9a89e143a
|
|||
|
55e998bb46
|
|||
|
bd40d20911
|
|||
|
efc5dac8f4
|
|||
|
c33a35003b
|
|||
|
a10c1bcff9
|
|||
|
2025e04b61
|
|||
|
77e2b5e7d6
|
|||
|
9b2b7682e3
|
|||
|
433abb0fec
|
|||
|
012cd0cc44
|
|||
|
f56f934514
|
|||
|
c9aaad376b
|
|||
|
3ebd2478fe
|
|||
|
b3fbaa1d97
|
|||
|
94da974373
|
|||
|
fd76d3ce59
|
|||
|
7c5420d279
|
|||
|
c2ab89457b
|
|||
|
8f87fae452
|
|||
|
d5c9c3550a
|
|||
|
b654cc3469
|
|||
|
fdb99d57d6
|
|||
|
e3e611d47b
|
|||
|
b8ef37188c
|
|||
|
f8d68789fc
|
|||
|
e0c9df41d7
|
|||
|
1363ed4f8a
|
|||
|
3e914b7a99
|
|||
|
d690256369
|
|||
|
18c37feed8
|
|||
|
d21a8721cf
|
|||
|
d0192d9a72
|
|||
|
684963bc2b
|
|||
|
220b995f28
|
|||
|
998d706bf7
|
|||
|
f4a394bd3b
|
|||
|
898bbe4827
|
|||
|
66b69d5629
|
|||
|
818729d6ed
|
|||
|
33a2a90eb1
|
|||
|
2ff6c193c9
|
|||
|
647ce980b4
|
|||
|
f557c5aff6
|
|||
|
2e67915bb6
|
|||
|
cce142d636
|
|||
|
e398e1acc4
|
|||
|
5c6756d98f
|
|||
|
f0ccd04718
|
|||
|
fe0545efc0
|
|||
|
15bfc1c35e
|
|||
|
a0635658bd
|
|||
|
cde7a1ab40
|
|||
|
c8d68bdb2a
|
|||
|
d18e67881c
|
|||
|
cdfccdd022
|
|||
|
44f6a002bf
|
|||
|
b85db52c77
|
|||
|
3ebc986132
|
|||
|
5973508f80
|
|||
|
9a9e4ebedf
|
|||
|
a78e3201cb
|
|||
|
fbdeea47eb
|
|||
|
761a4f187e
|
|||
|
77bb68e3a9
|
|||
|
189d913567
|
|||
|
2e9fdcf9bd
|
|||
|
f57a46cd29
|
|||
|
305abb3e47
|
|||
|
|
ef904032d7 | ||
|
|
55c1058832 | ||
|
879a9a658c
|
|||
|
893679c843
|
|||
|
f935b184d7
|
|||
|
010a440e3e
|
|||
|
51023a0e14
|
|||
|
55d5cae85f
|
|||
|
d564f064d6
|
|||
|
1750b6ff11
|
|||
|
0690e1551b
|
|||
|
d1a7460c05
|
|||
|
70e349d7e3
|
|||
|
568c3fc219
|
|||
|
f55ecae8f3
|
|||
|
e4436ad7b7
|
|||
|
67d7019a93
|
|||
|
4b45c0a2a2
|
|||
|
b3aae7b837
|
|||
|
122286bd7b
|
|||
|
6708bb17a3
|
|||
|
5fa7cd9d85
|
|||
|
25ac27dd64
|
|||
|
a659e03512
|
|||
|
4d081adda2
|
|||
|
279d48d8ee
|
|||
|
c017578631
|
|||
|
f4baade73b
|
|||
|
f68053b461
|
|||
|
ec18ceb6db
|
|||
|
68c4778ed8
|
|||
|
cf28156e70
|
|||
|
149fe89f89
|
|||
|
c124d93285
|
|||
|
06e5d42c9c
|
|||
|
c42b60a58c
|
|||
|
1e8bdcddd8
|
|||
|
90c2295bb8
|
|||
|
cca7b48d3b
|
|||
|
2d9dec2d74
|
|||
|
30741f124e
|
|||
|
f256a9db06
|
|||
|
baf850308f
|
|||
|
|
d9174d2a20 | ||
|
a5dad1e7bb
|
|||
|
aa4278e7a7
|
|||
|
4dfff72a9c
|
|||
|
624b24b1be
|
|||
|
c14f035147
|
|||
|
2d787f458d
|
|||
|
9169e5177e
|
|||
|
077c63d793
|
|||
|
2696fe05d4
|
|||
| 3d042a3739 | |||
|
|
ad57bc5f78 | ||
|
|
5f2bb97d65 | ||
|
d9cb0edebe
|
|||
|
56c2bb2e4c
|
|||
|
3326468637
|
|||
|
23eeccb5e4
|
|||
|
7cd8e4af9b
|
|||
|
a14aa856ab
|
|||
|
d80d5e37c0
|
|||
|
60c6924870
|
|||
|
c3871cd542
|
|||
| 585051e324 | |||
|
77d22521c0
|
|||
|
5f1f9f7fff
|
|||
|
f8a2bdd464
|
|||
|
6e0c6c6ce0
|
|||
|
8fd37af0d3
|
|||
|
8f71f8195e
|
|||
|
1c75f11e9f
|
|||
|
711f6b59f3
|
|||
|
568158484e
|
|||
|
81d17dd982
|
|||
|
07b34a7650
|
|||
|
10da0f4980
|
|||
|
02591c5cff
|
|||
|
1675b9b751
|
|||
|
6bf0c45277
|
|||
|
a76543d7a7
|
|||
|
e6d4cb7e4f
|
|||
|
d567ea4517
|
|||
|
424a4efb7a
|
|||
|
03d863f5e7
|
|||
|
820f770619
|
|||
|
b6d5505c2d
|
|||
|
6af347f5d2
|
|||
|
eb0f7a5a72
|
|||
|
01415e13d5
|
|||
|
9329a3a032
|
|||
|
e857bfee03
|
|||
|
7e71ff5e37
|
|||
|
bc629d6384
|
|||
|
21d1c8bacf
|
|||
|
f086e806df
|
|||
|
fdd9093f49
|
|||
|
7fad9689c6
|
|||
|
2b2795b7dd
|
|||
|
fab2bc636a
|
|||
|
f0237eb488
|
|||
|
1160f43820
|
|||
|
d7b2e338d9
|
|||
|
2d61f8516d
|
|||
|
7c1483184a
|
|||
|
5f03e374d4
|
|||
|
d391676a8e
|
|||
|
25ed3c38e7
|
|||
|
37195341c5
|
|||
|
6f0602f49b
|
|||
|
b163dff842
|
|||
|
|
439b706060 | ||
|
44f7f8c6c2
|
|||
|
075303e9b6
|
|||
|
62da08860d
|
|||
|
a6abfcde90
|
|||
|
9f394e84cb
|
|||
|
e0062d181d
|
|||
|
bc0ed61e1a
|
|||
|
6965d2eaa4
|
|||
|
016751ddbd
|
|||
|
06bf294f8a
|
|||
|
23f2726ff8
|
|||
|
9e54446f44
|
|||
|
811380215a
|
|||
|
b4675dac70
|
|||
|
d4df854820
|
|||
|
94a55d5922
|
|||
|
02f5d5e7d9
|
|||
|
f8ce387f4f
|
|||
|
8e01deba82
|
|||
|
5dbf387bf0
|
|||
|
8a13954718
|
|||
|
a05c4d3684
|
|||
|
a6543fdc28
|
|||
|
23d4d523d6
|
|||
|
b6a8bb2e66
|
|||
|
dea4a21f92
|
|||
|
074fbe67d8
|
|||
|
eee25769c8
|
|||
|
cbef38f970
|
|||
|
03ab50f557
|
|||
|
6b88664db0
|
|||
|
ceafd71461
|
|||
|
614a0a2daf
|
|||
|
e6bde3e0de
|
|||
|
50c724869e
|
|||
|
b595aa09a5
|
|||
|
7e68e55ae6
|
|||
| 1a423d0def | |||
|
|
e107475252 | ||
| 667b260aff | |||
| 4036117d6c | |||
|
|
83ee35b9ae | ||
|
9cca602585
|
|||
|
05944d284e
|
|||
|
b8d6e4f538
|
|||
|
a45541f0b9
|
|||
|
d836665df3
|
|||
|
21cb2a90c8
|
|||
|
|
259f0a1fe1 | ||
|
731ca00390
|
|||
|
c938f7a212
|
|||
|
b11f85caf5
|
|||
|
0e0eefba2b
|
|||
|
06cbd4663c
|
|||
|
a578677137
|
|||
|
e5cecbac54
|
|||
|
42597e0652
|
|||
|
8ccd339d05
|
|||
|
54afd779b3
|
|||
|
f83ef42653
|
|||
|
dc36741c72
|
|||
|
2ec3b6ed19
|
|||
|
77ae969d28
|
|||
|
f8bf7afbe2
|
|||
|
aa61eeec34
|
|||
|
7cdb4b9109
|
|||
|
99c0491cb5
|
|||
|
e889bb37b6
|
|||
|
2db3ea8c62
|
|||
| d54303d0d7 | |||
|
|
f6fa7054bd | ||
|
|
6249d3ad42 | ||
| da241a8c9e | |||
| 525dae72e1 | |||
|
|
6182a1c3d4 | ||
|
|
a00aaa77cf | ||
| 57aa72b355 | |||
| 5ad42e6388 | |||
|
|
d0b2f0a4f4 | ||
|
af90927a84
|
|||
| 5a5c0606a7 | |||
|
|
946469a4db | ||
|
|
5aa8e1ad7e | ||
| b29144be8f | |||
|
c13bb89584
|
|||
|
|
aaed36e18b | ||
|
57f84e4bba
|
|||
|
8983cabd48
|
|||
|
8d856a30bd
|
|||
|
2518424ad1
|
|||
|
f587291d72
|
|||
|
b8dbba7a7e
|
|||
|
7d29ab31ce
|
|||
|
61345f3bcd
|
|||
|
7c21adb843
|
|||
|
dd88789f14
|
|||
|
4d8794d3d0
|
|||
|
aa0028901a
|
|||
|
901a11382d
|
|||
|
9e19d9798f
|
|||
|
97f01942af
|
|||
|
d622de1341
|
|||
|
6e1ed71674
|
|||
|
4ee2e79446
|
|||
|
c70553093d
|
|||
|
57b0d44c7d
|
|||
|
71fad013cf
|
|||
|
d2aee89c21
|
|||
|
544302de6e
|
|||
|
dfdc44b1e3
|
|||
|
05ab495a46
|
|||
|
f5829034a2
|
|||
|
f186dd8030
|
|||
|
ec885559af
|
|||
|
57c4547a66
|
|||
|
f8a90a3e33
|
|||
|
6700d94abb
|
|||
|
577b28cd6d
|
|||
|
f5c767426f
|
|||
|
9a9b18bfbc
|
|||
|
a2aaddb9b2
|
|||
|
eac58e39aa
|
|||
|
6ec3894175
|
|||
|
f8b333af70
|
|||
|
d021aaaea5
|
|||
|
0a892a80ad
|
|||
|
17ecda57fe
|
|||
|
4c0af665d5
|
|||
|
3ef13657cd
|
@@ -3,7 +3,9 @@
|
|||||||
"projectOwner": "Aetherinox",
|
"projectOwner": "Aetherinox",
|
||||||
"repoType": "github",
|
"repoType": "github",
|
||||||
"repoHost": "https://github.com",
|
"repoHost": "https://github.com",
|
||||||
"files": ["README.md"],
|
"files": [
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
"imageSize": 40,
|
"imageSize": 40,
|
||||||
"commit": true,
|
"commit": true,
|
||||||
"commitConvention": "angular",
|
"commitConvention": "angular",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# #
|
# #
|
||||||
# @file .editorconfig
|
# @file .editorconfig
|
||||||
# @author Aetherinox https://github.com/Aetherinox
|
# @author Aetherinox
|
||||||
|
# @repo https://github.com/TheBinaryNinja/tvapp2
|
||||||
# https://git.binaryninja.net/Aetherinox
|
# https://git.binaryninja.net/Aetherinox
|
||||||
# @ref http://editorconfig.org
|
# @ref http://editorconfig.org
|
||||||
# #
|
# #
|
||||||
|
|||||||
8
.github/ISSUE_TEMPLATE/bug-report.yml
vendored
@@ -14,6 +14,9 @@ body:
|
|||||||
4. Before creating this bug report, ensure you updated your applications to the latest versions.
|
4. Before creating this bug report, ensure you updated your applications to the latest versions.
|
||||||
Check your configurations to ensure there are no typos or errors.
|
Check your configurations to ensure there are no typos or errors.
|
||||||
Docker users should attempt to re-pull the TVApp2 image to ensure caching is not the cause of an issue.
|
Docker users should attempt to re-pull the TVApp2 image to ensure caching is not the cause of an issue.
|
||||||
|
5. To get detailed logs of the issue, set the environment variable:
|
||||||
|
`LOG_LEVEL=5`
|
||||||
|
Restart the docker container and you should get more detailed logs.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -126,9 +129,9 @@ body:
|
|||||||
- type: textarea
|
- type: textarea
|
||||||
id: docker-compose
|
id: docker-compose
|
||||||
attributes:
|
attributes:
|
||||||
label: docker-compose.yml
|
label: docker-compose.yml / Run command
|
||||||
description: |
|
description: |
|
||||||
Copy / paste your `docker-compose.yml` file here
|
Copy / paste your `docker-compose.yml` file or run command here
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: logs
|
id: logs
|
||||||
@@ -137,6 +140,7 @@ body:
|
|||||||
description: |
|
description: |
|
||||||
Paste your docker logs here.
|
Paste your docker logs here.
|
||||||
You can get your docker logs by opening terminal and running `docker logs tvapp2`
|
You can get your docker logs by opening terminal and running `docker logs tvapp2`
|
||||||
|
To get detailed logs, set the environment variable `LOG_LEVEL=5` and restart the container.
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: screenshots
|
id: screenshots
|
||||||
|
|||||||
1
.github/ISSUE_TEMPLATE/roadmap.yml
vendored
@@ -41,6 +41,7 @@ body:
|
|||||||
- Distribution
|
- Distribution
|
||||||
- Documentation
|
- Documentation
|
||||||
- M3U / EPG Functionality
|
- M3U / EPG Functionality
|
||||||
|
- Refactor (Code)
|
||||||
- Repository
|
- Repository
|
||||||
- S6-Overlay
|
- S6-Overlay
|
||||||
default: 0
|
default: 0
|
||||||
|
|||||||
302
.github/workflows/cache-clean.yml
vendored
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
# #
|
||||||
|
# @type github workflow
|
||||||
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage cleans up the cache for a repository.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# You can view your current cached items by going to Github and going to the page:
|
||||||
|
# https://github.com/USERNAME/REPO/actions/caches
|
||||||
|
#
|
||||||
|
# Caches have branch scope restrictions in place, which means some caches have limited usage options. For more information
|
||||||
|
# on cache scope restrictions, see Restrictions for accessing a cache, earlier in this article. If caches limited to a specific
|
||||||
|
# branch are using a lot of storage quota, it may cause caches from the default branch to be created and deleted at a high frequency.
|
||||||
|
#
|
||||||
|
# For example, a repository could have many new pull requests opened, each with their own caches that are restricted to that branch.
|
||||||
|
# These caches could take up the majority of the cache storage for that repository. Once a repository has reached its maximum cache
|
||||||
|
# storage, the cache eviction policy will create space by deleting the caches in order of last access date, from oldest to most
|
||||||
|
# recent. In order to prevent cache thrashing when this happens, you can set up workflows to delete caches on a faster cadence than
|
||||||
|
# the cache eviction policy will. You can use the GitHub CLI to delete caches for specific branches.
|
||||||
|
#
|
||||||
|
# @reference https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#deleting-cache-entries
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/cache-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/cache-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# #
|
||||||
|
|
||||||
|
# #
|
||||||
|
|
||||||
|
name: '🧹 Cache › Clean'
|
||||||
|
run-name: '🧹 Cache › Clean'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# triggers
|
||||||
|
# #
|
||||||
|
|
||||||
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Workflow Dispatch
|
||||||
|
# #
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Num Per Page
|
||||||
|
#
|
||||||
|
# this is the number of cached items to fetch per page.
|
||||||
|
# #
|
||||||
|
|
||||||
|
NUM_PER_PAGE:
|
||||||
|
description: '📦 Number Per Page'
|
||||||
|
required: true
|
||||||
|
default: '100'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# environment variables
|
||||||
|
# #
|
||||||
|
|
||||||
|
env:
|
||||||
|
NUM_PER_PAGE: ${{ github.event.inputs.NUM_PER_PAGE || '100' }}
|
||||||
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
|
# #
|
||||||
|
# jobs
|
||||||
|
# #
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cleanup:
|
||||||
|
name: >-
|
||||||
|
🧹 Cache › Clean
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 5
|
||||||
|
permissions: write-all
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Clean › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Clean › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Clean › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Clean › Start
|
||||||
|
#
|
||||||
|
# You can view your current cached items by going to Github and going to the page:
|
||||||
|
# https://github.com/USERNAME/REPO/actions/caches
|
||||||
|
#
|
||||||
|
# Caches have branch scope restrictions in place, which means some caches have limited usage options. For more information
|
||||||
|
# on cache scope restrictions, see Restrictions for accessing a cache, earlier in this article. If caches limited to a specific
|
||||||
|
# branch are using a lot of storage quota, it may cause caches from the default branch to be created and deleted at a high frequency.
|
||||||
|
#
|
||||||
|
# For example, a repository could have many new pull requests opened, each with their own caches that are restricted to that branch.
|
||||||
|
# These caches could take up the majority of the cache storage for that repository. Once a repository has reached its maximum cache
|
||||||
|
# storage, the cache eviction policy will create space by deleting the caches in order of last access date, from oldest to most
|
||||||
|
# recent. In order to prevent cache thrashing when this happens, you can set up workflows to delete caches on a faster cadence than
|
||||||
|
# the cache eviction policy will. You can use the GitHub CLI to delete caches for specific branches.
|
||||||
|
#
|
||||||
|
# @reference https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#deleting-cache-entries
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🪣 Cache › Clean
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const cacheConf =
|
||||||
|
{
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
per_page: ${{ env.NUM_PER_PAGE }},
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log( `✅ Starting to clean cache; showing ${{ env.NUM_PER_PAGE }} cached items per page` )
|
||||||
|
const caches = await github.rest.actions.getActionsCacheList( cacheConf )
|
||||||
|
|
||||||
|
while( caches.data.actions_caches.length )
|
||||||
|
{
|
||||||
|
for ( const cache of caches.data.actions_caches )
|
||||||
|
{
|
||||||
|
console.log( `⚠️ Clearing cache id: ${cache.key} (${cache.id})` )
|
||||||
|
const res = await github.rest.actions.deleteActionsCacheById(
|
||||||
|
{
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
cache_id: cache.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log( `✔️ Cache item ${cache.key} (${cache.id}) cleared at ${new Date().toISOString()}` )
|
||||||
|
}
|
||||||
|
|
||||||
|
caches = await github.rest.actions.getActionsCacheList(congif);
|
||||||
|
console.log( `Getting another ${caches.data.actions_caches.length} caches from github ...` );
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log( `✔️ Finished cleaning the cache` );
|
||||||
|
}
|
||||||
|
catch( e )
|
||||||
|
{
|
||||||
|
console.log( `❌ The workflow has terminated with an error:`, e )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Cache › Clean › Get Weekly Commits
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🕛 Get Weekly Commit List
|
||||||
|
run: |
|
||||||
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
330
.github/workflows/deploy-clean.yml
vendored
@@ -1,25 +1,58 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc cleans up the list of deployments in the environment history
|
|
||||||
# edit the 'environment:' to determine which deployment to keep clean
|
|
||||||
# - can be ran manually
|
|
||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage cleans up the list of deployments in the environment history
|
||||||
|
# edit the 'environment:' to determine which deployment to keep clean
|
||||||
|
# - can be ran manually
|
||||||
#
|
#
|
||||||
# @secrets secrets.SELF_TOKEN_CL Github Access Token (Classic)
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS Discord Webbhook URL; right-click on channel, click "Integrations"
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/deploy-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/deploy-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "⚙️ Deploy › Clean"
|
name: '🧹 Deployments › Clean'
|
||||||
run-name: "⚙️ Deploy › Clean"
|
run-name: '🧹 Deployments › Clean'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
# #
|
# #
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger > Workflow Dispatch
|
||||||
|
# #
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
|
|
||||||
@@ -47,6 +80,54 @@ on:
|
|||||||
default: '1000'
|
default: '1000'
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Name
|
||||||
|
#
|
||||||
|
# The discord bot name
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_NAME:
|
||||||
|
description: '🤖 Bot Name'
|
||||||
|
required: true
|
||||||
|
default: 'Europa'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Avatar
|
||||||
|
#
|
||||||
|
# The discord bot avatar to show; let's use some weird picture
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_AVATAR:
|
||||||
|
description: '🤖 Avatar URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://i.imgur.com/UqwMom1.jpeg'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Author Icon URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON:
|
||||||
|
description: '🤖 Embed Author Icon'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Thumbnail URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL:
|
||||||
|
description: '🤖 Embed Thumbnail URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# environment variables
|
# environment variables
|
||||||
# #
|
# #
|
||||||
@@ -54,69 +135,14 @@ on:
|
|||||||
env:
|
env:
|
||||||
DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }}
|
DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }}
|
||||||
DEPLOYMENT_DELAY: ${{ github.event.inputs.DEPLOYMENT_DELAY || '1000' }}
|
DEPLOYMENT_DELAY: ${{ github.event.inputs.DEPLOYMENT_DELAY || '1000' }}
|
||||||
|
DISCORD_BOT_NAME: ${{ github.event.inputs.DISCORD_BOT_NAME || 'Europa' }}
|
||||||
|
DISCORD_BOT_AVATAR: ${{ github.event.inputs.DISCORD_BOT_AVATAR || 'https://i.imgur.com/UqwMom1.jpeg' }}
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON: ${{ github.event.inputs.DISCORD_BOT_EMBED_AUTHOR_ICON || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL: ${{ github.event.inputs.DISCORD_BOT_EMBED_THUMBNAIL || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
LABELS_JSON: |
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
[
|
|
||||||
{ "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
|
|
||||||
{ "name": "AC › Changes Required", "color": "8F1784", "description": "Requires changes to be made to the package before being accepted" },
|
|
||||||
{ "name": "AC › Failed", "color": "a61f2d", "description": "Autocheck failed to run through a complete cycle, requires investigation" },
|
|
||||||
{ "name": "AC › Needs Rebase", "color": "8F1784", "description": "Due to the permissions on the requesting repo, this pull request must be rebased by the author" },
|
|
||||||
{ "name": "AC › Passed", "color": "146b4a", "description": "Ready to be reviewed" },
|
|
||||||
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
|
||||||
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
|
||||||
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
|
||||||
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
|
||||||
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
|
||||||
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
|
||||||
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
|
||||||
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by EuropaServ for a prolonged period of inactivity" },
|
|
||||||
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
|
||||||
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
|
|
||||||
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
|
|
||||||
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
|
||||||
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
|
||||||
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
|
|
||||||
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
|
||||||
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
|
||||||
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
|
||||||
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
|
||||||
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
|
|
||||||
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
|
||||||
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
|
||||||
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
|
||||||
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
|
||||||
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
|
||||||
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
|
||||||
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
|
||||||
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
|
||||||
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
|
|
||||||
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
|
||||||
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
|
||||||
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
|
||||||
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
|
||||||
{ "name": "› Customization", "color": "E3F0FC", "description": "Customizations: plugins, themes, configs" },
|
|
||||||
{ "name": "› Design", "color": "FA70DE", "description": "Design related queries" },
|
|
||||||
{ "name": "› Dist", "color": "FA70DE", "description": "Installers and other forms of software distribution" },
|
|
||||||
{ "name": "› Enterprise", "color": "11447a", "description": "Issues about collaboration, administration, and so on" },
|
|
||||||
{ "name": "› Hardware", "color": "5a7503", "description": "YubiKey, other tokens, biometrics" },
|
|
||||||
{ "name": "› Import/Export", "color": "F5FFCC", "description": "Import from and export to different file formats" },
|
|
||||||
{ "name": "› Improvement", "color": "185c98", "description": "Enhance an existing feature" },
|
|
||||||
{ "name": "› Performance", "color": "006b75", "description": "Web and desktop performance issues" },
|
|
||||||
{ "name": "› Plugin Request", "color": "FCE9CA", "description": "Requested changes should be implemented as a plugin" },
|
|
||||||
{ "name": "› Security", "color": "F75D39", "description": "Security issues" },
|
|
||||||
{ "name": "› Self-Hosting", "color": "fad8c7", "description": "Self-hosting installations and configs" },
|
|
||||||
{ "name": "› Storage", "color": "5319e7", "description": "Storage providers: Dropbox, Google, WebDAV, etc." },
|
|
||||||
{ "name": "› Updater", "color": "1BADDE", "description": "Auto-updater issues" },
|
|
||||||
{ "name": "› UX", "color": "1BADDE", "description": "UX and usability" },
|
|
||||||
{ "name": "› Website", "color": "fef2c0", "description": "Website related issues" },
|
|
||||||
{ "name": "⚠ Urgent", "color": "a8740e", "description": "Requires urgent attention" },
|
|
||||||
{ "name": "⚠ Announcement", "color": "DB4712", "description": "Announcements" },
|
|
||||||
{ "name": "📰 Progress Report", "color": "392297", "description": "Development updates" },
|
|
||||||
{ "name": "📦 Release", "color": "277542", "description": "Release announcements" },
|
|
||||||
{ "name": "✔️ Poll", "color": "972255", "description": "Community polls" },
|
|
||||||
{ "name": "❔ Question", "color": "FFFFFF", "description": "All questions" }
|
|
||||||
]
|
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# jobs
|
# jobs
|
||||||
@@ -124,44 +150,139 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cleanup:
|
cleanup:
|
||||||
# runs-on: ubuntu-latest
|
name: >-
|
||||||
runs-on: apollo-x64
|
🧹 Deployments › Clean
|
||||||
timeout-minutes: 20
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 5
|
||||||
permissions: write-all
|
permissions: write-all
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Set Env Variables
|
# Deployments › Cleanup › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: '☑️ Checkout'
|
||||||
🕛 Get Timestamp
|
|
||||||
id: task_cleanup_set_timestamp
|
|
||||||
run: |
|
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Release › Github › Checkout › Arm64
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
✅ Checkout
|
|
||||||
id: task_cleanup_gh_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Start
|
# Deployments › Cleanup › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Deployments › Cleanup › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Deployments › Cleanup › Start
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
⚙️ Deployments › Clean
|
⚙️ Deployments › Clean
|
||||||
id: task_cleanup_start
|
|
||||||
uses: Aetherinox/delete-deploy-env-action@v3
|
uses: Aetherinox/delete-deploy-env-action@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.SELF_TOKEN_CL }}
|
token: ${{ secrets.SELF_TOKEN_CL }}
|
||||||
@@ -170,33 +291,31 @@ jobs:
|
|||||||
delay: "${{ env.DEPLOYMENT_DELAY }}"
|
delay: "${{ env.DEPLOYMENT_DELAY }}"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Get Weekly Commits
|
# Deployments › Cleanup › Get Weekly Commits
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Weekly Commit List
|
🕛 Get Weekly Commit List
|
||||||
id: task_cleanup_set_weekly_commit_list
|
|
||||||
run: |
|
run: |
|
||||||
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
echo 'EOF' >> $GITHUB_ENV
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Notify Github › Success
|
# Deployments › Cleanup › Notify Github › Success
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Success)
|
🔔 Send Discord Webhook Message (Success)
|
||||||
id: task_cleanup_notify_discord_success
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: success()
|
if: success()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
|
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -215,24 +334,23 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Notify Github › Failure
|
# Deployments › Cleanup › Notify Github › Failure
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Failure)
|
🔔 Send Discord Webhook Message (Failure)
|
||||||
id: task_cleanup_notify_discord_failure
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
|
## 📦 Deployment Cleanup ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -251,5 +369,5 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
|
|||||||
1852
.github/workflows/deploy-docker-all.yml
vendored
951
.github/workflows/deploy-docker-dockerhub.yml
vendored
1145
.github/workflows/deploy-docker-gitea.yml
vendored
783
.github/workflows/deploy-docker-giteacom.yml
vendored
Normal file
@@ -0,0 +1,783 @@
|
|||||||
|
# #
|
||||||
|
# @type github workflow
|
||||||
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage deploys docker container to Gitea.com and send message to discord
|
||||||
|
# upload this workflow to both the `main` branch of the tvapp2 repository
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/deploy-docker-giteacom.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/deploy-docker-giteacom.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# #
|
||||||
|
|
||||||
|
name: "📦 Deploy › Docker › Gitea.com"
|
||||||
|
run-name: "📦 Deploy › Docker › Gitea.com"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Triggers
|
||||||
|
# #
|
||||||
|
|
||||||
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Workflow Dispatch
|
||||||
|
#
|
||||||
|
# If any values are not provided, will use fallback env variable
|
||||||
|
# #
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Image Name
|
||||||
|
#
|
||||||
|
# used in github image path
|
||||||
|
# gitea.com/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
|
||||||
|
# #
|
||||||
|
|
||||||
|
IMAGE_NAME:
|
||||||
|
description: '📦 Image Name'
|
||||||
|
required: true
|
||||||
|
default: 'tvapp2'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Image Version
|
||||||
|
#
|
||||||
|
# used to create new release tag, and add version to docker image name
|
||||||
|
# #
|
||||||
|
|
||||||
|
IMAGE_VERSION:
|
||||||
|
description: '🏷️ Image Version'
|
||||||
|
required: true
|
||||||
|
default: '1.0.0'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Gitea › Author
|
||||||
|
#
|
||||||
|
# used in github image path
|
||||||
|
# gitea.com/${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }}
|
||||||
|
# #
|
||||||
|
|
||||||
|
IMAGE_GITEA_AUTHOR:
|
||||||
|
description: '🪪 Image Author'
|
||||||
|
required: true
|
||||||
|
default: 'BinaryNinja'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Gitea › Username
|
||||||
|
#
|
||||||
|
# this is the user to sign into gitea as.
|
||||||
|
# #
|
||||||
|
|
||||||
|
IMAGE_GITEA_USERNAME:
|
||||||
|
description: '🪪 Gitea Username'
|
||||||
|
required: true
|
||||||
|
default: 'aetherinox'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Gitea › Website
|
||||||
|
#
|
||||||
|
# this is the gitea website / url to push to
|
||||||
|
# #
|
||||||
|
|
||||||
|
IMAGE_GITEA_WEBSITE:
|
||||||
|
description: '🌎 Gitea Website'
|
||||||
|
required: true
|
||||||
|
default: 'gitea.com'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# true no changes to the repo will be made
|
||||||
|
# false workflow will behave normally, and push any changes detected to the files
|
||||||
|
# #
|
||||||
|
|
||||||
|
DRY_RUN:
|
||||||
|
description: '🐛 Dry Run (Debug)'
|
||||||
|
required: true
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
# #
|
||||||
|
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
|
||||||
|
# false release version will be marked with -latest docker tag
|
||||||
|
# #
|
||||||
|
|
||||||
|
DEV_RELEASE:
|
||||||
|
description: '🧪 Development Release'
|
||||||
|
required: true
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Push
|
||||||
|
# #
|
||||||
|
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Environment Vars
|
||||||
|
# #
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE_NAME: ${{ github.event.inputs.IMAGE_NAME || 'tvapp2' }}
|
||||||
|
IMAGE_VERSION: ${{ github.event.inputs.IMAGE_VERSION || '1.0.0' }}
|
||||||
|
IMAGE_GITEA_AUTHOR: ${{ github.event.inputs.IMAGE_GITEA_AUTHOR || 'BinaryNinja' }}
|
||||||
|
IMAGE_GITEA_USERNAME: ${{ github.event.inputs.IMAGE_GITEA_USERNAME || 'BinaryNinja' }}
|
||||||
|
IMAGE_GITEA_WEBSITE: ${{ github.event.inputs.IMAGE_GITEA_WEBSITE || 'gitea.com' }}
|
||||||
|
|
||||||
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Jobs
|
||||||
|
#
|
||||||
|
# The way pushed docker containers on Gitea work, the most recent image built goes at the top.
|
||||||
|
# We will use the order below which builds the :latest image last so that it appears at the very
|
||||||
|
# top of the packages page.
|
||||||
|
# #
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Job › Create Tag
|
||||||
|
# #
|
||||||
|
|
||||||
|
job-docker-release-tags-create:
|
||||||
|
name: >-
|
||||||
|
📦 Release › Create Tag
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
runs-on: apollo-x64
|
||||||
|
timeout-minutes: 4
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Tags › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🏳️ Start'
|
||||||
|
id: task_release_tags_start
|
||||||
|
run: |
|
||||||
|
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }}"
|
||||||
|
echo "Using original Gitea workflow without manifest"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Tags › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '✅ Checkout'
|
||||||
|
id: task_release_tags_checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Tags › Fix Permissions
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '#️⃣ Manage Permissions'
|
||||||
|
id: task_release_tags_permissions
|
||||||
|
run: |
|
||||||
|
find ./ -name 'run' -exec chmod 755 {} \;
|
||||||
|
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
|
||||||
|
if [ -n "${WRONG_PERM}" ]; then
|
||||||
|
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
|
||||||
|
for i in ${WRONG_PERM}; do
|
||||||
|
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅✅✅ Executable permissions are OK ✅✅✅"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Tags › Create Tag
|
||||||
|
#
|
||||||
|
# only called in dispatch mode
|
||||||
|
# #
|
||||||
|
|
||||||
|
- uses: rickstaa/action-create-tag@v1
|
||||||
|
id: task_release_tags_create
|
||||||
|
if: ( github.event_name != 'workflow_dispatch' && inputs.DRY_RUN == false )
|
||||||
|
with:
|
||||||
|
tag: "${{ env.IMAGE_VERSION }}"
|
||||||
|
tag_exists_error: false
|
||||||
|
message: '${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}'
|
||||||
|
gpg_private_key: ${{ secrets.ADMINSERV_GPG_KEY_ASC }}
|
||||||
|
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Job › Docker Release › Gitea › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
job-docker-release-gitea-arm64:
|
||||||
|
name: >-
|
||||||
|
📦 Release › Gitea › Arm64
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
runs-on: apollo-x64
|
||||||
|
timeout-minutes: 10
|
||||||
|
needs: [ job-docker-release-tags-create ]
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Start › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🏳️ Start'
|
||||||
|
id: task_release_gi_start
|
||||||
|
run: |
|
||||||
|
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }} › arm64"
|
||||||
|
echo "Using original Gitea workflow without manifest"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Checkout › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '✅ Checkout'
|
||||||
|
id: task_release_gh_checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Get Timestamp
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🕛 Get Timestamp'
|
||||||
|
id: task_release_set_timestamp
|
||||||
|
run: |
|
||||||
|
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
|
||||||
|
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
|
||||||
|
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja/tvapp2
|
||||||
|
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja
|
||||||
|
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
|
||||||
|
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
|
||||||
|
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
|
||||||
|
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
|
||||||
|
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Install Dependencies
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '📦 Install Dependencies'
|
||||||
|
id: task_release_gi_dependencies
|
||||||
|
run:
|
||||||
|
sudo apt-get install -qq dos2unix
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Execute dos2unix
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔐 Apply dos2unix'
|
||||||
|
id: task_release_gi_dos2unix
|
||||||
|
run: |
|
||||||
|
echo "⚠️⚠️⚠️ Running DOS2UNIX ⚠️⚠️⚠️"
|
||||||
|
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
|
||||||
|
echo "✅✅✅ Completed DOS2UNIX ✅✅✅"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Fix Permissions
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '#️⃣ Manage Permissions'
|
||||||
|
id: task_release_gi_permissions
|
||||||
|
run: |
|
||||||
|
find ./ -name 'run' -exec chmod 755 {} \;
|
||||||
|
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
|
||||||
|
if [ -n "${WRONG_PERM}" ]; then
|
||||||
|
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
|
||||||
|
for i in ${WRONG_PERM}; do
|
||||||
|
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅✅✅ Executable permissions are OK ✅✅✅"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › QEMU › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Set up QEMU'
|
||||||
|
id: task_release_gi_qemu
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Setup BuildX › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Setup Buildx'
|
||||||
|
id: task_release_gi_buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
driver-opts: 'image=moby/buildkit:latest'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Registry Login › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Login to Gitea'
|
||||||
|
id: task_release_gi_registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.IMAGE_GITEA_WEBSITE }}
|
||||||
|
username: ${{ env.IMAGE_GITEA_USERNAME }}
|
||||||
|
password: ${{ secrets.ORG_BINARYNINJA_GITEACOM_TOKEN }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Meta › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔨 Gitea: Meta - Arm64'
|
||||||
|
id: task_release_gi_meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
# latest no
|
||||||
|
type=raw,value=latest,enable=false
|
||||||
|
|
||||||
|
# tag add arm64
|
||||||
|
# type=raw,enable=true,priority=1000,value=arm64
|
||||||
|
|
||||||
|
# dispatch add x1.x.x-arm64
|
||||||
|
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=300,prefix=,suffix=-arm64,value=${{ env.IMAGE_VERSION }}
|
||||||
|
|
||||||
|
# dispatch add arm64-development
|
||||||
|
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=-arm64,value=development
|
||||||
|
|
||||||
|
# tag add tag-arm64
|
||||||
|
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-arm64,event=tag
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
|
||||||
|
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
|
||||||
|
org.opencontainers.image.licenses=MIT
|
||||||
|
org.opencontainers.image.revision=${{ github.sha }}
|
||||||
|
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
|
||||||
|
org.opencontainers.image.ref.name=${{ github.ref_name }}
|
||||||
|
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
|
||||||
|
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Build and Push › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '📦 Build & Push (linux/arm64)'
|
||||||
|
id: task_release_gi_push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile.aarch64
|
||||||
|
platforms: linux/arm64
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.task_release_gi_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.task_release_gi_meta.outputs.labels }}
|
||||||
|
provenance: false
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Checkpoint › Arm64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚠️ Checkpoint'
|
||||||
|
id: task_release_gi_checkpoint
|
||||||
|
run: |
|
||||||
|
echo "registry ................................. Gitea"
|
||||||
|
echo "github.actor.............................. ${{ github.actor }}"
|
||||||
|
echo "github.ref ............................... ${{ github.ref }}"
|
||||||
|
echo "github.ref_name .......................... ${{ github.ref_name }}"
|
||||||
|
echo "github.event_name ........................ ${{ github.event_name }}"
|
||||||
|
echo "github.repository_owner .................. ${{ github.repository_owner }}"
|
||||||
|
echo "github.repository ........................ ${{ github.repository }}"
|
||||||
|
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
|
||||||
|
echo "env.AUTHOR ............................... ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
|
||||||
|
echo "tags ..................................... ${{ steps.task_release_gi_meta.outputs.tags }}"
|
||||||
|
echo "labels ................................... ${{ steps.task_release_gi_meta.outputs.labels }}"
|
||||||
|
echo "docker image ............................. ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
|
||||||
|
echo "docker sha ............................... ${{ env.DOCKER_SHA }}"
|
||||||
|
echo "docker image id .......................... ${{ steps.task_release_gi_push.outputs.imageid }}"
|
||||||
|
echo "docker digest ............................ ${{ steps.task_release_gi_push.outputs.digest }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Get Weekly Commits
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🕛 Get Weekly Commit List'
|
||||||
|
id: task_release_set_weekly_commit_list
|
||||||
|
run: |
|
||||||
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Notify Gitea
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔔 Send Discord Webhook Message'
|
||||||
|
id: task_release_notifications_discord_send
|
||||||
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
|
if: success()
|
||||||
|
with:
|
||||||
|
username: 'Io'
|
||||||
|
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
||||||
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
|
||||||
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
||||||
|
embed-description: |
|
||||||
|
## 📦 Docker › Deploy (Gitea) ${{ job.status == 'success' && '✅' || '❌' }} › `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
|
||||||
|
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
|
||||||
|
|
||||||
|
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Gitea. The image is available at:
|
||||||
|
- https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
|
||||||
|
|
||||||
|
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
|
||||||
|
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}-arm64`
|
||||||
|
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push.outputs.digest }}`
|
||||||
|
- Dry Run: `${{ inputs.DRY_RUN }}`
|
||||||
|
- Source: `Gitea` https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
|
||||||
|
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
|
||||||
|
- Version: `${{ env.IMAGE_VERSION }}`
|
||||||
|
- Branch: `${{ github.ref_name }}`
|
||||||
|
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
|
||||||
|
- Runner: `${{ runner.name }}`
|
||||||
|
- Triggered By: `${{ github.actor }}`
|
||||||
|
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
|
||||||
|
|
||||||
|
### Tags
|
||||||
|
-# This docker image will use the following tags:
|
||||||
|
|
||||||
|
```
|
||||||
|
${{ steps.task_release_gi_meta.outputs.tags }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
-# This docker image embeds the following labels:
|
||||||
|
|
||||||
|
```
|
||||||
|
${{ steps.task_release_gi_meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
||||||
|
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
||||||
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Job › Docker Release › Gitea › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
job-docker-release-gitea-amd64:
|
||||||
|
name: >-
|
||||||
|
📦 Release › Gitea › Amd64
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
runs-on: apollo-x64
|
||||||
|
timeout-minutes: 10
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
needs: [ job-docker-release-tags-create, job-docker-release-gitea-arm64 ]
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Start › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🏳️ Start'
|
||||||
|
id: task_release_gi_start
|
||||||
|
run: |
|
||||||
|
echo "Generating Docker Image on ${{ env.IMAGE_GITEA_WEBSITE }} › amd64"
|
||||||
|
echo "Using original Gitea workflow without manifest"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '✅ Checkout'
|
||||||
|
id: task_release_gh_checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Get Timestamp
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🕛 Get Timestamp'
|
||||||
|
id: task_release_set_timestamp
|
||||||
|
run: |
|
||||||
|
echo "IMAGE_VERSION_1DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1`" >> ${GITHUB_ENV} # 1
|
||||||
|
echo "IMAGE_VERSION_2DIGIT=`echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-2`" >> ${GITHUB_ENV} # 1.0
|
||||||
|
echo "REGISTRY_REPO_ORG_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }}/${{ env.IMAGE_NAME }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja/tvapp2
|
||||||
|
echo "REGISTRY_REPO_AUTHOR_LC=`echo ${{ env.IMAGE_GITEA_AUTHOR }} | tr '[:upper:]' '[:lower:]'`" >> ${GITHUB_ENV} # binaryninja
|
||||||
|
echo "DOCKER_SHA=${GITHUB_SHA}" >> $GITHUB_ENV # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV # 02-25-2025 12:49:48
|
||||||
|
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV # 02-25-2025
|
||||||
|
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV # 02-25-2025 12:49
|
||||||
|
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV # 20250225
|
||||||
|
echo "NOW_DOCKER_TS=$(date -u +'%FT%T.%3NZ')" >> $GITHUB_ENV # 2025-02-25T12:50:11.569Z
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Install Dependencies
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '📦 Install Dependencies'
|
||||||
|
id: task_release_gi_dependencies
|
||||||
|
run:
|
||||||
|
sudo apt-get install -qq dos2unix
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Execute dos2unix
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔐 Apply dos2unix'
|
||||||
|
id: task_release_gi_dos2unix
|
||||||
|
run: |
|
||||||
|
find ./ \( -path "./.git" -o -path "./docs" -o -path "./.github" -o -path "*.png" -o -path "*.jpg" \) -prune -o -name '*' -print | xargs dos2unix --
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Fix Permissions
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '#️⃣ Manage Permissions'
|
||||||
|
id: task_release_gi_permissions
|
||||||
|
run: |
|
||||||
|
find ./ -name 'run' -exec chmod 755 {} \;
|
||||||
|
WRONG_PERM=$(find ./ -path "./.git" -prune -o \( -name "run" -o -name "finish" -o -name "check" \) -not -perm -u=x,g=x,o=x -print)
|
||||||
|
if [ -n "${WRONG_PERM}" ]; then
|
||||||
|
echo "⚠️⚠️⚠️ Permissions are invalid ⚠️⚠️⚠️"
|
||||||
|
for i in ${WRONG_PERM}; do
|
||||||
|
echo "::error file=${i},line=1,title=Missing Executable Bit::This file needs to be set as executable!"
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅✅✅ Executable permissions are OK ✅✅✅"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › QEMU › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Set up QEMU'
|
||||||
|
id: task_release_gi_qemu
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Setup BuildX › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Setup Buildx'
|
||||||
|
id: task_release_gi_buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
driver-opts: 'image=moby/buildkit:latest'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Registry Login › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Login to Gitea'
|
||||||
|
id: task_release_gi_registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.IMAGE_GITEA_WEBSITE }}
|
||||||
|
username: ${{ env.IMAGE_GITEA_USERNAME }}
|
||||||
|
password: ${{ secrets.ORG_BINARYNINJA_GITEACOM_TOKEN }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Meta › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔨 Gitea: Meta - Amd64'
|
||||||
|
id: task_release_gi_meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_AUTHOR_LC }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
# latest yes
|
||||||
|
type=raw,value=latest,enable=${{ !inputs.DEV_RELEASE }}
|
||||||
|
|
||||||
|
# tag add amd64
|
||||||
|
# type=raw,enable=true,priority=1000,value=amd64
|
||||||
|
|
||||||
|
# dispatch add x1.x.x-amd64
|
||||||
|
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == false }},priority=300,prefix=,suffix=-amd64,value=${{ env.IMAGE_VERSION }}
|
||||||
|
|
||||||
|
# dispatch add amd64-development
|
||||||
|
type=raw,enable=${{ github.event_name == 'workflow_dispatch' && inputs.DEV_RELEASE == true }},priority=300,prefix=,suffix=-amd64,value=development
|
||||||
|
|
||||||
|
# tag add tag-amd64
|
||||||
|
type=ref,enable=${{ github.event_name == 'pull_request' || github.event_name == 'push' }},priority=600,prefix=,suffix=-amd64,event=tag
|
||||||
|
|
||||||
|
# add development tag to default architecture (amd64)
|
||||||
|
type=raw,enable=${{ inputs.DEV_RELEASE }},priority=400,prefix=,suffix=,value=development
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
|
||||||
|
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
|
||||||
|
org.opencontainers.image.licenses=MIT
|
||||||
|
org.opencontainers.image.revision=${{ github.sha }}
|
||||||
|
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
|
||||||
|
org.opencontainers.image.ref.name=${{ github.ref_name }}
|
||||||
|
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
|
||||||
|
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
|
||||||
|
annotations: |
|
||||||
|
org.opencontainers.image.created=${{ env.NOW_DOCKER_TS }}
|
||||||
|
org.opencontainers.image.version=${{ env.IMAGE_VERSION }}
|
||||||
|
org.opencontainers.image.licenses=MIT
|
||||||
|
org.opencontainers.image.revision=${{ github.sha }}
|
||||||
|
org.opencontainers.image.vendor=${{ env.REGISTRY_REPO_AUTHOR_LC }}
|
||||||
|
org.opencontainers.image.ref.name=${{ github.ref_name }}
|
||||||
|
org.opencontainers.image.development=${{ inputs.DEV_RELEASE == true && 'true' || 'false' }}
|
||||||
|
org.tvapp2.image.build-version="Version:- ${{ env.IMAGE_VERSION }} Date:- ${{ env.NOW_DOCKER_LABEL }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Build and Push › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '📦 Build & Push (linux/amd64)'
|
||||||
|
id: task_release_gi_push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
if: ( github.event_name == 'workflow_dispatch' && inputs.DRY_RUN == false ) || ( github.event_name == 'push' )
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.task_release_gi_meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.task_release_gi_meta.outputs.labels }}
|
||||||
|
provenance: false
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Checkpoint › Amd64
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚠️ Checkpoint'
|
||||||
|
id: task_release_gi_checkpoint
|
||||||
|
run: |
|
||||||
|
echo "registry ................................. Gitea"
|
||||||
|
echo "github.actor.............................. ${{ github.actor }}"
|
||||||
|
echo "github.ref ............................... ${{ github.ref }}"
|
||||||
|
echo "github.ref_name .......................... ${{ github.ref_name }}"
|
||||||
|
echo "github.event_name ........................ ${{ github.event_name }}"
|
||||||
|
echo "github.repository_owner .................. ${{ github.repository_owner }}"
|
||||||
|
echo "github.repository ........................ ${{ github.repository }}"
|
||||||
|
echo "inputs.DRY_RUN ........................... ${{ inputs.DRY_RUN }}"
|
||||||
|
echo "env.AUTHOR ............................... ${{ env.REGISTRY_REPO_AUTHOR_LC }}"
|
||||||
|
echo "tags ..................................... ${{ steps.task_release_gi_meta.outputs.tags }}"
|
||||||
|
echo "labels ................................... ${{ steps.task_release_gi_meta.outputs.labels }}"
|
||||||
|
echo "docker image ............................. ${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}"
|
||||||
|
echo "docker sha ............................... ${{ env.DOCKER_SHA }}"
|
||||||
|
echo "docker image id .......................... ${{ steps.task_release_gi_push.outputs.imageid }}"
|
||||||
|
echo "docker digest ............................ ${{ steps.task_release_gi_push.outputs.digest }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Get Weekly Commits
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🕛 Get Weekly Commit List'
|
||||||
|
id: task_release_set_weekly_commit_list
|
||||||
|
run: |
|
||||||
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Gitea › Notify Gitea
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔔 Send Discord Webhook Message'
|
||||||
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
|
if: success()
|
||||||
|
with:
|
||||||
|
username: 'Io'
|
||||||
|
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
||||||
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES }}
|
||||||
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
||||||
|
embed-description: |
|
||||||
|
## 📦 Docker › Deploy (Gitea) ${{ job.status == 'success' && '✅' || '❌' }} › `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
|
||||||
|
${{ inputs.DEV_RELEASE == true && '### ⚠️⚠️ Development / Pre-release ⚠️⚠️' || '' }}
|
||||||
|
|
||||||
|
A new version of the docker container `${{ env.IMAGE_NAME }}` has been released from Github to Gitea. The image is available at:
|
||||||
|
- https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
|
||||||
|
|
||||||
|
- Release Type: `${{ inputs.DEV_RELEASE == true && '⚠️⚠️ Development / Pre-release ⚠️⚠️' || 'Stable' }}`
|
||||||
|
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}:${{ inputs.DEV_RELEASE == true && 'development' || env.IMAGE_VERSION }}-amd64`
|
||||||
|
- Pull: `docker pull ${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.REGISTRY_REPO_ORG_AUTHOR_LC }}@${{ steps.task_release_gi_push.outputs.digest }}`
|
||||||
|
- Dry Run: `${{ inputs.DRY_RUN }}`
|
||||||
|
- Source: `Gitea` https://${{ env.IMAGE_GITEA_WEBSITE }}/${{ env.IMAGE_GITEA_USERNAME }}/${{ env.IMAGE_NAME }}/packages
|
||||||
|
- Docker Image: `${{ env.IMAGE_NAME }}-${{ env.IMAGE_VERSION }}${{ inputs.DEV_RELEASE == true && '-development' || '' }}`
|
||||||
|
- Version: `${{ env.IMAGE_VERSION }}`
|
||||||
|
- Branch: `${{ github.ref_name }}`
|
||||||
|
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
|
||||||
|
- Runner: `${{ runner.name }}`
|
||||||
|
- Triggered By: `${{ github.actor }}`
|
||||||
|
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
|
||||||
|
|
||||||
|
### Tags
|
||||||
|
-# This docker image will use the following tags:
|
||||||
|
|
||||||
|
```
|
||||||
|
${{ steps.task_release_gi_meta.outputs.tags }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
-# This docker image embeds the following labels:
|
||||||
|
|
||||||
|
```
|
||||||
|
${{ steps.task_release_gi_meta.outputs.labels }}
|
||||||
|
```
|
||||||
|
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
||||||
|
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
||||||
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
||||||
1015
.github/workflows/deploy-docker-github.yml
vendored
319
.github/workflows/documentation.yml
vendored
@@ -1,44 +1,168 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc builds mkdocs from the main branch /docs/ folder and puts the compiled version
|
|
||||||
# in the `gh-pages` branch. Is hosted using Github Pages.
|
|
||||||
#
|
|
||||||
# @update pip install --upgrade mkdocs
|
|
||||||
# pip install --upgrade --force-reinstall mkdocs-material
|
|
||||||
#
|
|
||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage builds mkdocs from the main branch /docs/ folder and puts the compiled version
|
||||||
|
# in the `gh-pages` branch. Is hosted using Github Pages.
|
||||||
#
|
#
|
||||||
# @secrets secrets.SELF_TOKEN_CL Github Access Token (Classic)
|
# @update use the following commands to update mkdocs and the mkdocs-material theme:
|
||||||
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS Discord Webbhook URL; right-click on channel, click "Integrations"
|
# pip install --upgrade mkdocs
|
||||||
|
# pip install --upgrade --force-reinstall mkdocs-material
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/documentation.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/documentation.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "📒 Docs › Build"
|
name: '📒 Docs › Build'
|
||||||
run-name: "📒 Docs › Build"
|
run-name: '📒 Docs › Build'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
# #
|
# #
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Release
|
||||||
|
#
|
||||||
|
# update documentation every time a release is made
|
||||||
|
# #
|
||||||
|
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
- published
|
- published
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Push
|
||||||
|
#
|
||||||
|
# update documentation every time a file in docs/ folder is modified
|
||||||
|
# #
|
||||||
|
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- docs/**
|
- docs/**
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Workflow Dispatch
|
||||||
|
#
|
||||||
|
# If any values are not provided, will use fallback env variable
|
||||||
|
# #
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
inputs:
|
||||||
- cron: "0 */12 * * *"
|
|
||||||
|
# #
|
||||||
|
# Image Name
|
||||||
|
#
|
||||||
|
# used in github image path
|
||||||
|
# ghcr.io/${{ env.IMAGE_GHCR_AUTHOR }}/${{ env.IMAGE_NAME }}
|
||||||
|
# #
|
||||||
|
|
||||||
|
WORKING_DIR:
|
||||||
|
description: '📁 Docs Folder'
|
||||||
|
required: true
|
||||||
|
default: './docs/site'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Name
|
||||||
|
#
|
||||||
|
# The discord bot name
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_NAME:
|
||||||
|
description: '🤖 Bot Name'
|
||||||
|
required: true
|
||||||
|
default: 'Europa'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Avatar
|
||||||
|
#
|
||||||
|
# The discord bot avatar to show; let's use some weird picture
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_AVATAR:
|
||||||
|
description: '🤖 Avatar URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://i.imgur.com/UqwMom1.jpeg'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Author Icon URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON:
|
||||||
|
description: '🤖 Embed Author Icon'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Thumbnail URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL:
|
||||||
|
description: '🤖 Embed Thumbnail URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger › Cron
|
||||||
|
#
|
||||||
|
# update documentation every X hours
|
||||||
|
# #
|
||||||
|
|
||||||
|
# schedule:
|
||||||
|
# - cron: "0 */12 * * *"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# environment variables
|
# environment variables
|
||||||
# #
|
# #
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
WORKING_DIR: ${{ github.event.inputs.WORKING_DIR || './docs/site' }}
|
||||||
|
DISCORD_BOT_NAME: ${{ github.event.inputs.DISCORD_BOT_NAME || 'Europa' }}
|
||||||
|
DISCORD_BOT_AVATAR: ${{ github.event.inputs.DISCORD_BOT_AVATAR || 'https://i.imgur.com/UqwMom1.jpeg' }}
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON: ${{ github.event.inputs.DISCORD_BOT_EMBED_AUTHOR_ICON || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL: ${{ github.event.inputs.DISCORD_BOT_EMBED_THUMBNAIL || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
ASSIGN_USER: Aetherinox
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# jobs
|
# jobs
|
||||||
@@ -46,9 +170,9 @@ env:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-docs:
|
build-docs:
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 20
|
timeout-minutes: 10
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
pages: write
|
pages: write
|
||||||
@@ -57,44 +181,139 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Checkout › Arm64
|
# Documentation › Build › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: '☑️ Checkout'
|
||||||
✅ Checkout
|
|
||||||
id: task_docs_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Set Env Variables
|
# Documentation › Build › Job Information
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Timestamp
|
🔄 Load Job
|
||||||
id: task_docs_set_timestamp
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Documentation › Build › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
run: |
|
run: |
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
echo ""
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Setup Python
|
# Documentation › Build › Setup Python
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🐍 Setup Python"
|
- name: >-
|
||||||
id: task_docs_python_setup
|
🐍 Setup Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.x
|
python-version: 3.x
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Build Documentation
|
# Documentation › Build › Build
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
📕 Build Documentation
|
📕 Build Documentation
|
||||||
id: task_docs_build
|
|
||||||
run: |
|
run: |
|
||||||
export DOCS_NAME=${{ secrets.DOCS_NAME || 'TVApp2' }}
|
export DOCS_NAME=${{ secrets.DOCS_NAME || 'TVApp2' }}
|
||||||
export DOCS_SECRET_L1=${{ secrets.DOCS_SECRET_L1 }}
|
export DOCS_SECRET_L1=${{ secrets.DOCS_SECRET_L1 }}
|
||||||
@@ -104,6 +323,7 @@ jobs:
|
|||||||
pip install mkdocs
|
pip install mkdocs
|
||||||
pip install mkdocs-material
|
pip install mkdocs-material
|
||||||
pip install mike
|
pip install mike
|
||||||
|
pip install mkdocs-embed-external-markdown
|
||||||
pip install mkdocs-git-committers-plugin-2
|
pip install mkdocs-git-committers-plugin-2
|
||||||
pip install mkdocs-encryptcontent-plugin
|
pip install mkdocs-encryptcontent-plugin
|
||||||
pip install mkdocs-redirects mkdocs-glightbox pymdown-extensions mkdocs-git-revision-date-localized-plugin mkdocs-git-authors-plugin mkdocs-link-embeds-plugin
|
pip install mkdocs-redirects mkdocs-glightbox pymdown-extensions mkdocs-git-revision-date-localized-plugin mkdocs-git-authors-plugin mkdocs-link-embeds-plugin
|
||||||
@@ -114,45 +334,43 @@ jobs:
|
|||||||
GH_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
GH_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Deploy
|
# Documentation › Build › Deploy
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "💽 Deploy"
|
- name: >-
|
||||||
id: task_docs_deploy
|
💽 Deploy
|
||||||
uses: peaceiris/actions-gh-pages@v4
|
uses: peaceiris/actions-gh-pages@v4
|
||||||
with:
|
with:
|
||||||
personal_token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
personal_token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
publish_dir: ./docs/site
|
publish_dir: "${{ env.WORKING_DIR }}"
|
||||||
|
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Get Weekly Commits
|
# Documentation › Build › Get Weekly Commits
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Weekly Commit List
|
🕛 Get Weekly Commit List
|
||||||
id: task_docs_set_weekly_commit_list
|
|
||||||
run: |
|
run: |
|
||||||
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
echo 'EOF' >> $GITHUB_ENV
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Notify Github › Success
|
# Documentation › Build › Notify Github › Success
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Success)
|
🔔 Send Discord Webhook Message (Success)
|
||||||
id: task_docs_notify_discord_success
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: success()
|
if: success()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
|
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -169,24 +387,23 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Documentation › Notify Github › Failure
|
# Documentation › Build › Notify Github › Failure
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Failure)
|
🔔 Send Discord Webhook Message (Failure)
|
||||||
id: task_docs_notify_discord_failure
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
|
## 📦 Documentation Deployment${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -203,5 +420,5 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
|
|||||||
366
.github/workflows/gpg-tests.yml
vendored
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
# #
|
||||||
|
# @type github workflow
|
||||||
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage tests gpg keys
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/gpg-tests.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/gpg-tests.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# #
|
||||||
|
|
||||||
|
name: '🔑 GPG › Tests'
|
||||||
|
run-name: '🔑 GPG › Tests'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# triggers
|
||||||
|
# #
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Name of the plugin to use when creating the release zip filename
|
||||||
|
# e.g: ntfy-desktop-v1.0.0.zip
|
||||||
|
# #
|
||||||
|
|
||||||
|
PROJECT_NAME:
|
||||||
|
description: '📦 Name of App'
|
||||||
|
required: true
|
||||||
|
default: 'ntfy-desktop'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# environment variables
|
||||||
|
# #
|
||||||
|
|
||||||
|
env:
|
||||||
|
PROJECT_NAME: ${{ github.event.inputs.PROJECT_NAME || 'ntfy-desktop' }}
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
GPG_KEY_BASE64: ${{ secrets.ADMINSERV_GPG_KEY_B64 }}
|
||||||
|
GPG_KEY_PASSPHRASE: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Jobs
|
||||||
|
# #
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# JOB > INITIALIZE
|
||||||
|
# #
|
||||||
|
|
||||||
|
job-initialize:
|
||||||
|
name: >-
|
||||||
|
🔑 GPG › Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 5
|
||||||
|
outputs:
|
||||||
|
package_version: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
packages: write
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Get version from package.json VERSION value
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '👁️🗨️ Get Package Version'
|
||||||
|
id: task_initialize_package_getversion
|
||||||
|
run: |
|
||||||
|
VER=$(cat package.json | jq -r '.version')
|
||||||
|
echo "PACKAGE_VERSION=$VER" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: '👁️🗨️ Get Package Version › Print'
|
||||||
|
id: task_initialize_package_getversion_debug
|
||||||
|
run: |
|
||||||
|
echo "VERSION: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Import Key (No Passphrase)
|
||||||
|
#
|
||||||
|
# requires your GPG private key, converted to base64 binary .gpg (not armored .asc)
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🪪 GPG › Import Signing Key › W/o Passphrase'
|
||||||
|
if: env.GPG_KEY_BASE64 != '' && env.GPG_KEY_PASSPHRASE == ''
|
||||||
|
run: |
|
||||||
|
echo "$GPG_KEY_BASE64" | base64 -di | gpg --import
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Import Key (With Passphrase)
|
||||||
|
#
|
||||||
|
# requires your GPG private key, converted to base64 binary .gpg (not armored .asc)
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🪪 GPG › Import Signing Key › w/ Passphrase'
|
||||||
|
if: env.GPG_KEY_BASE64 != '' && env.GPG_KEY_PASSPHRASE != ''
|
||||||
|
run: |
|
||||||
|
echo "$GPG_KEY_BASE64" | base64 -di > /tmp/signing-key.gpg
|
||||||
|
echo "$GPG_KEY_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg
|
||||||
|
(echo "$GPG_KEY_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Checksum › Stable
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🆔 Checksum › Stable'
|
||||||
|
run: |
|
||||||
|
# windows
|
||||||
|
file_1_example="package.json"
|
||||||
|
file_2_example="package-lock.json"
|
||||||
|
|
||||||
|
|
||||||
|
# get sha1 and sha256 for .json
|
||||||
|
find . -maxdepth 1 \( -name '*.json' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha1sum | gpg --digest-algo sha256 --clearsign > sha1sum.txt.asc
|
||||||
|
find . -maxdepth 1 \( -name '*.json' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha256sum | gpg --digest-algo sha256 --clearsign > sha256sum.txt.asc
|
||||||
|
|
||||||
|
|
||||||
|
# SHA1SUM
|
||||||
|
sha1sum_file_1="$(shasum --algorithm 1 ${file_1_example} | awk '{ print $1 }')"
|
||||||
|
echo "SHA1SUM_FILE_1=${sha1sum_file_1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
sha1sum_file_2="$(shasum --algorithm 1 ${file_2_example} | awk '{ print $1 }')"
|
||||||
|
echo "SHA1SUM_FILE_2=${sha1sum_file_2}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
|
||||||
|
# SHA256SUM
|
||||||
|
sha256sum_file_1="$(shasum --algorithm 256 ${file_1_example} | awk '{ print $1 }')"
|
||||||
|
echo "SHA256SUM_FILE_1=${sha256sum_file_1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
sha256sum_file_2="$(shasum --algorithm 256 ${file_2_example} | awk '{ print $1 }')"
|
||||||
|
echo "SHA256SUM_FILE_2=${sha256sum_file_2}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
|
||||||
|
# no longer needed, replaced by find . command
|
||||||
|
# shasum --algorithm 256 ${file_file_1} > SHA256SUMS.txt
|
||||||
|
echo "FILE_1_EXAMPLE=${file_1_example}" >> $GITHUB_ENV
|
||||||
|
echo "FILE_2_EXAMPLE=${file_2_example}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
|
||||||
|
# generate sha256sum.sig from sha256sum.txt.asc file
|
||||||
|
gpg --batch --yes --quiet --armor --detach-sig --sign --output sha256sum.sig sha256sum.txt.asc
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Verbose › Print Results
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Verbose › Print Results'
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " 🌲 Tree"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
tree -I node_modules
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " 📄 sha256sum.txt.asc"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
cat sha256sum.txt.asc
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " 📄 sha1sum.txt.asc"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
cat sha1sum.txt.asc
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " 📄 sha256sum.sig"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
cat sha256sum.sig
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "Running command gpg --verify sha256sum.sig sha256sum.txt.asc"
|
||||||
|
echo ""
|
||||||
|
gpg --verify sha256sum.sig sha256sum.txt.asc
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " 🔑 List GPG Keys"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
gpg --list-keys --keyid-format=long --fingerprint --with-fingerprint
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# GPG › Checksum › Print
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🆔 Checksum › Print'
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Checksums"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo " ${{ env.FILE_1_EXAMPLE }} ${{ env.SHA256SUM_FILE_1 }}"
|
||||||
|
echo " ${{ env.FILE_2_EXAMPLE }} ${{ env.SHA256SUM_FILE_2 }}"
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
313
.github/workflows/history-clean.yml
vendored
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
# #
|
||||||
|
# @type github workflow
|
||||||
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage cleans all commit history for a repository
|
||||||
|
# edit the 'environment:' to determine which deployment to keep clean
|
||||||
|
# - can be ran manually
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/history-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/history-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# #
|
||||||
|
|
||||||
|
name: '🧹 History › Clean'
|
||||||
|
run-name: '🧹 History › Clean'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# triggers
|
||||||
|
# #
|
||||||
|
|
||||||
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger > Workflow Dispatch
|
||||||
|
# #
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Commit Label
|
||||||
|
#
|
||||||
|
# the label to use when repository is cleaned
|
||||||
|
# #
|
||||||
|
|
||||||
|
COMMIT_LABEL:
|
||||||
|
description: '🏷️ Commit Label'
|
||||||
|
required: true
|
||||||
|
default: 'cleanup'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Branch
|
||||||
|
#
|
||||||
|
# select branch to clean
|
||||||
|
# you must also run the workflow from that branch
|
||||||
|
# #
|
||||||
|
|
||||||
|
BRANCH:
|
||||||
|
description: '🌳 Branch'
|
||||||
|
required: true
|
||||||
|
default: 'main'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# environment variables
|
||||||
|
# #
|
||||||
|
|
||||||
|
env:
|
||||||
|
COMMIT_LABEL: ${{ github.event.inputs.COMMIT_LABEL || 'cleanup' }}
|
||||||
|
BRANCH: ${{ github.event.inputs.BRANCH || 'main' }}
|
||||||
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
|
# #
|
||||||
|
# jobs
|
||||||
|
# #
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
history-clean:
|
||||||
|
name: >-
|
||||||
|
🧹 History › Clean
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 15
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Git Identify
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🪪 Configure Git Identity
|
||||||
|
run: |
|
||||||
|
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
|
git config --local user.name "github-actions[bot]"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Pre-Commit
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
📦 Commit › Pre-commit
|
||||||
|
run: |
|
||||||
|
now=$(date -u '+%m/%d/%Y %H:%M')
|
||||||
|
commit_label="${{ env.COMMIT_LABEL }}" >> $GITHUB_ENV
|
||||||
|
echo -e "$commit_label"
|
||||||
|
commit_message="chore(maint): \\\`️️🧹 $commit_label 🧹\\\` \\\`$now UTC\\\`" >> $GITHUB_ENV
|
||||||
|
echo -e "$commit_message"
|
||||||
|
echo "COMMIT_MESSAGE=$(echo $commit_message)" >> $GITHUB_ENV
|
||||||
|
echo "NOW=$(echo $now)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Pre-Commit › Debug
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
📦 Commit › Pre-commit › Debug
|
||||||
|
run: |
|
||||||
|
echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " Printing Values"
|
||||||
|
echo -e "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo -e " env.COMMIT_LABEL .................... ${{ env.COMMIT_LABEL }}"
|
||||||
|
echo -e " env.COMMIT_MESSAGE .................. ${{ env.COMMIT_MESSAGE }}"
|
||||||
|
echo -e " env.NOW ............................. ${{ env.NOW }}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🧹 Clean Repo History
|
||||||
|
run: |
|
||||||
|
# Create a new orphan branch
|
||||||
|
git checkout --orphan temp-branch
|
||||||
|
|
||||||
|
# Add all files to the new branch
|
||||||
|
git add -A
|
||||||
|
|
||||||
|
# Commit the files to the new branch
|
||||||
|
git commit -m "${{ env.COMMIT_MESSAGE }}"
|
||||||
|
|
||||||
|
# Delete the old main branch
|
||||||
|
git branch -D ${{ env.BRANCH }}
|
||||||
|
|
||||||
|
# Rename the new orphan branch to main
|
||||||
|
git branch -m ${{ env.BRANCH }}
|
||||||
|
|
||||||
|
# Force push the new main branch to the remote repository
|
||||||
|
git push -f origin ${{ env.BRANCH }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › References
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🗑️ Garbage Collection (Aggressive)
|
||||||
|
run: |
|
||||||
|
# Remove remote-tracking references to deleted branches (optional)
|
||||||
|
git fetch origin --prune
|
||||||
|
git repack
|
||||||
|
git prune-packed
|
||||||
|
git reflog expire --expire=now --all
|
||||||
|
git gc --prune=now --aggressive
|
||||||
|
|
||||||
|
# #
|
||||||
|
# History › Clean › Commit
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
📦 Commit › Execute
|
||||||
|
uses: stefanzweifel/git-auto-commit-action@v5
|
||||||
|
with:
|
||||||
|
commit_message: ${{ env.COMMIT_MESSAGE }}
|
||||||
960
.github/workflows/issues-new.yml
vendored
583
.github/workflows/issues-scan.yml
vendored
@@ -1,16 +1,48 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc pull request autoscan
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage pull request auto-scan
|
||||||
# scans all of the files related to a particular pull request
|
# scans all of the files related to a particular pull request
|
||||||
# if the code in the files being submitted contains code that is forbidden,
|
# if the code in the files being submitted contains code that is forbidden,
|
||||||
# a report is generated and posted as a comment in the PR.
|
# a report is generated and posted as a comment in the PR.
|
||||||
# sends notifications to discord using webhooks
|
# sends notifications to discord using webhooks
|
||||||
# @author Aetherinox
|
#
|
||||||
# @url https://github.com/Aetherinox
|
# @notes skips title changes if the author of the PR is renovate[bat]
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/issues-scan.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/issues-scan.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "🎫 Issues › Scan"
|
name: '🎫 PR › Scan'
|
||||||
run-name: "🎫 Issues › Scan"
|
run-name: '🎫 PR › Scan'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
@@ -26,6 +58,11 @@ on:
|
|||||||
# #
|
# #
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
DISCORD_BOT_NAME: 'Europa'
|
||||||
|
DISCORD_BOT_AVATAR: 'https://i.imgur.com/UqwMom1.jpeg'
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
|
||||||
LABEL_CHECK_STATUS_FAILED: AC › Failed
|
LABEL_CHECK_STATUS_FAILED: AC › Failed
|
||||||
LABEL_CHECK_REVIEW_READY: AC › Passed
|
LABEL_CHECK_REVIEW_READY: AC › Passed
|
||||||
LABEL_CHECK_CHANGES_REQ: AC › Changes Required
|
LABEL_CHECK_CHANGES_REQ: AC › Changes Required
|
||||||
@@ -34,12 +71,16 @@ env:
|
|||||||
LABEL_CHECK_SECURITY_ERR: AC › Security Warning
|
LABEL_CHECK_SECURITY_ERR: AC › Security Warning
|
||||||
LABEL_CHECK_STATUS_CHGMADE: AC › Changes Made
|
LABEL_CHECK_STATUS_CHGMADE: AC › Changes Made
|
||||||
LABEL_CHECK_SCAN_SKIPPED: AC › Skipped Scan
|
LABEL_CHECK_SCAN_SKIPPED: AC › Skipped Scan
|
||||||
LABEL_TYPE_PR: Type ◦ Pull Request
|
LABEL_TYPE_PR: Type › Pull Request
|
||||||
LABEL_TYPE_DEPENDENCY: Type ◦ Dependency
|
LABEL_TYPE_DEPENDENCY: Type › Dependency
|
||||||
LABEL_TYPE_GITACTION: Type ◦ Git Action
|
LABEL_TYPE_GITACTION: Type › Git Action
|
||||||
|
LABEL_TYPE_MAINTENANCE: Type › Lock Maintenance
|
||||||
|
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
LABELS_JSON: |
|
LABELS_JSON: |
|
||||||
[
|
[
|
||||||
@@ -51,32 +92,33 @@ env:
|
|||||||
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
||||||
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
||||||
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
||||||
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
{ "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
||||||
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
{ "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
||||||
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
{ "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
||||||
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
{ "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
||||||
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by EuropaServ for a prolonged period of inactivity" },
|
{ "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
||||||
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
{ "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
||||||
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
|
{ "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" },
|
||||||
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
|
{ "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" },
|
||||||
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
{ "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
||||||
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
{ "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
||||||
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
|
{ "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" },
|
||||||
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
{ "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
||||||
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
{ "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
||||||
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
{ "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
||||||
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
{ "name": "Type › Lock Maintenance", "color": "FBCA04", "description": "Sync package-lock.json" },
|
||||||
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
|
{ "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
||||||
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
{ "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" },
|
||||||
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
{ "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
||||||
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
{ "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
||||||
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
{ "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
||||||
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
{ "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
||||||
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
{ "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
||||||
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
{ "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
||||||
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
{ "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
||||||
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
|
{ "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
||||||
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
{ "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" },
|
||||||
|
{ "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
||||||
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
||||||
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
||||||
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
||||||
@@ -110,13 +152,17 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job [ Autoscan ]
|
# Job › PR Scan
|
||||||
|
#
|
||||||
|
# automatically scan a pull request once it is submitted
|
||||||
# #
|
# #
|
||||||
|
|
||||||
pr-autoscan:
|
job-pr-scan:
|
||||||
# runs-on: ubuntu-latest
|
name: >-
|
||||||
runs-on: apollo-x64
|
🎫 Issues › Autoscan
|
||||||
timeout-minutes: 10
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 5
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
actions: read
|
actions: read
|
||||||
@@ -125,27 +171,135 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Set Env Variables
|
# PR › Scan › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# PR › Scan › Job Information
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Timestamp
|
🔄 Load Job
|
||||||
id: task_autocheck_set_timestamp
|
uses: qoomon/actions--context@v4
|
||||||
run: |
|
id: 'context'
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
# #
|
# #
|
||||||
|
# PR › Scan › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# PR Scan › Labels › Verify Existing
|
||||||
|
#
|
||||||
|
# check if repo has all of the needed issue / pr labels; create label if not exists
|
||||||
|
#
|
||||||
# action needed if using 'pull_request' and 'issue_comment'
|
# action needed if using 'pull_request' and 'issue_comment'
|
||||||
# to get the pull request, you would normally use ${{ github.event.number }}
|
# to get the pull request, you would normally use ${{ github.event.number }}
|
||||||
# however this isnt available for 'issue_comment'
|
# however this isnt available for 'issue_comment'
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🏷️ Verify Existing Labels
|
🎫 Labels › Verify Existing
|
||||||
id: task_autocheck_labels_verify
|
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
@@ -160,7 +314,7 @@ jobs:
|
|||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
name: label.name,
|
name: label.name,
|
||||||
description: label.description || '',
|
description: label.description || 'No Description',
|
||||||
color: label.color
|
color: label.color
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -178,13 +332,15 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# set issue number
|
# PR Scan › Assign Pull Request ID to variable
|
||||||
|
#
|
||||||
|
# get id (number) for pr when submitted
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
#️⃣ Issue number › Set
|
#️⃣ Pull-Request ID › Set
|
||||||
|
id: task_prscan_issue_num_set
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
id: task_autocheck_issue_num_set
|
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
script: |
|
script: |
|
||||||
@@ -195,53 +351,58 @@ jobs:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Otherwise return issue number from commit
|
const data = (
|
||||||
return (
|
|
||||||
await github.rest.repos.listPullRequestsAssociatedWithCommit(
|
await github.rest.repos.listPullRequestsAssociatedWithCommit(
|
||||||
{
|
{
|
||||||
commit_sha: context.sha,
|
commit_sha: context.sha,
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
})
|
})
|
||||||
).data[ 0 ].number;
|
).data[0];
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
return data.number;
|
||||||
|
} else {
|
||||||
|
return '32';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result-encoding: string
|
result-encoding: string
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# print issue number
|
# PR Scan › Pull-Request ID › Print
|
||||||
|
#
|
||||||
|
# prints the pr number detected
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
#️⃣ Issue number › Print
|
#️⃣ Pull-Request ID › Print
|
||||||
id: task_autocheck_issue_num_get
|
|
||||||
run: |
|
run: |
|
||||||
echo '${{ steps.task_autocheck_issue_num_set.outputs.result }}'
|
echo '${{ steps.task_prscan_issue_num_set.outputs.result }}'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# checkout
|
# PR Scan › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
☑️ Checkout
|
☑️ Checkout
|
||||||
id: task_autoscan_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
if: |
|
if: |
|
||||||
( github.event_name == 'pull_request_target' ) || ( github.event_name == 'pull_request' ) || ( github.event_name == 'issue_comment' && contains( github.event.comment.html_url, '/pull/' ) && contains( github.event.comment.body, '/rescan' ) )
|
( github.event_name == 'pull_request_target' ) || ( github.event_name == 'pull_request' ) || ( github.event_name == 'issue_comment' && contains( github.event.comment.html_url, '/pull/' ) && contains( github.event.comment.body, '/rescan' ) )
|
||||||
with:
|
with:
|
||||||
|
token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: "refs/pull/${{ steps.task_autocheck_issue_num_set.outputs.result }}/merge"
|
ref: "refs/pull/${{ steps.task_prscan_issue_num_set.outputs.result }}/merge"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# nodejs
|
# PR Scan › Setup NodeJS
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
⚙️ Setup Node
|
⚙️ Setup Node
|
||||||
id: task_autocheck_nodejs
|
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# get list of changed files
|
# PR Scan › Get List of Changed Files
|
||||||
#
|
#
|
||||||
# Effortlessly track all changed files and directories relative to a target branch,
|
# Effortlessly track all changed files and directories relative to a target branch,
|
||||||
# the current branch (preceding commit or the last remote commit), multiple branches,
|
# the current branch (preceding commit or the last remote commit), multiple branches,
|
||||||
@@ -251,63 +412,176 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
📄 Get changed files
|
📄 Get changed files
|
||||||
id: task_autocheck_changed_files_get
|
id: task_prscan_changed_files_get
|
||||||
uses: tj-actions/changed-files@v45
|
uses: tj-actions/changed-files@v46
|
||||||
with:
|
with:
|
||||||
separator: ","
|
separator: ","
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# list of changed files
|
# PR Scan › List All Changed Files
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
📄 List all added files
|
📄 List all added files
|
||||||
id: task_autocheck_added_files_get
|
id: task_prscan_added_files_get
|
||||||
run: |
|
run: |
|
||||||
for file in ${CHANGED_FILES}; do
|
for file in ${CHANGED_FILES}; do
|
||||||
echo "$file was changed"
|
echo "$file was changed"
|
||||||
done
|
done
|
||||||
env:
|
env:
|
||||||
ADDED_FILES: ${{ steps.task_autocheck_changed_files_get.outputs.added_files }}
|
ADDED_FILES: ${{ steps.task_prscan_changed_files_get.outputs.added_files }}
|
||||||
MODIFIED_FILES: ${{ steps.task_autocheck_changed_files_get.outputs.modified_files }}
|
MODIFIED_FILES: ${{ steps.task_prscan_changed_files_get.outputs.modified_files }}
|
||||||
CHANGED_FILES: ${{ steps.task_autocheck_changed_files_get.outputs.all_changed_files }}
|
CHANGED_FILES: ${{ steps.task_prscan_changed_files_get.outputs.all_changed_files }}
|
||||||
COUNT_ADDED: ${{ steps.task_autocheck_changed_files_get.outputs.added_files_count }}
|
COUNT_ADDED: ${{ steps.task_prscan_changed_files_get.outputs.added_files_count }}
|
||||||
COUNT_MODIFIED: ${{ steps.task_autocheck_changed_files_get.outputs.modified_files_count }}
|
COUNT_MODIFIED: ${{ steps.task_prscan_changed_files_get.outputs.modified_files_count }}
|
||||||
COUNT_DELETED: ${{ steps.task_autocheck_changed_files_get.outputs.deleted_files_count }}
|
COUNT_DELETED: ${{ steps.task_prscan_changed_files_get.outputs.deleted_files_count }}
|
||||||
COUNT_RENAMED: ${{ steps.task_autocheck_changed_files_get.outputs.renamed_files_count }}
|
COUNT_RENAMED: ${{ steps.task_prscan_changed_files_get.outputs.renamed_files_count }}
|
||||||
COUNT_COPIED: ${{ steps.task_autocheck_changed_files_get.outputs.copied_files_count }}
|
COUNT_COPIED: ${{ steps.task_prscan_changed_files_get.outputs.copied_files_count }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# List directories
|
# PR Scan › List Directories / File Structure
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
📂 List Directories
|
📂 List Directories
|
||||||
id: task_autocheck_dirs_list
|
|
||||||
run: |
|
run: |
|
||||||
ls
|
ls
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Run autocheck
|
# PR Scan › Autocheck
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
☑️ Run Autocheck
|
☑️ Run Autocheck
|
||||||
id: task_autocheck_run
|
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
script: |
|
script: |
|
||||||
|
console.log('Running Autoscan')
|
||||||
|
console.log(JSON.stringify(context, null, 4));
|
||||||
|
console.log(JSON.stringify(github, null, 4));
|
||||||
|
let ct = context;
|
||||||
|
|
||||||
|
/* #
|
||||||
|
# Example PR used for local act testing
|
||||||
|
# Uncomment to use in local env
|
||||||
|
#
|
||||||
|
# can be tested using act:
|
||||||
|
# - https://github.com/nektos/act
|
||||||
|
# command:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/issues-scan.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/issues-scan.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# */
|
||||||
|
|
||||||
|
/*
|
||||||
|
ct = {
|
||||||
|
"issue": {
|
||||||
|
"number": 32
|
||||||
|
},
|
||||||
|
"repo": {
|
||||||
|
"owner": "Aetherinox",
|
||||||
|
"repo": "TheRepoName"
|
||||||
|
},
|
||||||
|
"payload": {
|
||||||
|
"action": "synchronize",
|
||||||
|
"after": "f087c5bea8800f41018ef328463531ea247547ef",
|
||||||
|
"before": "a8bdd791b80b2fbb78169234690ccb61b9d014f1",
|
||||||
|
"number": 32,
|
||||||
|
"organization": {
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/200161462?v=4",
|
||||||
|
"events_url": "https://api.github.com/orgs/Aetherinox/events",
|
||||||
|
"hooks_url": "https://api.github.com/orgs/Aetherinox/hooks",
|
||||||
|
"issues_url": "https://api.github.com/orgs/Aetherinox/issues",
|
||||||
|
"login": "Aetherinox",
|
||||||
|
"members_url": "https://api.github.com/orgs/Aetherinox/members{/member}",
|
||||||
|
"public_members_url": "https://api.github.com/orgs/Aetherinox/public_members{/member}",
|
||||||
|
"repos_url": "https://api.github.com/orgs/Aetherinox/repos",
|
||||||
|
"url": "https://api.github.com/orgs/Aetherinox"
|
||||||
|
},
|
||||||
|
"pull_request": {
|
||||||
|
"created_at": "2025-03-17T23:32:22Z",
|
||||||
|
"updated_at": "2025-03-17T23:32:22Z",
|
||||||
|
"url": "https://api.github.com/repos/Aetherinox/TheRepoName",
|
||||||
|
"title": "Test PR Workflow",
|
||||||
|
"head": {
|
||||||
|
"ref": "main"
|
||||||
|
},
|
||||||
|
"base": {
|
||||||
|
"ref": "main"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"login": "Aetherinox"
|
||||||
|
},
|
||||||
|
"labels": [
|
||||||
|
{
|
||||||
|
"color": "146b4a",
|
||||||
|
"default": false,
|
||||||
|
"description": "Ready to be reviewed",
|
||||||
|
"id": 7821944832,
|
||||||
|
"name": "AC › Passed",
|
||||||
|
"node_id": "LA_kwDONW-GkM8AAAAB0jloAA",
|
||||||
|
"url": "https://api.github.com/repos/Aetherinox/TheRepoName/labels/AC%20%E2%80%BA%20Passed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"color": "8F1784",
|
||||||
|
"default": false,
|
||||||
|
"description": "Normal pull request",
|
||||||
|
"id": 7821944963,
|
||||||
|
"name": "Type › Pull Request",
|
||||||
|
"node_id": "LA_kwDONW-GkM8AAAAB0jlogw",
|
||||||
|
"url": "https://api.github.com/repos/Aetherinox/TheRepoName/labels/Type%20%E2%97%A6%20Pull%20Request"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"eventName": "pull_request_target",
|
||||||
|
"sha": "c938f7a21247f69b29cf352d0c6890a63f260d47",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"workflow": "🎫 Issues › Scan",
|
||||||
|
"action": "task_prscan_run",
|
||||||
|
"actor": "renovate[bot]",
|
||||||
|
"job": "job-pr-autoscan",
|
||||||
|
"runNumber": 45,
|
||||||
|
"runId": 13911964505,
|
||||||
|
"apiUrl": "https://api.github.com",
|
||||||
|
"serverUrl": "https://github.com",
|
||||||
|
"graphqlUrl": "https://api.github.com/graphql"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #
|
||||||
|
# if local env ct isn't used, set ct to context for production
|
||||||
|
# */
|
||||||
|
|
||||||
|
if (!ct) {
|
||||||
|
ct = context;
|
||||||
|
}
|
||||||
|
|
||||||
const fs = require( 'fs' );
|
const fs = require( 'fs' );
|
||||||
const escape_html = ( unsafe ) => unsafe.replace( /&/g, '&' ).replace( /</g, '<' ).replace( />/g, '>' ).replace( /"/g, '"' ).replace( /'/g, ''' );
|
const escape_html = ( unsafe ) => unsafe.replace( /&/g, '&' ).replace( /</g, '<' ).replace( />/g, '>' ).replace( /"/g, '"' ).replace( /'/g, ''' );
|
||||||
const labels = [];
|
const labels = [];
|
||||||
|
|
||||||
const files_List = `${{ steps.task_autocheck_changed_files_get.outputs.all_changed_files }}` || ''
|
/* #
|
||||||
|
# Get existing labels and add to list
|
||||||
|
# */
|
||||||
|
|
||||||
|
const labelsExisting = await github.rest.issues.listLabelsOnIssue({
|
||||||
|
issue_number: ct.issue.number,
|
||||||
|
owner: ct.repo.owner,
|
||||||
|
repo: ct.repo.repo
|
||||||
|
})
|
||||||
|
|
||||||
|
labelsExisting.data.forEach(({ name }) => {
|
||||||
|
labels.push(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
const files_List = `${{ steps.task_prscan_changed_files_get.outputs.all_changed_files }}` || ''
|
||||||
const files_Array = files_List.split(',')
|
const files_Array = files_List.split(',')
|
||||||
const branch_ref = `${ context.payload.pull_request.head.ref }`
|
const branch_ref = `${ ct.payload.pull_request.head.ref }`
|
||||||
|
|
||||||
let message = [ "\n<br />\n" ]
|
let message = [ "\n<br />\n" ]
|
||||||
message.push ( "## Automatic Self-Check - #" + context.issue.number + "\n" );
|
message.push ( "## Automatic Self-Check - #" + ct.issue.number + "\n" );
|
||||||
message.push ( `The details of our automated scan for your pull request are listed below. If our scan detected errors, they must be corrected before this pull request will be advanced to the review stage:\n` );
|
message.push ( `The details of our automated scan for your pull request are listed below. If our scan detected errors, they must be corrected before this pull request will be advanced to the review stage:\n` );
|
||||||
message.push ( "\n<br />\n\n---\n\n<br />\n\n" );
|
message.push ( "\n<br />\n\n---\n\n<br />\n\n" );
|
||||||
message.push ( "### About\nThis pull request includes the following information:" );
|
message.push ( "### About\nThis pull request includes the following information:" );
|
||||||
@@ -315,7 +589,7 @@ jobs:
|
|||||||
let bHasError = false;
|
let bHasError = false;
|
||||||
let bHasWarning = false;
|
let bHasWarning = false;
|
||||||
|
|
||||||
let date = new Date( `${ context.payload.pull_request.created_at }` );
|
let date = new Date( `${ ct.payload.pull_request.created_at }` );
|
||||||
date.toISOString( )
|
date.toISOString( )
|
||||||
|
|
||||||
const actor = '${{ github.actor }}';
|
const actor = '${{ github.actor }}';
|
||||||
@@ -341,25 +615,25 @@ jobs:
|
|||||||
|
|
||||||
let date_created = dateTimeformat( date ) + " UTC";
|
let date_created = dateTimeformat( date ) + " UTC";
|
||||||
|
|
||||||
/*
|
/* #
|
||||||
context.payload.pull_request.base.repo.owner.login
|
# ct.payload.pull_request.base.repo.owner.login
|
||||||
*/
|
# */
|
||||||
|
|
||||||
let md_table =
|
let md_table =
|
||||||
`
|
`
|
||||||
| Category | Value |
|
| Category | Value |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| Title | [ ` + context.payload.pull_request.title + ` ](https://github.com/` + context.repo.owner + `/` + context.repo.repo + `/pull/` + context.payload.pull_request.number + `) |
|
| Title | [ ` + ct.payload.pull_request.title + ` ](https://github.com/` + ct.repo.owner + `/` + ct.repo.repo + `/pull/` + ct.payload.pull_request.number + `) |
|
||||||
| Created | [ ` + date_created + ` ](https://worldtimebuddy.com) |
|
| Created | [ ` + date_created + ` ](https://worldtimebuddy.com) |
|
||||||
| ID | ` + context.payload.pull_request.html_url + ` |
|
| ID | ` + ct.payload.pull_request.html_url + ` |
|
||||||
| Author | [ ` + context.payload.pull_request.user.login + ` ](https://github.com/` + context.repo.owner + `/) |
|
| Author | [ ` + ct.payload.pull_request.user.login + ` ](https://github.com/` + ct.repo.owner + `/) |
|
||||||
| Repo | [ ` + context.repo.repo + ` ](https://github.com/` + context.repo.owner + `/` + context.repo.repo + `) |
|
| Repo | [ ` + ct.repo.repo + ` ](https://github.com/` + ct.repo.owner + `/` + ct.repo.repo + `) |
|
||||||
| Branch | [ ` + context.payload.pull_request.head.ref + `](https://github.com/` + context.repo.owner + `/` + context.repo.repo + `/tree/` + context.payload.pull_request.head.ref + `) ⇁ [ ` + context.payload.pull_request.base.ref + `](https://github.com/` + context.repo.owner + `/` + context.repo.repo + `/tree/` + context.payload.pull_request.base.ref + `) |
|
| Branch | [ ` + ct.payload.pull_request.head.ref + `](https://github.com/` + ct.repo.owner + `/` + ct.repo.repo + `/tree/` + ct.payload.pull_request.head.ref + `) ⇁ [ ` + ct.payload.pull_request.base.ref + `](https://github.com/` + ct.repo.owner + `/` + ct.repo.repo + `/tree/` + ct.payload.pull_request.base.ref + `) |
|
||||||
| Added Files | ${{ steps.task_autocheck_changed_files_get.outputs.added_files_count }} |
|
| Added Files | ${{ steps.task_prscan_changed_files_get.outputs.added_files_count }} |
|
||||||
| Modified Files | ${{ steps.task_autocheck_changed_files_get.outputs.all_modified_files_count }} |
|
| Modified Files | ${{ steps.task_prscan_changed_files_get.outputs.all_modified_files_count }} |
|
||||||
| Renamed Files | ${{ steps.task_autocheck_changed_files_get.outputs.renamed_files_count }} |
|
| Renamed Files | ${{ steps.task_prscan_changed_files_get.outputs.renamed_files_count }} |
|
||||||
| Copied Files | ${{ steps.task_autocheck_changed_files_get.outputs.deleted_files_count }} |
|
| Copied Files | ${{ steps.task_prscan_changed_files_get.outputs.deleted_files_count }} |
|
||||||
| Deleted Files | ${{ steps.task_autocheck_changed_files_get.outputs.deleted_files_count }} |
|
| Deleted Files | ${{ steps.task_prscan_changed_files_get.outputs.deleted_files_count }} |
|
||||||
`;
|
`;
|
||||||
|
|
||||||
message.push ( md_table );
|
message.push ( md_table );
|
||||||
@@ -389,12 +663,33 @@ jobs:
|
|||||||
|
|
||||||
const type_dependency =
|
const type_dependency =
|
||||||
[
|
[
|
||||||
"dependabot/npm_and_yarn"
|
"dependabot/npm_and_yarn",
|
||||||
|
"renovate/github_actions",
|
||||||
|
"renovate/testing-library",
|
||||||
|
"renovate/electron",
|
||||||
|
"renovate/aetherinox/noxenv",
|
||||||
|
"renovate/playwright",
|
||||||
|
"renovate/types",
|
||||||
|
"renovate/@types",
|
||||||
|
"renovate/eslint",
|
||||||
|
"renovate/stylistic",
|
||||||
|
"renovate/jimp",
|
||||||
|
"renovate/custom-electron-prompt",
|
||||||
|
"renovate/moment",
|
||||||
|
"renovate/semver",
|
||||||
|
"renovate/toasted",
|
||||||
|
"renovate/uuid"
|
||||||
];
|
];
|
||||||
|
|
||||||
const type_gitaction =
|
const type_gitaction =
|
||||||
[
|
[
|
||||||
"dependabot/github_actions"
|
"dependabot/github_actions",
|
||||||
|
"renovate/github_actions"
|
||||||
|
];
|
||||||
|
|
||||||
|
const type_maint =
|
||||||
|
[
|
||||||
|
"renovate/lock-file-maintenance"
|
||||||
];
|
];
|
||||||
|
|
||||||
const files_skipList =
|
const files_skipList =
|
||||||
@@ -715,7 +1010,7 @@ jobs:
|
|||||||
if ( bHasError == true )
|
if ( bHasError == true )
|
||||||
{
|
{
|
||||||
labels.push( "${{ env.LABEL_CHECK_STATUS_FAILED }}" );
|
labels.push( "${{ env.LABEL_CHECK_STATUS_FAILED }}" );
|
||||||
core.setFailed( "Pull Request Failed Autocheck: " + context.issue.number + ": " + context.payload.pull_request.title + "." );
|
core.setFailed( "Pull Request Failed Autocheck: " + ct.issue.number + ": " + ct.payload.pull_request.title + "." );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -729,21 +1024,21 @@ jobs:
|
|||||||
change pr title
|
change pr title
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const pr_title = `${ context.payload.pull_request.title }`;
|
const pr_title = `${ ct.payload.pull_request.title }`;
|
||||||
const pr_title_append = `PR ${ context.issue.number }:`;
|
const pr_title_append = `PR ${ ct.issue.number }:`;
|
||||||
|
|
||||||
if ( !pr_title.startsWith( pr_title_append ) )
|
if ( !pr_title.startsWith( pr_title_append ) && actor != "${{ env.BOT_NAME_RENOVATE }}" )
|
||||||
{
|
{
|
||||||
await github.rest.pulls.update(
|
await github.rest.pulls.update(
|
||||||
{
|
{
|
||||||
owner: context.repo.owner,
|
owner: ct.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: ct.repo.repo,
|
||||||
pull_number: context.issue.number,
|
pull_number: ct.issue.number,
|
||||||
title: `${ pr_title_append } ${ context.payload.pull_request.title }`
|
title: `${ pr_title_append } ${ ct.payload.pull_request.title }`
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !context.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_CHANGES_REQ }}" ).length > 0 )
|
if ( !ct.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_CHANGES_REQ }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_REVIEW_READY }}" );
|
labels.push( "${{ env.LABEL_CHECK_REVIEW_READY }}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,25 +1048,28 @@ jobs:
|
|||||||
|
|
||||||
const bGitaction = type_gitaction.some( s => s.includes( branch_ref ) || branch_ref.includes( s ) );
|
const bGitaction = type_gitaction.some( s => s.includes( branch_ref ) || branch_ref.includes( s ) );
|
||||||
const bDependency = type_dependency.some( s => s.includes( branch_ref ) || branch_ref.includes( s ) );
|
const bDependency = type_dependency.some( s => s.includes( branch_ref ) || branch_ref.includes( s ) );
|
||||||
|
const bMaintenance = type_maint.some( s => s.includes( branch_ref ) || branch_ref.includes( s ) );
|
||||||
|
|
||||||
if ( actor == "${{ env.BOT_NAME_DEPENDABOT }}" && bDependency )
|
if ( actor == "${{ env.BOT_NAME_DEPENDABOT }}" && bDependency || actor == "${{ env.BOT_NAME_RENOVATE }}" && bDependency )
|
||||||
labels.push( "${{ env.LABEL_TYPE_DEPENDENCY }}" );
|
labels.push( "${{ env.LABEL_TYPE_DEPENDENCY }}" );
|
||||||
else if ( actor == "${{ env.BOT_NAME_DEPENDABOT }}" && bGitaction )
|
else if ( actor == "${{ env.BOT_NAME_DEPENDABOT }}" && bGitaction || actor == "${{ env.BOT_NAME_RENOVATE }}" && bGitaction )
|
||||||
labels.push( "${{ env.LABEL_TYPE_GITACTION }}" );
|
labels.push( "${{ env.LABEL_TYPE_GITACTION }}" );
|
||||||
|
else if ( actor == "${{ env.BOT_NAME_DEPENDABOT }}" && bMaintenance || actor == "${{ env.BOT_NAME_RENOVATE }}" && bMaintenance )
|
||||||
|
labels.push( "${{ env.LABEL_TYPE_MAINTENANCE }}" );
|
||||||
|
|
||||||
if ( context.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_CHANGES_REQ }}" ).length > 0 )
|
if ( ct.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_CHANGES_REQ }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_CHANGES_REQ }}" );
|
labels.push( "${{ env.LABEL_CHECK_CHANGES_REQ }}" );
|
||||||
|
|
||||||
if (context.payload.pull_request.labels.filter(label => label.name === "${{ env.LABEL_CHECK_REBASE_REQ }}" ).length > 0 )
|
if (ct.payload.pull_request.labels.filter(label => label.name === "${{ env.LABEL_CHECK_REBASE_REQ }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_REBASE_REQ }}" );
|
labels.push( "${{ env.LABEL_CHECK_REBASE_REQ }}" );
|
||||||
|
|
||||||
if ( context.payload.pull_request.labels.filter(label => label.name === "${{ env.LABEL_CHECK_SECURITY_ERR }}" ).length > 0 )
|
if ( ct.payload.pull_request.labels.filter(label => label.name === "${{ env.LABEL_CHECK_SECURITY_ERR }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_SECURITY_ERR }}" );
|
labels.push( "${{ env.LABEL_CHECK_SECURITY_ERR }}" );
|
||||||
|
|
||||||
if (context.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_STATUS_CHGMADE }}" ).length > 0 )
|
if (ct.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_STATUS_CHGMADE }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_STATUS_CHGMADE }}" );
|
labels.push( "${{ env.LABEL_CHECK_STATUS_CHGMADE }}" );
|
||||||
|
|
||||||
if ( context.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_SCAN_SKIPPED }}" ).length > 0 )
|
if ( ct.payload.pull_request.labels.filter( label => label.name === "${{ env.LABEL_CHECK_SCAN_SKIPPED }}" ).length > 0 )
|
||||||
labels.push( "${{ env.LABEL_CHECK_SCAN_SKIPPED }}" );
|
labels.push( "${{ env.LABEL_CHECK_SCAN_SKIPPED }}" );
|
||||||
|
|
||||||
labels.push( "${{ env.LABEL_TYPE_PR }}" );
|
labels.push( "${{ env.LABEL_TYPE_PR }}" );
|
||||||
@@ -782,9 +1080,9 @@ jobs:
|
|||||||
|
|
||||||
await github.rest.issues.setLabels(
|
await github.rest.issues.setLabels(
|
||||||
{
|
{
|
||||||
issue_number: context.issue.number,
|
issue_number: ct.issue.number,
|
||||||
owner: context.repo.owner,
|
owner: ct.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: ct.repo.repo,
|
||||||
labels,
|
labels,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -794,9 +1092,9 @@ jobs:
|
|||||||
|
|
||||||
await github.rest.issues.createComment(
|
await github.rest.issues.createComment(
|
||||||
{
|
{
|
||||||
issue_number: context.issue.number,
|
issue_number: ct.issue.number,
|
||||||
owner: context.repo.owner,
|
owner: ct.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: ct.repo.repo,
|
||||||
body: message.join('\n'),
|
body: message.join('\n'),
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -806,7 +1104,6 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Weekly Commit List
|
🕛 Get Weekly Commit List
|
||||||
id: task_autocheck_set_weekly_commit_list
|
|
||||||
run: |
|
run: |
|
||||||
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
@@ -818,16 +1115,15 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Success)
|
🔔 Send Discord Webhook Message (Success)
|
||||||
id: task_autocheck_notify_discord_success
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: success()
|
if: success()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_960_720.png'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 🎫 Issues › Scan ${{ job.status == 'success' && '✅' || '❌' }}
|
## 🎫 Issues › Scan ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -850,11 +1146,11 @@ jobs:
|
|||||||
- Status: `${{ github.event.pull_request.state }}`
|
- Status: `${{ github.event.pull_request.state }}`
|
||||||
|
|
||||||
### Scan Results
|
### Scan Results
|
||||||
- Added Files: ${{ steps.task_autocheck_changed_files_get.outputs.added_files_count }}
|
- Added Files: ${{ steps.task_prscan_added_files_get.outputs.added_files_count }}
|
||||||
- Modified Files: ${{ steps.task_autocheck_changed_files_get.outputs.all_modified_files_count }}
|
- Modified Files: ${{ steps.task_prscan_added_files_get.outputs.all_modified_files_count }}
|
||||||
- Renamed Files: ${{ steps.task_autocheck_changed_files_get.outputs.renamed_files_count }}
|
- Renamed Files: ${{ steps.task_prscan_added_files_get.outputs.renamed_files_count }}
|
||||||
- Copied Files: ${{ steps.task_autocheck_changed_files_get.outputs.copied_files_count }}
|
- Copied Files: ${{ steps.task_prscan_added_files_get.outputs.copied_files_count }}
|
||||||
- Deleted Files: ${{ steps.task_autocheck_changed_files_get.outputs.deleted_files_count }}
|
- Deleted Files: ${{ steps.task_prscan_added_files_get.outputs.deleted_files_count }}
|
||||||
|
|
||||||
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
||||||
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
||||||
@@ -869,16 +1165,15 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Failure)
|
🔔 Send Discord Webhook Message (Failure)
|
||||||
id: task_autocheck_notify_discord_failure
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_960_720.png'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 🎫 Issues › Scan ${{ job.status == 'success' && '✅' || '❌' }}
|
## 🎫 Issues › Scan ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -901,11 +1196,11 @@ jobs:
|
|||||||
- Status: `${{ github.event.pull_request.state }}`
|
- Status: `${{ github.event.pull_request.state }}`
|
||||||
|
|
||||||
### Scan Results
|
### Scan Results
|
||||||
- Added Files: ${{ steps.task_autocheck_changed_files_get.outputs.added_files_count }}
|
- Added Files: ${{ steps.task_prscan_added_files_get.outputs.added_files_count }}
|
||||||
- Modified Files: ${{ steps.task_autocheck_changed_files_get.outputs.all_modified_files_count }}
|
- Modified Files: ${{ steps.task_prscan_added_files_get.outputs.all_modified_files_count }}
|
||||||
- Renamed Files: ${{ steps.task_autocheck_changed_files_get.outputs.renamed_files_count }}
|
- Renamed Files: ${{ steps.task_prscan_added_files_get.outputs.renamed_files_count }}
|
||||||
- Copied Files: ${{ steps.task_autocheck_changed_files_get.outputs.copied_files_count }}
|
- Copied Files: ${{ steps.task_prscan_added_files_get.outputs.copied_files_count }}
|
||||||
- Deleted Files: ${{ steps.task_autocheck_changed_files_get.outputs.deleted_files_count }}
|
- Deleted Files: ${{ steps.task_prscan_added_files_get.outputs.deleted_files_count }}
|
||||||
|
|
||||||
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
||||||
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
||||||
|
|||||||
648
.github/workflows/issues-stale.yml
vendored
@@ -1,17 +1,15 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc creates repository labels if they are not yet installed
|
|
||||||
# issues marked as stale after 30 days, given tag Status 𐄂 Stale
|
|
||||||
# inactive issues closed after 180 days, given tag Status 𐄂 Locked
|
|
||||||
# inactive pr closed after 365 days, given tag Status 𐄂 Locked
|
|
||||||
# issues marked stale after 30 days, given tag Status 𐄂 Stale
|
|
||||||
# issues marked closed 7 days after being marked stale, given tag Status 𐄂 Autoclosed
|
|
||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage creates repository labels if they are not yet installed
|
||||||
|
# issues marked as stale after 30 days, given tag Status › Stale
|
||||||
|
# inactive issues closed after 180 days, given tag Status › Locked
|
||||||
|
# inactive pr closed after 365 days, given tag Status › Locked
|
||||||
|
# issues marked stale after 30 days, given tag Status › Stale
|
||||||
|
# issues marked closed 7 days after being marked stale, given tag Status › Autoclosed
|
||||||
#
|
#
|
||||||
# This Github action must be activated manually. This workflow script will do the
|
# @notes This Github action must be activated manually. This workflow script will do the following:
|
||||||
# following:
|
|
||||||
#
|
|
||||||
# - Scan issues / pull requests and make sure they have properly assigned labels:
|
# - Scan issues / pull requests and make sure they have properly assigned labels:
|
||||||
# - `Bug`
|
# - `Bug`
|
||||||
# - `Feature`
|
# - `Feature`
|
||||||
@@ -22,10 +20,40 @@
|
|||||||
# if they haven't had any replies in 30 days.
|
# if they haven't had any replies in 30 days.
|
||||||
#
|
#
|
||||||
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
|
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/issues-stale.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/issues-stale.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "🎫 Issues › Stale"
|
name: '🎫 Issues › Stale'
|
||||||
run-name: "🎫 Issues › Stale"
|
run-name: '🎫 Issues › Stale'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
@@ -33,36 +61,47 @@ run-name: "🎫 Issues › Stale"
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
schedule:
|
# schedule:
|
||||||
- cron: "0 0 * * *"
|
# - cron: "0 0 * * *"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# environment variables
|
# environment variables
|
||||||
# #
|
# #
|
||||||
|
|
||||||
env:
|
env:
|
||||||
PREFIX_BUG: "Bug"
|
PREFIX_BUG: "🐛 Bug"
|
||||||
PREFIX_DEPENDENCY: "Dependency"
|
PREFIX_DEPENDENCY: "Dependency"
|
||||||
PREFIX_DOCS: "Docs"
|
PREFIX_DOCS: "Docs"
|
||||||
PREFIX_FEATURE: "Feature"
|
PREFIX_FEATURE: "💡 Feature"
|
||||||
PREFIX_GIT: "Git Action"
|
PREFIX_GIT: "Git Action"
|
||||||
PREFIX_PR: "PR"
|
PREFIX_PR: "PR"
|
||||||
PREFIX_ROADMAP: "Roadmap"
|
PREFIX_ROADMAP: "🗺️ Roadmap"
|
||||||
PREFIX_INTERNAL: "Internal"
|
PREFIX_INTERNAL: "Internal"
|
||||||
PREFIX_URGENT: "Urgent"
|
PREFIX_URGENT: "⚠ Urgent"
|
||||||
|
|
||||||
LABEL_BUG: "Type ◦ Bug"
|
LABEL_BUG: "Type › Bug"
|
||||||
LABEL_DEPENDENCY: "Type ◦ Dependency"
|
LABEL_DEPENDENCY: "Type › Dependency"
|
||||||
LABEL_DOCS: "Type ◦ Docs"
|
LABEL_DOCS: "Type › Docs"
|
||||||
LABEL_FEATURE: "Type ◦ Feature"
|
LABEL_FEATURE: "Type › Feature"
|
||||||
LABEL_GIT: "Type ◦ Git Action"
|
LABEL_GIT: "Type › Git Action"
|
||||||
LABEL_PR: "Type ◦ Pull Request"
|
LABEL_PR: "Type › Pull Request"
|
||||||
LABEL_ROADMAP: "Type ◦ Roadmap"
|
LABEL_ROADMAP: "Type › Roadmap"
|
||||||
LABEL_INTERNAL: "Type ◦ Internal"
|
LABEL_INTERNAL: "Type › Internal"
|
||||||
|
LABEL_LOCKED: "Status › Locked"
|
||||||
|
LABEL_STALE: "Status › Stale"
|
||||||
|
LABEL_AUTOCLOSE: "Status › Autoclosed"
|
||||||
|
LABEL_ACCEPTED: "Status › Accepted"
|
||||||
|
LABEL_REVIEW: "Status › Review"
|
||||||
|
LABEL_PENDING: "Status › Pending"
|
||||||
|
LABEL_AC_REVIEW: "AC › Review Required"
|
||||||
LABEL_URGENT: "⚠ Urgent"
|
LABEL_URGENT: "⚠ Urgent"
|
||||||
|
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
LABELS_JSON: |
|
LABELS_JSON: |
|
||||||
[
|
[
|
||||||
{ "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
|
{ "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
|
||||||
@@ -73,32 +112,33 @@ env:
|
|||||||
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
||||||
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
||||||
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
||||||
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
{ "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
||||||
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
{ "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
||||||
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
{ "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
||||||
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
{ "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
||||||
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
{ "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
||||||
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
{ "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
||||||
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
|
{ "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" },
|
||||||
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
|
{ "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" },
|
||||||
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
{ "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
||||||
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
{ "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
||||||
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
|
{ "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" },
|
||||||
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
{ "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
||||||
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
{ "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
||||||
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
{ "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
||||||
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
{ "name": "Type › Lock Maintenance", "color": "FBCA04", "description": "Sync package-lock.json" },
|
||||||
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
|
{ "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
||||||
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
{ "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" },
|
||||||
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
{ "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
||||||
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
{ "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
||||||
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
{ "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
||||||
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
{ "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
||||||
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
{ "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
||||||
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
{ "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
||||||
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
{ "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
||||||
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
|
{ "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
||||||
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
{ "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" },
|
||||||
|
{ "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
||||||
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
||||||
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
||||||
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
||||||
@@ -141,42 +181,144 @@ jobs:
|
|||||||
job-labels-create:
|
job-labels-create:
|
||||||
name: >-
|
name: >-
|
||||||
🎫 Labels › Verify Existing
|
🎫 Labels › Verify Existing
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 4
|
timeout-minutes: 5
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Create Labels ] Start
|
# Labels › Create › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: '☑️ Checkout'
|
||||||
✅ Start
|
|
||||||
id: task_label_create_start
|
|
||||||
run: |
|
|
||||||
echo "Assigning labels and assignees"
|
|
||||||
|
|
||||||
# #
|
|
||||||
# [ Create Labels ] Checkout
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
☑️ Checkout
|
|
||||||
id: task_label_create_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Create Labels ] Verify Existing Labels
|
# Labels › Create › Job Information
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🏷️ Verify Existing Labels
|
🔄 Load Job
|
||||||
id: task_label_create_verify
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Create › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Issues (Stale) › Labels › Create › Verify Existing
|
||||||
|
#
|
||||||
|
# check if repo has all of the needed issue / pr labels; create label if not exists
|
||||||
|
#
|
||||||
|
# action needed if using 'pull_request' and 'issue_comment'
|
||||||
|
# to get the pull request, you would normally use ${{ github.event.number }}
|
||||||
|
# however this isnt available for 'issue_comment'
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🎫 Labels › Verify Existing
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
script: |
|
script: |
|
||||||
const labels = JSON.parse( process.env.LABELS_JSON );
|
const labels = JSON.parse( process.env.LABELS_JSON );
|
||||||
for ( const label of labels )
|
for ( const label of labels )
|
||||||
@@ -188,7 +330,7 @@ jobs:
|
|||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
name: label.name,
|
name: label.name,
|
||||||
description: label.description || '',
|
description: label.description || 'No Description',
|
||||||
color: label.color
|
color: label.color
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -206,7 +348,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job [ Check Labels ]
|
# Issues (Stale) › Labels › Assign Missing
|
||||||
#
|
#
|
||||||
# Runs through all submissions to check for ones that have not been properly labeled
|
# Runs through all submissions to check for ones that have not been properly labeled
|
||||||
# - Bug
|
# - Bug
|
||||||
@@ -218,32 +360,141 @@ jobs:
|
|||||||
job-issues-nolabel:
|
job-issues-nolabel:
|
||||||
name: >-
|
name: >-
|
||||||
🎫 Labels › Assign Missing
|
🎫 Labels › Assign Missing
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 4
|
timeout-minutes: 4
|
||||||
needs: job-labels-create
|
needs: job-labels-create
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Check Labels ] Checkout
|
# Labels › Assign › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "☑️ Prepare"
|
- name: '☑️ Checkout'
|
||||||
id: task_issues_nolabel_prepare
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Check Labels ] Check
|
# Labels › Assign › Job Information
|
||||||
# Check if repo has labels currently added to issues
|
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: 🏷️ Checking Issues
|
- name: >-
|
||||||
id: task_issues_nolabel_run
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Assign › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Assign › Check
|
||||||
|
#
|
||||||
|
# Check if repo has labels to use
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🎫 Labels › Check
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
script: |
|
script: |
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -263,7 +514,6 @@ jobs:
|
|||||||
hours = hours % 12;
|
hours = hours % 12;
|
||||||
hours = hours ? hours : 12;
|
hours = hours ? hours : 12;
|
||||||
minutes = minutes.toString( ).padStart( 2, '0' );
|
minutes = minutes.toString( ).padStart( 2, '0' );
|
||||||
|
|
||||||
let mergeTime = month + '.' + day + '.' + year + ' ' + hours + ':' + minutes + ' ' + x;
|
let mergeTime = month + '.' + day + '.' + year + ' ' + hours + ':' + minutes + ' ' + x;
|
||||||
|
|
||||||
return mergeTime;
|
return mergeTime;
|
||||||
@@ -289,7 +539,7 @@ jobs:
|
|||||||
let date_UpdateHuman = dateTimeformat( date_UpdateDate ) + " UTC"; // 03.26.2024 4:40 PM UTC
|
let date_UpdateHuman = dateTimeformat( date_UpdateDate ) + " UTC"; // 03.26.2024 4:40 PM UTC
|
||||||
const time_UpdateMs = new Date( issue.updated_at ).getTime( ); // 1711471241000
|
const time_UpdateMs = new Date( issue.updated_at ).getTime( ); // 1711471241000
|
||||||
|
|
||||||
//if ( curtime < time_UpdateMs + expireAfterMs ) continue;
|
// if ( curtime < time_UpdateMs + expireAfterMs ) continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Anything past this point is stale / to be closed
|
Anything past this point is stale / to be closed
|
||||||
@@ -310,8 +560,8 @@ jobs:
|
|||||||
let iss_body = `${ issue.body }`;
|
let iss_body = `${ issue.body }`;
|
||||||
const iss_body_lc = iss_body.toLowerCase( );
|
const iss_body_lc = iss_body.toLowerCase( );
|
||||||
|
|
||||||
console.log( ` └── 📁 ` + iss_title );
|
console.log( ` └── 📁 ` + iss_title + ` #${ issue.number }`);
|
||||||
console.log( ` └── 📄 Issue #${ issue.number } last updated on ${ date_UpdateHuman }` );
|
console.log( ` └── 📄 last updated on ${ date_UpdateHuman }` );
|
||||||
console.log( ` └── 📄 ${add_labels}` );
|
console.log( ` └── 📄 ${add_labels}` );
|
||||||
console.log( `\n\n` )
|
console.log( `\n\n` )
|
||||||
|
|
||||||
@@ -319,8 +569,8 @@ jobs:
|
|||||||
Keywords
|
Keywords
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const bug_words = [ "bug", "broke", "issue", "fail" ];
|
const bug_words = [ "bug", "broke", "issue", "fail", "wont work" ];
|
||||||
const feat_words = [ "feature", "request", "add support" ];
|
const feat_words = [ "feature", "request", "add", "addition", "enhance", "create" ];
|
||||||
const urgn_words = [ "urgent", "urgency", "emergency", "important", "critical" ];
|
const urgn_words = [ "urgent", "urgency", "emergency", "important", "critical" ];
|
||||||
const road_words = [ "roadmap", "road map", "planned" ];
|
const road_words = [ "roadmap", "road map", "planned" ];
|
||||||
|
|
||||||
@@ -339,17 +589,14 @@ jobs:
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Label > Bugs
|
Label > Bugs
|
||||||
*/
|
|
||||||
|
|
||||||
const bug_bIncWordT = bug_words.some( s => s.includes( iss_title_lc ) || iss_title_lc.includes( s ) );
|
|
||||||
|
|
||||||
/*
|
|
||||||
Find regex based phrases
|
Find regex based phrases
|
||||||
|
|
||||||
Regex:
|
Regex:
|
||||||
https://regex101.com/r/Z99Gnq/2
|
https://regex101.com/r/Z99Gnq/2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const bug_bIncWordT = bug_words.some( s => s.includes( iss_title_lc ) || iss_title_lc.includes( s ) );
|
||||||
const bug_findWordList = /^\b(?:I?\s*have\s*(?:a|an)\s*(?:issue|problem|bug))|(?:will\s*not\s*work)|(?:it\s*is\s*(?:broken|broke|stuck))|(?:found\s*(?:an?|the)\s*(?:bug|issue))|(?:can\s*I\s*fix\s*the\s*(?:bug|issue))|(?:(?:does not|doesn'?t|don'?t|won'?t|can'?t|can\s?not|will\s*not)\s*(?:work|load|function))|(?:it\s*(?:will\s?not|won'?t|can\s?not|can'?t))\s*(?:get|find)\s*the\s*(?:website|site|webpage|page)|(?:the\s*(?:window|frame)\s*is\s*(?:blank|white|empty|missing))\b$/igm;
|
const bug_findWordList = /^\b(?:I?\s*have\s*(?:a|an)\s*(?:issue|problem|bug))|(?:will\s*not\s*work)|(?:it\s*is\s*(?:broken|broke|stuck))|(?:found\s*(?:an?|the)\s*(?:bug|issue))|(?:can\s*I\s*fix\s*the\s*(?:bug|issue))|(?:(?:does not|doesn'?t|don'?t|won'?t|can'?t|can\s?not|will\s*not)\s*(?:work|load|function))|(?:it\s*(?:will\s?not|won'?t|can\s?not|can'?t))\s*(?:get|find)\s*the\s*(?:website|site|webpage|page)|(?:the\s*(?:window|frame)\s*is\s*(?:blank|white|empty|missing))\b$/igm;
|
||||||
const bug_bFoundMatchTitle = Boolean( bug_findWordList.test( iss_title ) );
|
const bug_bFoundMatchTitle = Boolean( bug_findWordList.test( iss_title ) );
|
||||||
const bug_bFoundMatchBody = Boolean( bug_findWordList.test( iss_body ) );
|
const bug_bFoundMatchBody = Boolean( bug_findWordList.test( iss_body ) );
|
||||||
@@ -377,16 +624,49 @@ jobs:
|
|||||||
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
||||||
core.info( `Skipping: Detected ${ author }` )
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
// Rename title to contain Bug:
|
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
|
||||||
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rename title to contain Bug:
|
||||||
|
if bug title or body contains keyword hinting at the issue being about a bug; change the title of the issue
|
||||||
|
|
||||||
|
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
|
||||||
|
*/
|
||||||
|
|
||||||
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !bug_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !bug_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
||||||
{
|
{
|
||||||
const title = issue.title;
|
|
||||||
|
/*
|
||||||
|
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
|
||||||
|
original: Bug: CMD windows opens then closes, can't run the script.
|
||||||
|
new: 🐛 Bug: CMD windows opens then closes, can't run the script.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const removeBeginning1 = bug_tag.substring(3); // "Bug:"
|
||||||
|
let removeBeginning2 = bug_tag.substring(0); // "🐛 Bug:"
|
||||||
|
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Bug:"
|
||||||
|
|
||||||
|
if ( iss_title.startsWith(removeBeginning1) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning1.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
else if ( iss_title.startsWith(removeBeginning2) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning2.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = iss_title;
|
||||||
let title_new = title.replace( /^\s?bug\s*(.*?)\b/gi, '' );
|
let title_new = title.replace( /^\s?bug\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?fail\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?fail\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?issue\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?issue\s*(.*?)\b/gi, '' );
|
||||||
iss_title = `${ bug_tag } ${ title_new }`;
|
iss_title = `${ bug_tag } ${ title_new }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log( `New Title: ...................... ${ iss_title }` )
|
||||||
|
|
||||||
await github.rest.issues.update(
|
await github.rest.issues.update(
|
||||||
{
|
{
|
||||||
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
||||||
@@ -407,7 +687,7 @@ jobs:
|
|||||||
https://regex101.com/r/fR1Hm6/1
|
https://regex101.com/r/fR1Hm6/1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const feat_findWordList = /^(?:(?:request|include|see)\s*(?:an?|the?)\s*(?:feature|addon|addition|plugin))|(?:(?:add|see|get)\s*support\s*(?:for|with|of))|(?:can\s*we\s*get\s*(?:the|a)\s*(?:ability|feature))|(?:💡 Feature:)$/igm;
|
const feat_findWordList = /(?:(?:add|enjoy|would|like|can|request|include|see|could|have)\s*?(?:the|liked?|i|we|an?|the|you?)\s*?(?:to|have|an|get|ability|request|add|feature|functionality|addon|addition|plugin|create))|(?:(?:add|see|get)\s*?support\s*?(?:for|with|of))|(?:can\s*we\s*get\s*?(?:the|a)\s*?(?:ability|feature))|(?:💡 Feature:)$/igm;
|
||||||
const feat_bFoundMatchTitle = Boolean( feat_findWordList.test( iss_title ) );
|
const feat_bFoundMatchTitle = Boolean( feat_findWordList.test( iss_title ) );
|
||||||
const feat_bFoundMatchBody = Boolean( feat_findWordList.test( iss_body ) );
|
const feat_bFoundMatchBody = Boolean( feat_findWordList.test( iss_body ) );
|
||||||
|
|
||||||
@@ -434,17 +714,49 @@ jobs:
|
|||||||
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
||||||
core.info( `Skipping: Detected ${ author }` )
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
// Rename title to contain Feature:
|
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
|
||||||
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rename title to contain Feature:
|
||||||
|
if feature title or body contains keyword hinting at the issue being about a feature; change the title of the issue
|
||||||
|
|
||||||
|
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
|
||||||
|
*/
|
||||||
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !feat_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !feat_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
||||||
{
|
{
|
||||||
const title = issue.title;
|
|
||||||
|
/*
|
||||||
|
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
|
||||||
|
original: Feature: CMD windows opens then closes, can't run the script.
|
||||||
|
new: 💡 Feature: CMD windows opens then closes, can't run the script.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const removeBeginning1 = feat_tag.substring(3); // "Feature:"
|
||||||
|
let removeBeginning2 = feat_tag.substring(0); // "💡 Feature:"
|
||||||
|
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Feature:"
|
||||||
|
|
||||||
|
if ( iss_title.startsWith(removeBeginning1) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning1.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
else if ( iss_title.startsWith(removeBeginning2) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning2.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = iss_title;
|
||||||
let title_new = title.replace( /^\s?feature\s*(.*?)\b/gi, '' );
|
let title_new = title.replace( /^\s?feature\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?request\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?request\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?add(.*?)\s?feature\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?add(.*?)\s?feature\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?add(.*?)\s?support\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?add(.*?)\s?support\s*(.*?)\b/gi, '' );
|
||||||
iss_title = `${ feat_tag } ${ title_new }`;
|
iss_title = `${ feat_tag } ${ title_new }`; // change TAG per category
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log( `New Title: ...................... ${ iss_title }` )
|
||||||
|
|
||||||
await github.rest.issues.update(
|
await github.rest.issues.update(
|
||||||
{
|
{
|
||||||
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
||||||
@@ -492,10 +804,40 @@ jobs:
|
|||||||
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
||||||
core.info( `Skipping: Detected ${ author }` )
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
// Rename title to contain Urgent:
|
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
|
||||||
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rename title to contain Urgent:
|
||||||
|
if urgent title or body contains keyword hinting at the issue being about urgent; change the title of the issue
|
||||||
|
|
||||||
|
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
|
||||||
|
*/
|
||||||
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !urgn_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !urgn_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
||||||
{
|
{
|
||||||
const title = issue.title;
|
|
||||||
|
/*
|
||||||
|
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
|
||||||
|
original: Urgent: CMD windows opens then closes, can't run the script.
|
||||||
|
new: ⚠ Urgent: CMD windows opens then closes, can't run the script.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const removeBeginning1 = urgn_tag.substring(3); // "Urgent:"
|
||||||
|
let removeBeginning2 = urgn_tag.substring(0); // "⚠ Urgent:"
|
||||||
|
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Urgent:"
|
||||||
|
|
||||||
|
if ( iss_title.startsWith(removeBeginning1) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning1.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
else if ( iss_title.startsWith(removeBeginning2) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning2.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = iss_title;
|
||||||
let title_new = title.replace( /^\s?emergency\s*(.*?)\b/gi, '' );
|
let title_new = title.replace( /^\s?emergency\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?urgent\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?urgent\s*(.*?)\b/gi, '' );
|
||||||
title_new = title.replace( /^\s?urgency\s*(.*?)\b/gi, '' );
|
title_new = title.replace( /^\s?urgency\s*(.*?)\b/gi, '' );
|
||||||
@@ -504,6 +846,8 @@ jobs:
|
|||||||
iss_title = `${ urgn_tag } ${ title_new }`;
|
iss_title = `${ urgn_tag } ${ title_new }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log( `New Title: ...................... ${ iss_title }` )
|
||||||
|
|
||||||
await github.rest.issues.update(
|
await github.rest.issues.update(
|
||||||
{
|
{
|
||||||
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
owner: context.repo.owner, repo: context.repo.repo, issue_number: issue.number,
|
||||||
@@ -552,17 +896,47 @@ jobs:
|
|||||||
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
if ( author === `${{ env.BOT_NAME_DEPENDABOT }}` )
|
||||||
core.info( `Skipping: Detected ${ author }` )
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
// Rename title to contain Roadmap:
|
if ( author === `${{ env.BOT_NAME_RENOVATE }}` )
|
||||||
|
core.info( `Skipping: Detected ${ author }` )
|
||||||
|
|
||||||
|
/*
|
||||||
|
Rename title to contain Roadmap:
|
||||||
|
if roadmap title or body contains keyword hinting at the issue being about roadmap; change the title of the issue
|
||||||
|
|
||||||
|
@ref https://jsfiddle.net/aetherinox/wj17x8mp/2/
|
||||||
|
*/
|
||||||
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !road_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
if ( author !== `${{ env.BOT_NAME_DEPENDABOT }}` && !road_bFoundPRTitle && !iss_title_lc.startsWith( bug_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( feat_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( urgn_tag.toLowerCase( ) ) && !iss_title_lc.startsWith( road_tag.toLowerCase( ) ) )
|
||||||
{
|
{
|
||||||
const title = issue.title;
|
|
||||||
let title_new = title.replace( /^\s?emergency\s*(.*?)\b/gi, '' );
|
/*
|
||||||
title_new = title.replace( /^\s?urgent\s*(.*?)\b/gi, '' );
|
If a user creates an issue starting with our tag; strip it and add ours with the emoji instead
|
||||||
title_new = title.replace( /^\s?urgency\s*(.*?)\b/gi, '' );
|
original: Roadmap: CMD windows opens then closes, can't run the script.
|
||||||
title_new = title.replace( /^\s?important\s*(.*?)\b/gi, '' );
|
new: 🗺️ Roadmap: CMD windows opens then closes, can't run the script.
|
||||||
title_new = title.replace( /^\s?critical\s*(.*?)\b/gi, '' );
|
*/
|
||||||
iss_title = `${ road_tag } ${ title_new }`;
|
|
||||||
|
const removeBeginning1 = road_tag.substring(3); // "Roadmap:"
|
||||||
|
let removeBeginning2 = road_tag.substring(0); // "🗺️ Roadmap:"
|
||||||
|
removeBeginning2 = removeBeginning2.replace(/\s/g, '') // "Roadmap:"
|
||||||
|
|
||||||
|
if ( iss_title.startsWith(removeBeginning1) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning1.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
}
|
}
|
||||||
|
else if ( iss_title.startsWith(removeBeginning2) )
|
||||||
|
{
|
||||||
|
iss_title = iss_title.slice(removeBeginning2.length);
|
||||||
|
iss_title = iss_title.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = iss_title;
|
||||||
|
let title_new = title.replace( /^\s?broad(.*?)\s?map\s*(.*?)\b/gi, '' );
|
||||||
|
title_new = title.replace( /^\s?planned\s*(.*?)\b/gi, '' );
|
||||||
|
title_new = title.replace( /^\s?broadmap\s*(.*?)\b/gi, '' );
|
||||||
|
iss_title = `${ road_tag } ${ title_new }`; // change TAG per category
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log( `New Title: ...................... ${ iss_title }` )
|
||||||
|
|
||||||
await github.rest.issues.update(
|
await github.rest.issues.update(
|
||||||
{
|
{
|
||||||
@@ -581,15 +955,15 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job [ Stale Issues ]
|
# Issues (Stale) › Stale
|
||||||
# #
|
# #
|
||||||
|
|
||||||
job-issues-stale:
|
job-issues-stale:
|
||||||
name: >-
|
name: >-
|
||||||
💤 Check › Stale
|
💤 Scan › Check Stale
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 4
|
timeout-minutes: 5
|
||||||
needs:
|
needs:
|
||||||
- job-labels-create
|
- job-labels-create
|
||||||
- job-issues-nolabel
|
- job-issues-nolabel
|
||||||
@@ -600,14 +974,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Stale Issues ] Check Condition
|
# Labels › Stale › Check
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "💤 Stale › Check Condition"
|
- name: >-
|
||||||
|
💤 Stale › Check Condition
|
||||||
uses: actions/stale@v9
|
uses: actions/stale@v9
|
||||||
id: task_issues_stale_run
|
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
repo-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
stale-issue-message: |
|
stale-issue-message: |
|
||||||
⚠️ It looks like there hasn't been any recent updates on this issue. If you created this issue and no longer consider it open, then please login to github and close the issue.
|
⚠️ It looks like there hasn't been any recent updates on this issue. If you created this issue and no longer consider it open, then please login to github and close the issue.
|
||||||
|
|
||||||
@@ -616,41 +990,41 @@ jobs:
|
|||||||
---
|
---
|
||||||
|
|
||||||
<sub>I am a bot reaching out to you with an automated response.</sub>
|
<sub>I am a bot reaching out to you with an automated response.</sub>
|
||||||
stale-issue-label: 'Status 𐄂 Stale'
|
stale-issue-label: '${{ env.LABEL_STALE }}'
|
||||||
close-issue-label: 'Status 𐄂 Autoclosed'
|
close-issue-label: '${{ env.LABEL_AUTOCLOSE }}'
|
||||||
exempt-issue-labels: 'Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Pull Request,Type ◦ Roadmap'
|
exempt-issue-labels: '${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_PR }},${{ env.LABEL_ROADMAP }}'
|
||||||
days-before-stale: 60
|
days-before-stale: 120
|
||||||
days-before-close: 7
|
days-before-close: 7
|
||||||
days-before-pr-stale: -1
|
days-before-pr-stale: -1
|
||||||
days-before-pr-close: -1
|
days-before-pr-close: -1
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job [ Lock Issues ]
|
# Issues (Stale) › Lock
|
||||||
# #
|
# #
|
||||||
|
|
||||||
job-issues-lock:
|
job-issues-lock:
|
||||||
name: >-
|
name: >-
|
||||||
🔒 Check › Inactive
|
🔒 Scan › Lock Inactive
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 4
|
timeout-minutes: 5
|
||||||
needs:
|
needs:
|
||||||
- job-labels-create
|
- job-labels-create
|
||||||
- job-issues-nolabel
|
- job-issues-nolabel
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Lock Issues ] Look for inactives
|
# Labels › Inactive › Lock
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🔒 Lock › Inactives"
|
- name: >-
|
||||||
|
🔒 Inactive › Lock
|
||||||
uses: dessant/lock-threads@v5
|
uses: dessant/lock-threads@v5
|
||||||
id: task_issues_lock_run
|
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
exclude-any-issue-labels: 'AC › Review Required,Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Roadmap,Type ◦ Internal'
|
exclude-any-issue-labels: '${{ env.LABEL_AC_REVIEW }},${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_ROADMAP }},${{ env.LABEL_INTERNAL }}'
|
||||||
add-issue-labels: 'Status 𐄂 Locked'
|
add-issue-labels: '${{ env.LABEL_LOCKED }}'
|
||||||
issue-inactive-days: '60'
|
issue-inactive-days: '120'
|
||||||
issue-lock-reason: 'resolved'
|
issue-lock-reason: 'resolved'
|
||||||
issue-comment: >
|
issue-comment: >
|
||||||
⚠️ This **issue** has been automatically locked since there has not been any recent activity after it was closed.
|
⚠️ This **issue** has been automatically locked since there has not been any recent activity after it was closed.
|
||||||
@@ -660,8 +1034,8 @@ jobs:
|
|||||||
---
|
---
|
||||||
|
|
||||||
<sub>I am a bot reaching out to you with an automated response.</sub>
|
<sub>I am a bot reaching out to you with an automated response.</sub>
|
||||||
exclude-any-pr-labels: 'AC › Review Required,Status 𐄂 Accepted,Status 𐄂 Review,Status 𐄂 Pending,Type ◦ Bug,Type ◦ Dependency,Type ◦ Docs,Type ◦ Feature,Type ◦ Git Action,Type ◦ Roadmap,Type ◦ Internal'
|
exclude-any-pr-labels: '${{ env.LABEL_AC_REVIEW }},${{ env.LABEL_ACCEPTED }},${{ env.LABEL_REVIEW }},${{ env.LABEL_PENDING }},${{ env.LABEL_BUG }},${{ env.LABEL_DEPENDENCY }},${{ env.LABEL_DOCS }},${{ env.LABEL_FEATURE }},${{ env.LABEL_GIT }},${{ env.LABEL_ROADMAP }},${{ env.LABEL_INTERNAL }}'
|
||||||
add-pr-labels: 'Status 𐄂 Locked'
|
add-pr-labels: '${{ env.LABEL_LOCKED }}'
|
||||||
pr-inactive-days: '365'
|
pr-inactive-days: '365'
|
||||||
pr-lock-reason: 'resolved'
|
pr-lock-reason: 'resolved'
|
||||||
pr-comment: >
|
pr-comment: >
|
||||||
|
|||||||
321
.github/workflows/labels-clean.yml
vendored
@@ -4,14 +4,42 @@
|
|||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
#
|
#
|
||||||
# This Github action must be activated manually. This workflow script will do the
|
# @notes This Github action must be activated manually. This workflow script will do the following:
|
||||||
# following:
|
|
||||||
#
|
|
||||||
# - Remove all existing labels in repository
|
# - Remove all existing labels in repository
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/labels-clean.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/labels-clean.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "🎫 Labels › Remove"
|
name: '🧹 Labels › Clean'
|
||||||
run-name: "🎫 Labels › Remove"
|
run-name: '🧹 Labels › Clean'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
@@ -25,8 +53,12 @@ on:
|
|||||||
# #
|
# #
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
LABELS_JSON: |
|
LABELS_JSON: |
|
||||||
[
|
[
|
||||||
{ "name": "bug", "color": "8F1784", "description": "Default github label" },
|
{ "name": "bug", "color": "8F1784", "description": "Default github label" },
|
||||||
@@ -46,32 +78,33 @@ env:
|
|||||||
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
||||||
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
||||||
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
||||||
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
{ "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
||||||
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
{ "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
||||||
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
{ "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
||||||
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
{ "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
||||||
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
{ "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
||||||
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
{ "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
||||||
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
|
{ "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" },
|
||||||
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
|
{ "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" },
|
||||||
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
{ "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
||||||
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
{ "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
||||||
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
|
{ "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" },
|
||||||
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
{ "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
||||||
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
{ "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
||||||
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
{ "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
||||||
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
{ "name": "Type › Lock Maintenance", "color": "FBCA04", "description": "Sync package-lock.json" },
|
||||||
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
|
{ "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
||||||
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
{ "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" },
|
||||||
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
{ "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
||||||
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
{ "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
||||||
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
{ "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
||||||
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
{ "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
||||||
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
{ "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
||||||
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
{ "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
||||||
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
{ "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
||||||
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
|
{ "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
||||||
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
{ "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" },
|
||||||
|
{ "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
||||||
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
||||||
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
||||||
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
||||||
@@ -110,12 +143,12 @@ jobs:
|
|||||||
# This job removes all existing labels
|
# This job removes all existing labels
|
||||||
# #
|
# #
|
||||||
|
|
||||||
issues-labels-remove:
|
issues-labels-clean:
|
||||||
name: >-
|
name: >-
|
||||||
🎫 Labels › Remove
|
🧹 Labels › Clean
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
runs-on: apollo-x64
|
# runs-on: apollo-x64
|
||||||
timeout-minutes: 4
|
timeout-minutes: 3
|
||||||
permissions:
|
permissions:
|
||||||
contents: 'read'
|
contents: 'read'
|
||||||
id-token: 'write'
|
id-token: 'write'
|
||||||
@@ -123,49 +156,132 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Labels › Start
|
# Labels › Clean › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: '☑️ Checkout'
|
||||||
✅ Start
|
|
||||||
id: task_label_remove_start
|
|
||||||
run: |
|
|
||||||
echo "Starting workflow"
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Labels › Set Env Variables
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
🕛 Get Timestamp
|
|
||||||
id: task_label_set_timestamp
|
|
||||||
run: |
|
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Labels › Checkout
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
☑️ Checkout
|
|
||||||
id: task_label_remove_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Labels › Start
|
# Labels › Clean › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Clean › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Clean › Delete Existing Labels
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🏷️ Delete Existing Labels
|
🏷️ Delete Existing Labels
|
||||||
id: task_label_remove_run
|
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
script: |
|
script: |
|
||||||
const targetOwner = context.repo.owner;
|
const targetOwner = context.repo.owner;
|
||||||
const targetRepo = context.repo.repo;
|
const targetRepo = context.repo.repo;
|
||||||
@@ -212,83 +328,12 @@ jobs:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Labels › Get Weekly Commits
|
# Labels › Clean › Get Weekly Commits
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🕛 Get Weekly Commit List
|
🕛 Get Weekly Commit List
|
||||||
id: task_label_set_weekly_commit_list
|
|
||||||
run: |
|
run: |
|
||||||
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
echo 'WEEKLY_COMMITS<<EOF' >> $GITHUB_ENV
|
||||||
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
git log --format="[\`%h\`](${{ github.server_url }}/${{ github.repository }}/commit/%H) %s - %an" --since=7.days >> $GITHUB_ENV
|
||||||
echo 'EOF' >> $GITHUB_ENV
|
echo 'EOF' >> $GITHUB_ENV
|
||||||
|
|
||||||
# #
|
|
||||||
# Labels › Notify Github › Success
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
🔔 Send Discord Webhook Message (Success)
|
|
||||||
id: task_label_notify_discord_success
|
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: success()
|
|
||||||
with:
|
|
||||||
username: 'Io'
|
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_TVAPP2_WORKFLOWS }}
|
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
|
||||||
embed-description: |
|
|
||||||
## 🎫 Labels › Clean ${{ job.status == 'success' && '✅' || '❌' }}
|
|
||||||
|
|
||||||
A **successful** workflow has been ran to wipe all labels from your repository.
|
|
||||||
|
|
||||||
**${{ steps.task_label_remove_run.outputs.result }}** labels have been removed.
|
|
||||||
|
|
||||||
- Labels: `${{ steps.task_label_remove_run.outputs.result }} created`
|
|
||||||
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
|
|
||||||
- Runner: `${{ runner.name }}`
|
|
||||||
- Triggered By: `${{ github.actor }}`
|
|
||||||
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
|
|
||||||
|
|
||||||
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
|
||||||
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
|
||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Labels › Notify Github › Failure
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
🔔 Send Discord Webhook Message (Failure)
|
|
||||||
id: task_label_notify_discord_failure
|
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
username: 'Io'
|
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_TVAPP2_WORKFLOWS }}
|
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
|
||||||
embed-description: |
|
|
||||||
## 🎫 Labels › Clean ${{ job.status == 'success' && '✅' || '❌' }}
|
|
||||||
|
|
||||||
A **failed** attempt was made to run this workflow. No new labels have been added to your repository.
|
|
||||||
|
|
||||||
- Labels: `${{ steps.task_label_remove_run.outputs.result }} created`
|
|
||||||
- Workflow: `${{ github.workflow }} (#${{github.run_number}})`
|
|
||||||
- Runner: `${{ runner.name }}`
|
|
||||||
- Triggered By: `${{ github.actor }}`
|
|
||||||
- Status: `${{ job.status == 'success' && '✅ Successful' || '❌ Failed' }}`
|
|
||||||
|
|
||||||
embed-color: ${{ job.status == 'success' && '5763719' || '15418782' }}
|
|
||||||
embed-footer-text: "Completed at ${{ env.NOW }} UTC"
|
|
||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
|
||||||
|
|||||||
334
.github/workflows/labels-create.yml
vendored
@@ -1,41 +1,119 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc manually activated workflow to create issue labels
|
|
||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage manually activated workflow to create issue labels
|
||||||
#
|
#
|
||||||
# This Github action must be activated manually. This workflow script will do the
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
# following:
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
#
|
#
|
||||||
# - Scan issues / pull requests and make sure they have properly assigned labels:
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
# - `Bug`
|
# https://github.com/nektos/act
|
||||||
# - `Feature`
|
# Extract act to folder
|
||||||
# - `Urgent`
|
# Add system env var with path to act.exe
|
||||||
# - `Roadmap`
|
# Run the commands:
|
||||||
#
|
# git pull https://github.com/username/repo
|
||||||
# - Workflow script will then scan each pr or issue and mark them as `Stale`
|
# act -W .github/workflows/labels-create.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
# if they haven't had any replies in 30 days.
|
# act -W .github/workflows/labels-create.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
#
|
|
||||||
# - Workflow will `autoclose` pr or issues which haven't had action in `365 days`.
|
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "🎫 Labels › Create"
|
name: '🎫 Labels › Create'
|
||||||
run-name: "🎫 Labels › Create"
|
run-name: '🎫 Labels › Create'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# triggers
|
# triggers
|
||||||
# #
|
# #
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Trigger > Workflow Dispatch
|
||||||
|
# #
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Name
|
||||||
|
#
|
||||||
|
# The discord bot name
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_NAME:
|
||||||
|
description: '🤖 Bot Name'
|
||||||
|
required: true
|
||||||
|
default: 'Europa'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Avatar
|
||||||
|
#
|
||||||
|
# The discord bot avatar to show; let's use some weird picture
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_AVATAR:
|
||||||
|
description: '🤖 Avatar URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://i.imgur.com/UqwMom1.jpeg'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Author Icon URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON:
|
||||||
|
description: '🤖 Embed Author Icon'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Discord Bot › Thumbnail URL
|
||||||
|
#
|
||||||
|
# A small picture shown to the top-right of each post
|
||||||
|
# #
|
||||||
|
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL:
|
||||||
|
description: '🤖 Embed Thumbnail URL'
|
||||||
|
required: true
|
||||||
|
default: 'https://avatars.githubusercontent.com/u/200161462'
|
||||||
|
type: string
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# environment variables
|
# environment variables
|
||||||
# #
|
# #
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
DISCORD_BOT_NAME: ${{ github.event.inputs.DISCORD_BOT_NAME || 'Europa' }}
|
||||||
|
DISCORD_BOT_AVATAR: ${{ github.event.inputs.DISCORD_BOT_AVATAR || 'https://i.imgur.com/UqwMom1.jpeg' }}
|
||||||
|
DISCORD_BOT_EMBED_AUTHOR_ICON: ${{ github.event.inputs.DISCORD_BOT_EMBED_AUTHOR_ICON || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
|
DISCORD_BOT_EMBED_THUMBNAIL: ${{ github.event.inputs.DISCORD_BOT_EMBED_THUMBNAIL || 'https://avatars.githubusercontent.com/u/200161462' }}
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
LABELS_JSON: |
|
LABELS_JSON: |
|
||||||
[
|
[
|
||||||
{ "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
|
{ "name": "AC › Changes Made", "color": "8F1784", "description": "Requested changes have been made and are pending a re-scan" },
|
||||||
@@ -46,32 +124,33 @@ env:
|
|||||||
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
{ "name": "AC › Review Required", "color": "8F1784", "description": "PR needs to be reviewed by another person, after the requested changes have been made" },
|
||||||
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
{ "name": "AC › Security Warning", "color": "761620", "description": "Does not conform to developer policies, or includes potentially dangerous code" },
|
||||||
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
{ "name": "AC › Skipped Scan", "color": "8F1784", "description": "Author has skipped code scan" },
|
||||||
{ "name": "Status 𐄂 Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
{ "name": "Status › Duplicate", "color": "75536b", "description": "Issue or pull request already exists" },
|
||||||
{ "name": "Status 𐄂 Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
{ "name": "Status › Accepted", "color": "2e7539", "description": "This pull request has been accepted" },
|
||||||
{ "name": "Status 𐄂 Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
{ "name": "Status › Autoclosed", "color": "3E0915", "description": "Originally stale and was autoclosed for no activity" },
|
||||||
{ "name": "Status 𐄂 Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
{ "name": "Status › Denied", "color": "ba4058", "description": "Pull request has been denied" },
|
||||||
{ "name": "Status 𐄂 Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
{ "name": "Status › Locked", "color": "550F45", "description": "Automatically locked by AdminServ for a prolonged period of inactivity" },
|
||||||
{ "name": "Status 𐄂 Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
{ "name": "Status › Need Info", "color": "2E3C4C", "description": "Not enough information to resolve" },
|
||||||
{ "name": "Status 𐄂 No Action", "color": "030406", "description": "Closed without any action being taken" },
|
{ "name": "Status › No Action", "color": "030406", "description": "Closed without any action being taken" },
|
||||||
{ "name": "Status 𐄂 Pending", "color": "984b12", "description": "Pending pull request" },
|
{ "name": "Status › Pending", "color": "984b12", "description": "Pending pull request" },
|
||||||
{ "name": "Status 𐄂 Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
{ "name": "Status › Released", "color": "1b6626", "description": "Issues or PR has been implemented and is now live" },
|
||||||
{ "name": "Status 𐄂 Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
{ "name": "Status › Reopened", "color": "8a6f14", "description": "A previously closed PR which has been re-opened" },
|
||||||
{ "name": "Status 𐄂 Review", "color": "9e1451", "description": "Currently pending review" },
|
{ "name": "Status › Review", "color": "9e1451", "description": "Currently pending review" },
|
||||||
{ "name": "Status 𐄂 Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
{ "name": "Status › Stale", "color": "928282", "description": "Has not had any activity in over 30 days" },
|
||||||
{ "name": "Type ◦ Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
{ "name": "Type › Bug", "color": "9a2c2c", "description": "Something isn't working" },
|
||||||
{ "name": "Type ◦ Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
{ "name": "Type › Dependency", "color": "243759", "description": "Item is associated to dependency" },
|
||||||
{ "name": "Type ◦ Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
{ "name": "Type › Lock Maintenance", "color": "FBCA04", "description": "Sync package-lock.json" },
|
||||||
{ "name": "Type ◦ Feature", "color": "3c4e93", "description": "Feature request" },
|
{ "name": "Type › Docs", "color": "0e588d", "description": "Improvements or modifications to docs" },
|
||||||
{ "name": "Type ◦ Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
{ "name": "Type › Feature", "color": "3c4e93", "description": "Feature request" },
|
||||||
{ "name": "Type ◦ Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
{ "name": "Type › Git Action", "color": "030406", "description": "GitHub Action / workflow" },
|
||||||
{ "name": "Type ◦ Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
{ "name": "Type › Pull Request", "color": "8F1784", "description": "Normal pull request" },
|
||||||
{ "name": "Type ◦ Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
{ "name": "Type › Roadmap", "color": "8F1784", "description": "Feature or bug currently planned for implementation" },
|
||||||
{ "name": "Build ◦ Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
{ "name": "Type › Internal", "color": "A51994", "description": "Assigned items are for internal developer use" },
|
||||||
{ "name": "Build ◦ Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
{ "name": "Build › Desktop", "color": "c7ca4a", "description": "Specific to desktop" },
|
||||||
{ "name": "Build ◦ MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
{ "name": "Build › Linux", "color": "c7ca4a", "description": "Specific to Linux" },
|
||||||
{ "name": "Build ◦ Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
{ "name": "Build › MacOS", "color": "c7ca4a", "description": "Specific to MacOS" },
|
||||||
{ "name": "Build ◦ Web", "color": "c7ca4a", "description": "Specific to web" },
|
{ "name": "Build › Mobile", "color": "c7ca4a", "description": "Specific to mobile" },
|
||||||
{ "name": "Build ◦ Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
{ "name": "Build › Web", "color": "c7ca4a", "description": "Specific to web" },
|
||||||
|
{ "name": "Build › Windows", "color": "c7ca4a", "description": "Specific to Windows" },
|
||||||
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
{ "name": "› API", "color": "F99B50", "description": "Plugin API, CLI, browser JS API" },
|
||||||
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
{ "name": "› Auto-type", "color": "9141E0", "description": "Auto-type functionality in desktop apps" },
|
||||||
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
{ "name": "› Browser", "color": "9141E0", "description": "Browser plugins and passing data to <=> from app" },
|
||||||
@@ -115,6 +194,8 @@ jobs:
|
|||||||
name: >-
|
name: >-
|
||||||
🎫 Labels › Create
|
🎫 Labels › Create
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 3
|
||||||
permissions:
|
permissions:
|
||||||
contents: 'read'
|
contents: 'read'
|
||||||
id-token: 'write'
|
id-token: 'write'
|
||||||
@@ -122,41 +203,125 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Create Labels ] Start
|
# Labels › Create › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: '☑️ Checkout'
|
||||||
✅ Start
|
|
||||||
id: task_label_create_start
|
|
||||||
run: |
|
|
||||||
echo "Assigning labels and assignees"
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Create Labels › Set Env Variables
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
🕛 Get Timestamp
|
|
||||||
id: task_label_set_timestamp
|
|
||||||
run: |
|
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
# #
|
|
||||||
# [ Create Labels ] Checkout
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: >-
|
|
||||||
☑️ Checkout
|
|
||||||
id: task_label_create_checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Create Labels ] Verify Existing Labels
|
# Labels › Create › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Create › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Labels › Create › Verify Existing Labels
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
@@ -164,7 +329,7 @@ jobs:
|
|||||||
id: task_label_verify_existing
|
id: task_label_verify_existing
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
github-token: ${{ secrets.ADMINSERV_TOKEN_CL || github.token }}
|
||||||
script: |
|
script: |
|
||||||
const labels = JSON.parse( process.env.LABELS_JSON );
|
const labels = JSON.parse( process.env.LABELS_JSON );
|
||||||
let result = Object.keys(labels).length;
|
let result = Object.keys(labels).length;
|
||||||
@@ -199,7 +364,7 @@ jobs:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Get Weekly Commits
|
# Labels › Create › Get Weekly Commits
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
@@ -216,16 +381,15 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Success)
|
🔔 Send Discord Webhook Message (Success)
|
||||||
id: task_label_notify_discord_success
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: success()
|
if: success()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_TVAPP2_WORKFLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 🎫 Labels › Create ${{ job.status == 'success' && '✅' || '❌' }}
|
## 🎫 Labels › Create ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -244,7 +408,7 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Cleanup › Notify Github › Failure
|
# Cleanup › Notify Github › Failure
|
||||||
@@ -252,16 +416,15 @@ jobs:
|
|||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
🔔 Send Discord Webhook Message (Failure)
|
🔔 Send Discord Webhook Message (Failure)
|
||||||
id: task_label_notify_discord_failure
|
uses: tsickert/discord-webhook@v7.0.0
|
||||||
uses: tsickert/discord-webhook@v6.0.0
|
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
username: 'Io'
|
username: ${{ env.DISCORD_BOT_NAME }}
|
||||||
avatar-url: 'https://i.imgur.com/8BVDkla.jpg'
|
avatar-url: ${{ env.DISCORD_BOT_AVATAR }}
|
||||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_TVAPP2_WORKFLOWS }}
|
webhook-url: ${{ secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKfLOWS }}
|
||||||
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
embed-title: "⚙️ ${{ github.workflow_ref }}"
|
||||||
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-thumbnail-url: 'https://i.imgur.com/zDIzE8T.jpg'
|
embed-thumbnail-url: ${{ env.DISCORD_BOT_EMBED_THUMBNAIL }}
|
||||||
embed-description: |
|
embed-description: |
|
||||||
## 🎫 Labels › Create ${{ job.status == 'success' && '✅' || '❌' }}
|
## 🎫 Labels › Create ${{ job.status == 'success' && '✅' || '❌' }}
|
||||||
|
|
||||||
@@ -278,5 +441,4 @@ jobs:
|
|||||||
embed-timestamp: "${{ env.NOW_LONG }}"
|
embed-timestamp: "${{ env.NOW_LONG }}"
|
||||||
embed-author-name: "${{ github.repository_owner }}"
|
embed-author-name: "${{ github.repository_owner }}"
|
||||||
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
embed-author-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
embed-author-icon-url: "https://avatars.githubusercontent.com/u/200161462"
|
embed-author-icon-url: ${{ env.DISCORD_BOT_EMBED_AUTHOR_ICON }}
|
||||||
|
|
||||||
|
|||||||
323
.github/workflows/ping-developer.yml
vendored
Normal file
@@ -0,0 +1,323 @@
|
|||||||
|
# #
|
||||||
|
# @type github workflow
|
||||||
|
# @author Aetherinox
|
||||||
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage pings the developer when an issue comment is made
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.CODECOV_TOKEN codecov upload token for nodejs projects
|
||||||
|
# secrets.MAXMIND_GELITE_TOKEN maxmind API token
|
||||||
|
# secrets.CF_ACCOUNT_ID cloudflare account id
|
||||||
|
# secrets.CF_ACCOUNT_TOKEN cloudflare account token
|
||||||
|
# secrets.ORG_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BOT_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BOT_GPG_KEY_B64 bot gpg private key (binary) converted to base64
|
||||||
|
# secrets.BOT_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/ping-developer.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/ping-developer.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
|
# #
|
||||||
|
|
||||||
|
name: '💬 Ping › Developer'
|
||||||
|
run-name: '💬 Ping › Developer'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# triggers
|
||||||
|
# #
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
# #
|
||||||
|
# environment variables
|
||||||
|
# #
|
||||||
|
|
||||||
|
env:
|
||||||
|
DEPLOYMENT_ENV: ${{ github.event.inputs.DEPLOYMENT_ENV || 'orion' }}
|
||||||
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
|
||||||
|
# #
|
||||||
|
# jobs
|
||||||
|
#
|
||||||
|
# env not available for job.if
|
||||||
|
# #
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
name: >-
|
||||||
|
💬 Issue › Accept
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# runs-on: apollo-x64
|
||||||
|
timeout-minutes: 5
|
||||||
|
if: |
|
||||||
|
contains(github.event.comment.body, '/ping')
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Ping › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Ping › Job Information
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
🔄 Load Job
|
||||||
|
uses: qoomon/actions--context@v4
|
||||||
|
id: 'context'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Ping › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Job ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
|
YEAR="$(date +'%Y')"
|
||||||
|
echo "YEAR=${YEAR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW="$(date +'%m-%d-%Y %H:%M:%S')" # 02-25-2025 12:49:48
|
||||||
|
echo "NOW=${NOW}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_SHORT="$(date +'%m-%d-%Y')" # 02-25-2025
|
||||||
|
echo "NOW_SHORT=${NOW_SHORT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_LONG="$(date +'%m-%d-%Y %H:%M')" # 02-25-2025 12:49
|
||||||
|
echo "NOW_LONG=${NOW_LONG}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER="$(date +'%Y%m%d')" # 20250225
|
||||||
|
echo "NOW_DOCKER=${NOW_DOCKER}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
NOW_DOCKER_TS="$(date -u +'%FT%T.%3NZ')" # 2025-02-25T12:50:11.569Z
|
||||||
|
echo "NOW_DOCKER_TS=${NOW_DOCKER_TS}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1="$(git rev-parse HEAD)" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1=${SHA1}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
SHA1_GH="$(echo ${GITHUB_SHA})" # 71fad013cfce9116ec62779e4a7e627fe4c33627
|
||||||
|
echo "SHA1_GH=${SHA1_GH}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_1DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -d '.' -f1-1)" # 3.22 > 3
|
||||||
|
echo "PKG_VER_1DIGIT=${PKG_VER_1DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
PKG_VER_2DIGIT="$(echo ${{ env.IMAGE_VERSION }} | cut -f2 -d ":" | cut -c1-3)" # 3.22 > 3.2
|
||||||
|
echo "PKG_VER_2DIGIT=${PKG_VER_2DIGIT}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
sudo apt -qq update
|
||||||
|
sudo apt -qq install tree
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... ${{ github.run_number }}"
|
||||||
|
echo " Ref ................. ${{ github.ref }}"
|
||||||
|
echo " Ref Name ............ ${{ github.ref_name }}"
|
||||||
|
echo " Event Name .......... ${{ github.event_name }}"
|
||||||
|
echo " Repo ................ ${{ github.repository }}"
|
||||||
|
echo " Repo Owner .......... ${{ github.repository_owner }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " SHA 1 (GITHUB_SHA) .. ${GITHUB_SHA}"
|
||||||
|
echo " SHA 2 (github.sha) .. ${{ github.sha }}"
|
||||||
|
echo " SHA 3 (env.SHA1) .... ${SHA1}"
|
||||||
|
echo " SHA 4 (env.SHA1_GH) . ${SHA1_GH}"
|
||||||
|
echo " Workspace ........... ${{ github.workspace }}"
|
||||||
|
echo " PWD ................. ${PWD}"
|
||||||
|
echo " Job Name ............ ${{ steps.context.outputs.job_name }}"
|
||||||
|
echo " Job ID .............. ${{ steps.context.outputs.job_id }}"
|
||||||
|
echo " Job URL ............. ${{ steps.context.outputs.job_url }}"
|
||||||
|
echo " Run ID .............. ${{ steps.context.outputs.run_id }}"
|
||||||
|
echo " Run Attempt ......... ${{ steps.context.outputs.run_attempt }}"
|
||||||
|
echo " Run Number .......... ${{ steps.context.outputs.run_number }}"
|
||||||
|
echo " Run URL ............. ${{ steps.context.outputs.run_url }}"
|
||||||
|
echo " Run Env ............. ${{ steps.context.outputs.environment }}"
|
||||||
|
echo " Run Env URL ......... ${{ steps.context.outputs.environment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Deployment URL .. ${{ steps.context.outputs.deployment_url }}"
|
||||||
|
echo " Run Deployment ...... ${{ steps.context.outputs.deployment_id }}"
|
||||||
|
echo " Run Runner Name ..... ${{ steps.context.outputs.runner_name }}"
|
||||||
|
echo " Run Runner ID ....... ${{ steps.context.outputs.runner_id }}"
|
||||||
|
echo " Year ................ ${YEAR}"
|
||||||
|
echo " Now ................. ${NOW}"
|
||||||
|
echo " Now (Short) ......... ${NOW_SHORT}"
|
||||||
|
echo " Now (Long) .......... ${NOW_LONG}"
|
||||||
|
echo " Now (Docker) ........ ${NOW_DOCKER}"
|
||||||
|
echo " Now (Docker TS) ..... ${NOW_DOCKER_TS}"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
tree -I node_modules -I .git
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo ""
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Ping › Developer › Send Mail
|
||||||
|
#
|
||||||
|
# Add Label to accepted PR
|
||||||
|
#
|
||||||
|
# port 465
|
||||||
|
# server_port: 465
|
||||||
|
# secure: true
|
||||||
|
# ignore_cert: false
|
||||||
|
#
|
||||||
|
# port 587
|
||||||
|
# server_port: 587
|
||||||
|
# secure: false
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
📨 Send mail
|
||||||
|
id: task_ping_developer_mail
|
||||||
|
uses: dawidd6/action-send-mail@v5
|
||||||
|
with:
|
||||||
|
server_address: ${{ secrets.EMAIL_SMTP }}
|
||||||
|
server_port: 465
|
||||||
|
secure: true
|
||||||
|
username: ${{ secrets.EMAIL_FROM }}
|
||||||
|
password: ${{ secrets.EMAIL_KEY }}
|
||||||
|
subject: "Github: Ping notification from ${{ github.repository }}"
|
||||||
|
to: ${{ secrets.EMAIL_TO }}
|
||||||
|
from: ${{ secrets.EMAIL_FROM }}
|
||||||
|
html_body: |
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Title</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: url('https://images.unsplash.com/photo-1541422348463-9bc715520974?fm=jpg&q=60&w=3000&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8ZGFyayUyMG1vdW50YWlufGVufDB8fDB8fHww');
|
||||||
|
font-size:9pt;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
.background-overlay {
|
||||||
|
background-color: #1111119f;
|
||||||
|
}
|
||||||
|
.background-header {
|
||||||
|
background: url('https://process.fs.teachablecdn.com/ADNupMnWyR7kCWRvm76Laz/resize=width:705/https://cdn.filestackcontent.com/MipxnobQRRS5h7raz9aM');
|
||||||
|
background-size: cover;
|
||||||
|
background-size: 100%;
|
||||||
|
background-color:#1b1b1b;
|
||||||
|
padding:5px;
|
||||||
|
height:100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="background-overlay">
|
||||||
|
<center>
|
||||||
|
<div class="background-header">
|
||||||
|
<a href="https://github.com/${{ github.repository }}"><img style="height:80px;padding-top:10px;" src="https://cdn0.iconfinder.com/data/icons/shift-logotypes/32/Github-512.png"></a>
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<div style="font-size:9pt;padding: 20px;color:#FFF;">
|
||||||
|
<h3><span style="font-size:9pt;color:#cc6613;">[Github]</span> <span style="font-size:9pt;color:#FFF;">Dear ${{github.repository_owner}},</span></h3>
|
||||||
|
<p style="font-size:9pt;color:#FFF;"><br />You have received a ping notification from <a href="https://github.com/${{ github.repository }}">${{ github.repository }}</a> by <a href="https://github.com/${{ github.event.comment.user.login }}">${{ github.event.comment.user.login }}</a>.</p>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<center>
|
||||||
|
<table cellspacing="0" cellpadding="0" width="40%" class="center">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Repository</b></td>
|
||||||
|
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">${{ github.repository }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Date</b></td>
|
||||||
|
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#0f0f0f;padding-left:10px;">${{ env.NOW }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Commenter</b></td>
|
||||||
|
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">${{ github.event.comment.user.login }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Issue #</b></td>
|
||||||
|
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#0f0f0f;padding-left:10px;">${{ github.event.issue.number }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="font-size:9pt;background-color:#8a2138;color:#FFF;padding:6px;padding-left:10px;"><b>Action</b></td>
|
||||||
|
<td style="font-size:9pt;padding-left:5px;color:#b3b3b3;background-color:#1b1b1b;padding-left:10px;">Notification</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<center>
|
||||||
|
<div style="font-family:Consolas;">
|
||||||
|
|
||||||
|
<textarea readonly=true style="font-size:9pt;width:60%;background-color:#363636;color:#FFF;padding:15px;border:1px solid #5a5a5a;" id="w3review" name="w3review" rows="20" cols="100">
|
||||||
|
${{ github.event.comment.body }}
|
||||||
|
</textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
<p style="color:#FFF;"><br /> ~ Github
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
<div style="background-color:#1b1b1b;padding:5px;line-height:70px;height:70px;text-align:center;">
|
||||||
|
<span style="color:#FFF;font-size:8pt;">Copyright © ${{ env.YEAR }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
ignore_cert: true
|
||||||
|
convert_markdown: true
|
||||||
|
priority: normal
|
||||||
556
.github/workflows/release.yml
vendored
@@ -1,12 +1,37 @@
|
|||||||
# #
|
# #
|
||||||
# @type github workflow
|
# @type github workflow
|
||||||
# @desc publishes a new release on Github
|
|
||||||
# @author Aetherinox
|
# @author Aetherinox
|
||||||
# @url https://github.com/Aetherinox
|
# @url https://github.com/Aetherinox
|
||||||
|
# @usage publishes a new release on Github
|
||||||
|
#
|
||||||
|
# @secrets secrets.SELF_TOKEN self github personal access token (fine-grained)
|
||||||
|
# secrets.SELF_TOKEN_CL self github personal access token (classic)
|
||||||
|
# secrets.NPM_TOKEN self npmjs access token
|
||||||
|
# secrets.PYPI_API_TOKEN self Pypi API token (production site) - https://pypi.org/
|
||||||
|
# secrets.PYPI_API_TEST_TOKEN self Pypi API token (test site) - https://test.pypi.org/
|
||||||
|
# secrets.SELF_DOCKERHUB_TOKEN self Dockerhub token
|
||||||
|
# secrets.ORG_BINARYNINJA_TOKEN org github personal access token (fine-grained)
|
||||||
|
# secrets.ORG_BINARYNINJA_TOKEN_CL org github personal access token (classic)
|
||||||
|
# secrets.ORG_BINARYNINJA_DOCKERHUB_TOKEN org dockerhub secret
|
||||||
|
# secrets.ORG_BINARYNINJA_GITEA_TOKEN org gitea personal access token (classic) with package:write permission
|
||||||
|
# secrets.BINARYSERV_GPG_KEY_ASC bot gpg private key (armored) | BEGIN PGP PRIVATE KEY BLOCK
|
||||||
|
# secrets.BINARYSERV_GPG_PASSPHRASE bot gpg private key passphrase
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_RELEASES discord webhook to report release notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_WORKFLOWS discord webhook to report workflow notifications from github to discord
|
||||||
|
# secrets.DISCORD_WEBHOOK_CHAN_GITHUB_TVAPP2_UPDATES discord webhook to report activity notifications from github to discord
|
||||||
|
#
|
||||||
|
# @local these workflows can be tested locally through the use of `act`
|
||||||
|
# https://github.com/nektos/act
|
||||||
|
# Extract act to folder
|
||||||
|
# Add system env var with path to act.exe
|
||||||
|
# Run the commands:
|
||||||
|
# git pull https://github.com/username/repo
|
||||||
|
# act -W .github/workflows/labels-create.yml -P ubuntu-latest=catthehacker/ubuntu:full-22.04
|
||||||
|
# act -W .github/workflows/labels-create.yml -s TOKEN_CL=XXXXXXXXXX --pull=false
|
||||||
# #
|
# #
|
||||||
|
|
||||||
name: "📦 Release › Github"
|
name: '📦 Release › Github'
|
||||||
run-name: "📦 Release › Github"
|
run-name: '📦 Release › Github'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Triggers
|
# Triggers
|
||||||
@@ -22,57 +47,57 @@ on:
|
|||||||
# #
|
# #
|
||||||
|
|
||||||
PROJECT_NAME:
|
PROJECT_NAME:
|
||||||
description: "📦 Name of App"
|
description: '📦 Name of App'
|
||||||
required: true
|
required: true
|
||||||
default: 'tvapp2'
|
default: 'tvapp2'
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# ENABLE: the changelog generated in releases tab will only display single commits.
|
# true the changelog generated in releases tab will only display single commits.
|
||||||
# DISABLE: the changelog shows pull requests completed based on their labels
|
# false the changelog shows pull requests completed based on their labels
|
||||||
# #
|
# #
|
||||||
|
|
||||||
CHANGELOG_MODE_COMMIT:
|
CHANGELOG_MODE_COMMIT:
|
||||||
description: "📑 Use Commits Instead of PRs"
|
description: '📑 Use Commits Instead of PRs'
|
||||||
required: true
|
required: true
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# ENABLE: Will show all types of commits, including uncategorized
|
# true Will show all types of commits, including uncategorized
|
||||||
# DISABLE: WIll only show actions that have been categorized using the format
|
# false WIll only show actions that have been categorized using the format
|
||||||
# type(scope): description
|
# type(scope): description
|
||||||
# type: description
|
# type: description
|
||||||
# #
|
# #
|
||||||
|
|
||||||
SHOW_UNCATEGORIZED:
|
SHOW_UNCATEGORIZED:
|
||||||
description: "🗂️ Show Uncategorized Commits"
|
description: '🗂️ Show Uncategorized Commits'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# ENABLE: released version will be marked as pre-release
|
# true released version will be marked as a development build and will have the v1.x.x-development tag instead of -latest
|
||||||
# DISABLE: release version will be marked as stable / normal release
|
# false release version will be marked with -latest docker tag
|
||||||
# #
|
# #
|
||||||
|
|
||||||
PRERELEASE:
|
RC_RELEASE:
|
||||||
description: "🧪 Build RC (Pre-release)"
|
description: '🧪 Build RC (Pre-release)'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Release Candidate version number
|
# only needed if env variable `RC_ONLY` = true
|
||||||
# this will be added to the end of your released app in the releases page.
|
# sets the version number for the release candidate
|
||||||
# e.g: tvapp2-v1.0.0-rc.1
|
# e.g: noxenv-v1.0.0-rc.1
|
||||||
# #
|
# #
|
||||||
|
|
||||||
VERSION_RC:
|
RC_VERSION:
|
||||||
description: "🧪 RC (Pre-release) Ver (tvapp2-rc.v1)"
|
description: '🧪 RC (Pre-release) Ver (tvapp2-rc.v1)'
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
default: "1"
|
default: '1'
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# environment variables
|
# environment variables
|
||||||
@@ -80,12 +105,17 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
PROJECT_NAME: ${{ github.event.inputs.PROJECT_NAME || 'tvapp2' }}
|
PROJECT_NAME: ${{ github.event.inputs.PROJECT_NAME || 'tvapp2' }}
|
||||||
CHANGELOG_MODE_COMMIT: true
|
CHANGELOG_MODE_COMMIT: ${{ github.event.inputs.CHANGELOG_MODE_COMMIT || true }}
|
||||||
SHOW_UNCATEGORIZED: false
|
SHOW_UNCATEGORIZED: ${{ github.event.inputs.SHOW_UNCATEGORIZED || false }}
|
||||||
PRERELEASE: false
|
RC_RELEASE: ${{ github.event.inputs.RC_RELEASE || false }}
|
||||||
VERSION_RC: '1'
|
RC_VERSION: ${{ github.event.inputs.RC_VERSION || '1' }}
|
||||||
|
ASSIGN_USER: Aetherinox
|
||||||
BOT_NAME_1: EuropaServ
|
BOT_NAME_1: EuropaServ
|
||||||
|
BOT_NAME_2: BinaryServ
|
||||||
BOT_NAME_DEPENDABOT: dependabot[bot]
|
BOT_NAME_DEPENDABOT: dependabot[bot]
|
||||||
|
BOT_NAME_RENOVATE: renovate[bot]
|
||||||
|
GPG_KEY_BASE64: ${{ secrets.ADMINSERV_GPG_KEY_B64 }}
|
||||||
|
GPG_KEY_PASSPHRASE: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Jobs
|
# Jobs
|
||||||
@@ -112,7 +142,7 @@ jobs:
|
|||||||
# Initialize › Start
|
# Initialize › Start
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "✅ Start"
|
- name: '✅ Start'
|
||||||
id: task_initialize_start
|
id: task_initialize_start
|
||||||
run: |
|
run: |
|
||||||
echo "Starting build"
|
echo "Starting build"
|
||||||
@@ -134,24 +164,28 @@ jobs:
|
|||||||
# Initialize › Checkout
|
# Initialize › Checkout
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "☑️ Checkout"
|
- name: '☑️ Checkout'
|
||||||
id: task_initialize_checkout
|
id: task_initialize_checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Initialize › Get version from package.json VERSION value
|
# Initialize › Set › Package.json › Version
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "👁️🗨️ Package Version › Set"
|
- name: '👁️🗨️ Package Version › Set'
|
||||||
id: task_initialize_package_getversion
|
id: task_initialize_package_getversion
|
||||||
working-directory: ./tvapp2
|
working-directory: ./tvapp2
|
||||||
run: |
|
run: |
|
||||||
VER=$(cat package.json | jq -r '.version')
|
VER=$(cat package.json | jq -r '.version')
|
||||||
echo "PACKAGE_VERSION=$VER" >> $GITHUB_OUTPUT
|
echo "PACKAGE_VERSION=$VER" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: "👁️🗨️ Package Version › Get"
|
# #
|
||||||
|
# Initialize › Get › Package.json › Version
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '👁️🗨️ Package Version › Get'
|
||||||
id: task_initialize_package_version_get
|
id: task_initialize_package_version_get
|
||||||
run: |
|
run: |
|
||||||
echo "VERSION: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}"
|
echo "VERSION: ${{ steps.task_initialize_package_getversion.outputs.PACKAGE_VERSION }}"
|
||||||
@@ -175,16 +209,6 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
|
||||||
# Release › Checkout
|
|
||||||
# #
|
|
||||||
|
|
||||||
- name: "☑️ Checkout"
|
|
||||||
id: task_release_checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Release › Set Env Variables
|
# Release › Set Env Variables
|
||||||
# #
|
# #
|
||||||
@@ -193,17 +217,45 @@ jobs:
|
|||||||
🕛 Get Timestamp
|
🕛 Get Timestamp
|
||||||
id: task_release_label_set_timestamp
|
id: task_release_label_set_timestamp
|
||||||
run: |
|
run: |
|
||||||
|
echo "YEAR=$(date +'%Y')" >> $GITHUB_ENV
|
||||||
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
echo "NOW=$(date +'%m-%d-%Y %H:%M:%S')" >> $GITHUB_ENV
|
||||||
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
echo "NOW_SHORT=$(date +'%m-%d-%Y')" >> $GITHUB_ENV
|
||||||
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
echo "NOW_LONG=$(date +'%m-%d-%Y %H:%M')" >> $GITHUB_ENV
|
||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Checkout
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '☑️ Checkout'
|
||||||
|
id: task_release_checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Start
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
✅ Start
|
||||||
|
id: task_release_start
|
||||||
|
run: |
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
echo " Starting Documentation Build script"
|
||||||
|
echo " Runner .............. ${{ runner.name }}"
|
||||||
|
echo " Workflow ............ ${{ github.workflow }} (#${{ github.workflow_ref }})"
|
||||||
|
echo " Run Number .......... #${{ github.run_number }}"
|
||||||
|
echo " Run ID .............. https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
||||||
|
echo " Triggered By ........ ${{ github.actor }}"
|
||||||
|
echo " Time ................ ${{ env.NOW_LONG }}"
|
||||||
|
echo "―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Release › Print Version Debug
|
# Release › Print Version Debug
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🪪 Test Next Job Version"
|
- name: '🪪 Test Next Job Version'
|
||||||
id: task_release_debug_print_ver
|
|
||||||
run: |
|
run: |
|
||||||
echo "VERSION: ${{ env.PACKAGE_VERSION }}"
|
echo "VERSION: ${{ env.PACKAGE_VERSION }}"
|
||||||
|
|
||||||
@@ -211,11 +263,11 @@ jobs:
|
|||||||
# Release › Install package via NPM
|
# Release › Install package via NPM
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🪪 NPM › Install"
|
- name: '🪪 NPM › Install & Lint'
|
||||||
id: task_release_npm_install
|
|
||||||
working-directory: ./tvapp2
|
working-directory: ./tvapp2
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
|
npm run lint
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.SELF_TOKEN_CL }}
|
NODE_AUTH_TOKEN: ${{ secrets.SELF_TOKEN_CL }}
|
||||||
|
|
||||||
@@ -223,71 +275,77 @@ jobs:
|
|||||||
# Release › Execute npm generate so that a uuid and guid can be created
|
# Release › Execute npm generate so that a uuid and guid can be created
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🪪 Generate IDs"
|
- name: '🪪 Generate IDs'
|
||||||
id: task_release_npm_env_generate
|
|
||||||
working-directory: ./tvapp2
|
working-directory: ./tvapp2
|
||||||
run: |
|
run: |
|
||||||
npm run root:generate
|
npm run root:generate
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# .ENV › Get
|
# Release › .ENV › Get
|
||||||
# Get guid and uuid from env variable generated by npm
|
# Get guid and uuid from env variable generated by npm
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🪪 .ENV › Get"
|
- name: '🪪 .ENV › Get'
|
||||||
id: task_release_dotenv_get
|
id: task_release_dotenv_get
|
||||||
uses: falti/dotenv-action@v1
|
uses: falti/dotenv-action@v1
|
||||||
with:
|
with:
|
||||||
path: "./tvapp2/.env"
|
path: "./tvapp2/.env"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# .ENV › Print (Debug)
|
# Release › .ENV › Print (Debug)
|
||||||
# Show guid and uuid from env variable generated by npm
|
# Show guid and uuid from env variable generated by npm
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🪪 .ENV › Read"
|
- name: '🪪 .ENV › Read'
|
||||||
id: task_dotenv_debug_print
|
|
||||||
run: |
|
run: |
|
||||||
echo "GUID: ${{ steps.task_release_dotenv_get.outputs.GUID }}"
|
echo "GUID: ${{ steps.task_release_dotenv_get.outputs.GUID }}"
|
||||||
echo "UUID: ${{ steps.task_release_dotenv_get.outputs.UUID }}"
|
echo "UUID: ${{ steps.task_release_dotenv_get.outputs.UUID }}"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Build Project & Create Zip
|
# Release › Build › Stable
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🔨 Build › Stable ( ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip )"
|
- name: '🔨 Build › Stable › ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip'
|
||||||
id: task_release_build_st
|
if: |
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
|
startsWith( inputs.RC_RELEASE, false ) ||
|
||||||
|
startsWith( env.RC_RELEASE, false )
|
||||||
run: |
|
run: |
|
||||||
echo Building STABLE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
echo Building STABLE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
||||||
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
|
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
|
||||||
|
|
||||||
echo Building STABLE Package ${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip
|
echo Building STABLE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip
|
||||||
zip -r ${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip docker-compose.yml README.md LICENSE
|
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip docker-compose.yml README.md LICENSE
|
||||||
env:
|
ls
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
|
||||||
|
|
||||||
- name: "🔨 Build › RC ( ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip )"
|
|
||||||
id: task_release_build_rc
|
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
|
|
||||||
run: |
|
|
||||||
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
|
|
||||||
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
|
|
||||||
|
|
||||||
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip
|
|
||||||
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip docker-compose.yml README.md LICENSE
|
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Tag ]: Pre Create
|
# Release › Build › Release Candidate
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🔨 Build › Release Candidate › ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip'
|
||||||
|
id: task_release_build_rc
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, true ) ||
|
||||||
|
startsWith( env.RC_RELEASE, true )
|
||||||
|
run: |
|
||||||
|
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip
|
||||||
|
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip Dockerfile Dockerfile.aarch64 docker-compose.yml docker-entrypoint.sh root/ tvapp2/package.json README.md LICENSE
|
||||||
|
|
||||||
|
echo Building PRE-RELEASE Package ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}-docker-compose.zip
|
||||||
|
zip -r ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}-docker-compose.zip docker-compose.yml README.md LICENSE
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Tag › Pre Create
|
||||||
#
|
#
|
||||||
# in order to use the changelog github action, you must pre-create the tag otherwise
|
# in order to use the changelog github action, you must pre-create the tag otherwise
|
||||||
# the changelog action will have no idea what tag you are going to be creating and
|
# the changelog action will have no idea what tag you are going to be creating and
|
||||||
# the list of commits will not be for the correct release.
|
# the list of commits will not be for the correct release.
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🔖 Tag › Pre Create ${{ env.PACKAGE_VERSION }}"
|
- name: '🔖 Tag › Pre Create ${{ env.PACKAGE_VERSION }}'
|
||||||
id: task_release_tag_create
|
id: task_release_tag_create
|
||||||
uses: rickstaa/action-create-tag@v1
|
uses: rickstaa/action-create-tag@v1
|
||||||
with:
|
with:
|
||||||
@@ -298,64 +356,124 @@ jobs:
|
|||||||
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
|
gpg_passphrase: ${{ secrets.ADMINSERV_GPG_PASSPHRASE }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Tag ]: Confirm
|
# Release › Tag › Confirm
|
||||||
#
|
#
|
||||||
# check if tag already exists
|
# check if tag already exists
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🔖 Tag › Confirm ${{ env.PACKAGE_VERSION }}"
|
- name: '🔖 Tag › Confirm ${{ env.PACKAGE_VERSION }}'
|
||||||
id: task_release_tag_get
|
|
||||||
run: |
|
run: |
|
||||||
echo "Tag already present: ${{ env.TAG_EXISTS }}"
|
echo "Tag already present: ${{ env.TAG_EXISTS }}"
|
||||||
echo "Tag already present: ${{ steps.task_release_tag_create.outputs.tag_exists }}"
|
echo "Tag already present: ${{ steps.task_release_tag_create.outputs.tag_exists }}"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Checksum › Generate
|
# Release › GPG › Import Key (No Passphrase)
|
||||||
|
#
|
||||||
|
# requires your GPG private key, converted to base64 binary .gpg (not armored .asc)
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🆔 Checksum › Stable"
|
- name: '🪪 GPG › Import Signing Key › W/o Passphrase'
|
||||||
|
if: env.GPG_KEY_BASE64 != '' && env.GPG_KEY_PASSPHRASE == ''
|
||||||
|
run: |
|
||||||
|
echo $GPG_KEY_BASE64 | base64 -di | gpg --import
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › GPG › Import Key (With Passphrase)
|
||||||
|
#
|
||||||
|
# requires your GPG private key, converted to base64 binary .gpg (not armored .asc)
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🪪 GPG › Import Signing Key › w/ Passphrase'
|
||||||
|
if: env.GPG_KEY_BASE64 != '' && env.GPG_KEY_PASSPHRASE != ''
|
||||||
|
run: |
|
||||||
|
echo "$GPG_KEY_BASE64" | base64 -di > /tmp/signing-key.gpg
|
||||||
|
echo "$GPG_KEY_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg
|
||||||
|
(echo "$GPG_KEY_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Checksum › Stable
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🆔 Checksum › Stable'
|
||||||
id: task_release_checksum_st_set
|
id: task_release_checksum_st_set
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, false ) ||
|
||||||
|
startsWith( env.RC_RELEASE, false )
|
||||||
run: |
|
run: |
|
||||||
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip"
|
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip"
|
||||||
sha256="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
|
|
||||||
shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
|
# get sha1 and sha256 for .zip and .gz files
|
||||||
|
find . -maxdepth 1 \( -name '*.zip' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha1sum | gpg --digest-algo sha256 --clearsign > sha1sum.txt.asc
|
||||||
|
find . -maxdepth 1 \( -name '*.zip' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha256sum | gpg --digest-algo sha256 --clearsign > sha256sum.txt.asc
|
||||||
|
|
||||||
|
# get sha1sum; assign to variable
|
||||||
|
sha1sum="$(shasum --algorithm 1 ${filename_zip} | awk '{ print $1 }')"
|
||||||
|
echo "SHA1SUM=${sha1sum}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# get sha256sum; assign to variable
|
||||||
|
sha256sum="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
|
||||||
|
echo "SHA256SUM=${sha256sum}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# no longer needed, replaced by find . command
|
||||||
|
# shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
|
||||||
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
|
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
|
||||||
echo "SHA256SUM=${sha256}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip"
|
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip"
|
||||||
sha256_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
|
sha256sum_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
|
||||||
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
|
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: "🆔 Checksum › RC"
|
gpg --batch --yes --quiet --armor --detach-sig --sign --output sha256sum.sig sha256sum.txt.asc
|
||||||
|
gpg --batch --yes --quiet --armor --detach-sig --sign --output sha1sum.sig sha1sum.txt.asc
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Checksum › Release Candidate
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🆔 Checksum › Release Candidate'
|
||||||
id: task_release_checksum_rc_set
|
id: task_release_checksum_rc_set
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, true ) ||
|
||||||
|
startsWith( env.RC_RELEASE, true )
|
||||||
run: |
|
run: |
|
||||||
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip"
|
filename_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip"
|
||||||
sha256="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
|
|
||||||
shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
|
|
||||||
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
|
|
||||||
echo "SHA256SUM=${sha256}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip"
|
# get sha1 and sha256 for .zip and .gz files
|
||||||
|
find . -maxdepth 1 \( -name '*.zip' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha1sum | gpg --digest-algo sha256 --clearsign > sha1sum.txt.asc
|
||||||
|
find . -maxdepth 1 \( -name '*.zip' -o -name '*.gz' \) -printf '%P\n' | xargs -r sha256sum | gpg --digest-algo sha256 --clearsign > sha256sum.txt.asc
|
||||||
|
|
||||||
|
# get sha1sum; assign to variable
|
||||||
|
sha1sum="$(shasum --algorithm 1 ${filename_zip} | awk '{ print $1 }')"
|
||||||
|
echo "SHA1SUM=${sha1sum}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# get sha256sum; assign to variable
|
||||||
|
sha256sum="$(shasum --algorithm 256 ${filename_zip} | awk '{ print $1 }')"
|
||||||
|
echo "SHA256SUM=${sha256sum}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# no longer needed, replaced by find . command
|
||||||
|
# shasum --algorithm 256 ${filename_zip} > SHA256SUMS.txt
|
||||||
|
echo "FILE_ZIP=${filename_zip}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
filename_compose_zip="${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}-docker-compose.zip"
|
||||||
sha256_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
|
sha256_compose="$(shasum --algorithm 256 ${filename_compose_zip} | awk '{ print $1 }')"
|
||||||
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
|
echo "FILE_COMPOSE_ZIP=${filename_compose_zip}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
gpg --batch --yes --quiet --armor --detach-sig --sign --output sha256sum.sig sha256sum.txt.asc
|
||||||
|
gpg --batch --yes --quiet --armor --detach-sig --sign --output sha1sum.sig sha1sum.txt.asc
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Checksum › Print
|
# Release › Checksum › Print
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🆔 Checksum › Print"
|
- name: '🆔 Checksum › Print'
|
||||||
id: task_release_checksum_st_get
|
|
||||||
run: |
|
run: |
|
||||||
echo ${{ env.SHA256SUM }}
|
echo SHA1SUM ............... ${{ env.SHA1SUM }}
|
||||||
|
echo SHA256SUM ............. ${{ env.SHA256SUM }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Contributor Images
|
# Release › Contributor Images
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🥸 Contributors › Generate"
|
- name: '🥸 Contributors › Generate'
|
||||||
id: task_release_contribs_generate
|
|
||||||
uses: jaywcjlove/github-action-contributors@main
|
uses: jaywcjlove/github-action-contributors@main
|
||||||
with:
|
with:
|
||||||
filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
|
filter-author: (renovate\[bot\]|renovate-bot|dependabot\[bot\])
|
||||||
@@ -363,44 +481,35 @@ jobs:
|
|||||||
avatarSize: 42
|
avatarSize: 42
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Checksum › Add to ZIP file
|
# Release › Changelog › Generate Tags
|
||||||
# #
|
|
||||||
|
|
||||||
- name: "📦 Zip › Add Checksum › Stable"
|
|
||||||
id: task_release_zip_st
|
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
|
|
||||||
run: |
|
|
||||||
echo Zipping STABLE Package .zip ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
|
||||||
zip -jr ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip SHA256SUMS.txt
|
|
||||||
ls
|
|
||||||
|
|
||||||
- name: "📦 Zip › Add Checksum › RC"
|
|
||||||
id: task_release_zip_rc
|
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
|
|
||||||
run: |
|
|
||||||
echo Zipping PRE-RELEASE Package .zip ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
|
|
||||||
zip -jr ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip SHA256SUMS.txt
|
|
||||||
ls
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Changelog › Generate
|
|
||||||
#
|
#
|
||||||
# generates a changelog from the github api. requires a PREVIOUS_TAG in order to figure
|
# generates a changelog from the github api. requires a TAG_LAST in order to figure
|
||||||
# out the changes made between the two versions.
|
# out the changes made between the two versions.
|
||||||
#
|
#
|
||||||
# outputs:
|
# outputs:
|
||||||
# ${{ steps.changelog.outputs.changelog }}
|
# ${{ steps.changelog.outputs.changelog }}
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "📝 Changelog › Pre Setup (Categorized Commits)"
|
- name: '📝 Changelog › Pre Setup (Categorized Commits)'
|
||||||
id: task_release_changelog_categorized_sha_set
|
|
||||||
run: |
|
run: |
|
||||||
echo "TAG_LAST=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
|
echo "TAG_LAST=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
|
||||||
echo "COMMIT_LAST=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
echo "COMMIT_LAST=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: "📝 Changelog › Build (Categorized)"
|
# #
|
||||||
|
# Release › Changelog › Build (Categorized)
|
||||||
|
#
|
||||||
|
# generates a changelog from the github api. requires a TAG_LAST in order to figure
|
||||||
|
# out the changes made between the two versions.
|
||||||
|
#
|
||||||
|
# outputs:
|
||||||
|
# ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '📝 Changelog › Build (Categorized)'
|
||||||
id: task_release_changelog_categorized
|
id: task_release_changelog_categorized
|
||||||
if: ${{ startsWith( inputs.SHOW_UNCATEGORIZED, false ) }}
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, false ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, false )
|
||||||
uses: mikepenz/release-changelog-builder-action@v5
|
uses: mikepenz/release-changelog-builder-action@v5
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.ADMINSERV_TOKEN }}
|
token: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
@@ -408,7 +517,7 @@ jobs:
|
|||||||
#toTag: "${{ github.ref }}"
|
#toTag: "${{ github.ref }}"
|
||||||
configuration: ".github/changelog-configuration.json"
|
configuration: ".github/changelog-configuration.json"
|
||||||
ignorePreReleases: false
|
ignorePreReleases: false
|
||||||
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT }}
|
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT || env.CHANGELOG_MODE_COMMIT }}
|
||||||
fetchReleaseInformation: true
|
fetchReleaseInformation: true
|
||||||
fetchViaCommits: true
|
fetchViaCommits: true
|
||||||
configurationJson: |
|
configurationJson: |
|
||||||
@@ -419,14 +528,24 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
|
# Release › Changelog › Build (Uncategorized)
|
||||||
|
#
|
||||||
|
# generates a changelog from the github api. requires a TAG_LAST in order to figure
|
||||||
|
# out the changes made between the two versions.
|
||||||
|
#
|
||||||
|
# outputs:
|
||||||
|
# ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
#
|
||||||
# shows only categorized commits using the commit standards
|
# shows only categorized commits using the commit standards
|
||||||
# type(scope): description
|
# type(scope): description
|
||||||
# type: description
|
# type: description
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "📝 Changelog › Build (Uncategorized)"
|
- name: '📝 Changelog › Build (Uncategorized)'
|
||||||
id: task_release_changelog_uncategorized
|
id: task_release_changelog_uncategorized
|
||||||
if: ${{ startsWith( inputs.SHOW_UNCATEGORIZED, true ) }}
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, true ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, true )
|
||||||
uses: mikepenz/release-changelog-builder-action@v5
|
uses: mikepenz/release-changelog-builder-action@v5
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.ADMINSERV_TOKEN }}
|
token: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
@@ -434,7 +553,7 @@ jobs:
|
|||||||
#toTag: "${{ github.ref }}"
|
#toTag: "${{ github.ref }}"
|
||||||
configuration: ".github/changelog-configuration.json"
|
configuration: ".github/changelog-configuration.json"
|
||||||
ignorePreReleases: false
|
ignorePreReleases: false
|
||||||
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT }}
|
commitMode: ${{ inputs.CHANGELOG_MODE_COMMIT || env.CHANGELOG_MODE_COMMIT }}
|
||||||
fetchReleaseInformation: true
|
fetchReleaseInformation: true
|
||||||
fetchViaCommits: true
|
fetchViaCommits: true
|
||||||
configurationJson: |
|
configurationJson: |
|
||||||
@@ -445,21 +564,95 @@ jobs:
|
|||||||
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Changelog › Fetch
|
# Release › Changelog › Convert step into ENV
|
||||||
|
#
|
||||||
|
# This is a requirement in order for the action mikepenz/release-changelog-builder-action@v5 to work properly.
|
||||||
|
# If you use special characters like quotes and tildes in your push comments, bash will have no way of knowing
|
||||||
|
# if it's part of the changelog, or code itself.
|
||||||
|
#
|
||||||
|
# By converting the step into an env var, we quote the text, and it fixes the issue.
|
||||||
|
#
|
||||||
|
# For every step that you need to print the changelog text, first define the env var
|
||||||
|
# env:
|
||||||
|
# CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
#
|
||||||
|
# Then you can call the changelog in the body / run command with
|
||||||
|
# echo "$CHANGELOG_CATEGORIZED"
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "📝 Changelog › Print (Categorized)"
|
- name: '🙊 Changelog › Step to Env › Categorized'
|
||||||
if: ${{ startsWith( inputs.SHOW_UNCATEGORIZED, false ) }}
|
id: task_release_changelog_escape_categorized
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, false ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, false )
|
||||||
|
env:
|
||||||
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
run: |
|
run: |
|
||||||
echo "${{ steps.task_release_changelog_categorized.outputs.changelog }}"
|
echo "$CHANGELOG_CATEGORIZED"
|
||||||
|
|
||||||
- name: "📝 Changelog › Print (Uncategorized)"
|
- name: '🙊 Changelog › Step to Env › Uncategorized'
|
||||||
if: ${{ startsWith( inputs.SHOW_UNCATEGORIZED, true ) }}
|
id: task_release_changelog_escape_uncategorized
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, true ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, true )
|
||||||
|
env:
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
run: |
|
run: |
|
||||||
echo "${{ steps.task_release_changelog_uncategorized.outputs.changelog }}"
|
echo "$CHANGELOG_UNCATEGORIZED"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# [ Release ]: Post Release
|
# Release › Verbose › List Tree
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Verbose › Tree Listing'
|
||||||
|
id: task_release_verbose_tree
|
||||||
|
run: |
|
||||||
|
tree
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Verbose › Changelog › Print Categorized
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Verbose › Changelog › Categorized'
|
||||||
|
id: task_release_changelog_verbose_categorized
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, false ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, false )
|
||||||
|
env:
|
||||||
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
run: |
|
||||||
|
echo
|
||||||
|
echo "---- CHANGELOG [ Categorized ] -----------------------------------------------"
|
||||||
|
echo
|
||||||
|
echo "$CHANGELOG_CATEGORIZED"
|
||||||
|
echo
|
||||||
|
echo "---- CHANGELOG ---------------------------------------------------------------"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Verbose › Changelog › Print Uncategorized
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '⚙️ Verbose › Changelog › Uncategorized'
|
||||||
|
id: task_release_changelog_verbose_uncategorized
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.SHOW_UNCATEGORIZED, true ) ||
|
||||||
|
startsWith( env.SHOW_UNCATEGORIZED, true )
|
||||||
|
env:
|
||||||
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
run: |
|
||||||
|
echo
|
||||||
|
echo "---- CHANGELOG [ Uncategorized ] ---------------------------------------------"
|
||||||
|
echo
|
||||||
|
echo "$CHANGELOG_UNCATEGORIZED"
|
||||||
|
echo
|
||||||
|
echo "---- CHANGELOG ---------------------------------------------------------------"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Post Release (Stable)
|
||||||
#
|
#
|
||||||
# outputs:
|
# outputs:
|
||||||
# [RELEASE ID]:
|
# [RELEASE ID]:
|
||||||
@@ -467,11 +660,15 @@ jobs:
|
|||||||
# ${{ steps.task_release_bundle_st.outputs.id
|
# ${{ steps.task_release_bundle_st.outputs.id
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🏳️ Post › Stable"
|
- name: '🏳️ Post › Stable'
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, false ) }}
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
id: task_release_bundle_st
|
id: task_release_bundle_st
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, false ) ||
|
||||||
|
startsWith( env.RC_RELEASE, false )
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
env:
|
env:
|
||||||
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
token: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
@@ -481,20 +678,36 @@ jobs:
|
|||||||
draft: false
|
draft: false
|
||||||
generate_release_notes: false
|
generate_release_notes: false
|
||||||
files: |
|
files: |
|
||||||
${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-docker-compose.zip
|
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-docker-compose.zip
|
||||||
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
||||||
SHA256SUMS.txt
|
sha1sum.txt.asc
|
||||||
|
sha256sum.txt.asc
|
||||||
|
sha256sum.sig
|
||||||
|
sha1sum.sig
|
||||||
prerelease: false
|
prerelease: false
|
||||||
body: |
|
body: |
|
||||||
${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
|
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
|
||||||
|
|
||||||
- name: "🏳️ Post › Release Candidate"
|
# #
|
||||||
if: ${{ startsWith( inputs.PRERELEASE, true ) }}
|
# Release › Post Release (Release Candidate)
|
||||||
uses: softprops/action-gh-release@v2
|
#
|
||||||
|
# outputs:
|
||||||
|
# [RELEASE ID]:
|
||||||
|
# ${{ steps.task_release_bundle_rc.outputs.id
|
||||||
|
# ${{ steps.task_release_bundle_st.outputs.id
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: '🏳️ Post › Release Candidate'
|
||||||
id: task_release_bundle_rc
|
id: task_release_bundle_rc
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, true ) ||
|
||||||
|
startsWith( env.RC_RELEASE, true )
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN }}
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.ADMINSERV_TOKEN_CL }}
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.ADMINSERV_TOKEN }}
|
token: ${{ secrets.ADMINSERV_TOKEN }}
|
||||||
name: v${{ env.PACKAGE_VERSION }}
|
name: v${{ env.PACKAGE_VERSION }}
|
||||||
@@ -503,9 +716,12 @@ jobs:
|
|||||||
draft: false
|
draft: false
|
||||||
generate_release_notes: false
|
generate_release_notes: false
|
||||||
files: |
|
files: |
|
||||||
${{ env.PROJECT_NAME }}-v${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}-docker-compose.zip
|
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}-docker-compose.zip
|
||||||
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.VERSION_RC }}.zip
|
${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip
|
||||||
SHA256SUMS.txt
|
sha1sum.txt.asc
|
||||||
|
sha256sum.txt.asc
|
||||||
|
sha256sum.sig
|
||||||
|
sha1sum.sig
|
||||||
prerelease: false
|
prerelease: false
|
||||||
body: |
|
body: |
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
@@ -515,17 +731,27 @@ jobs:
|
|||||||
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
|
${{ steps.task_release_changelog_uncategorized.outputs.changelog }}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Print Status
|
# Release › Print Status
|
||||||
|
#
|
||||||
|
# For every step that you need to print the changelog text, first define the env var
|
||||||
|
# env:
|
||||||
|
# CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
#
|
||||||
|
# Then you can call the changelog in the body / run command with
|
||||||
|
# echo "$CHANGELOG_CATEGORIZED"
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🎛️ Status › Print"
|
- name: "🎛️ Status › Print"
|
||||||
id: task_release_status_print
|
id: task_release_status_print
|
||||||
|
env:
|
||||||
|
CHANGELOG_CATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
|
CHANGELOG_UNCATEGORIZED: ${{ steps.task_release_changelog_categorized.outputs.changelog }}
|
||||||
run: |
|
run: |
|
||||||
echo "Printing Variables"
|
echo "Printing Variables"
|
||||||
echo
|
echo
|
||||||
echo "---- CHANGELOG ---------------------------------------------------------------"
|
echo "---- CHANGELOG ---------------------------------------------------------------"
|
||||||
echo "${{ steps.task_release_changelog_categorized.outputs.changelog }}"
|
echo "$CHANGELOG_CATEGORIZED"
|
||||||
echo "${{ steps.task_changelog_uncategorized.outputs.changelog }}"
|
echo "$CHANGELOG_UNCATEGORIZED"
|
||||||
echo "---- CHANGELOG ---------------------------------------------------------------"
|
echo "---- CHANGELOG ---------------------------------------------------------------"
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
@@ -539,19 +765,37 @@ jobs:
|
|||||||
echo "---- CHANGELOG ---------------------------------------------------------------"
|
echo "---- CHANGELOG ---------------------------------------------------------------"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Upload artifacts > release files
|
# Release › Upload Artifacts › Release Files › Stable
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
📋 Upload Artifacts › ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
📋 Upload Artifacts › Stable › ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
||||||
id: task_release_artifact
|
id: task_release_artifact_stable
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: always()
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, false ) ||
|
||||||
|
startsWith( env.RC_RELEASE, false )
|
||||||
with:
|
with:
|
||||||
name: "${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}"
|
name: "${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}"
|
||||||
path: ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
path: ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Release › Upload Artifacts › Release Files › Release Candidate
|
||||||
|
# #
|
||||||
|
|
||||||
|
- name: >-
|
||||||
|
📋 Upload Artifacts › RC › ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}.zip
|
||||||
|
id: task_release_artifact_rc
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: |
|
||||||
|
startsWith( inputs.RC_RELEASE, true ) ||
|
||||||
|
startsWith( env.RC_RELEASE, true )
|
||||||
|
with:
|
||||||
|
name: "${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}"
|
||||||
|
path: ${{ env.PROJECT_NAME }}-${{ env.PACKAGE_VERSION }}-rc.${{ inputs.RC_VERSION }}.zip
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job › Complete
|
# Job › Complete
|
||||||
# #
|
# #
|
||||||
@@ -568,7 +812,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job › Complete › Download Artifacts
|
# Complete › Download Artifacts
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "📁 Download › Saved Artifacts"
|
- name: "📁 Download › Saved Artifacts"
|
||||||
@@ -576,7 +820,7 @@ jobs:
|
|||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job › Complete › Get publish timestamp
|
# Complete › Get publish timestamp
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: >-
|
- name: >-
|
||||||
@@ -589,7 +833,7 @@ jobs:
|
|||||||
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
echo "NOW_DOCKER_LABEL=$(date +'%Y%m%d')" >> $GITHUB_ENV
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job > Complete > Set ENVs
|
# Complete › Set ENVs
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🕛 Get Env Vars"
|
- name: "🕛 Get Env Vars"
|
||||||
@@ -602,7 +846,7 @@ jobs:
|
|||||||
echo "SHA_STABLE=${release_stable_sha256}" >> $GITHUB_ENV
|
echo "SHA_STABLE=${release_stable_sha256}" >> $GITHUB_ENV
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Job › Complete › Summary of publish
|
# Complete › Summary of publish
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- name: "🆗 Completed: ${{ env.NOW }}"
|
- name: "🆗 Completed: ${{ env.NOW }}"
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
|||||||
# #
|
# #
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
|
tvapp2/node_modules/
|
||||||
jspm_packages/
|
jspm_packages/
|
||||||
|
|
||||||
# #
|
# #
|
||||||
|
|||||||
58
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
|
|
||||||
|
- Using welcoming and inclusive language
|
||||||
|
- Being respectful of differing viewpoints and experiences
|
||||||
|
- Gracefully accepting constructive criticism
|
||||||
|
- Focusing on what is best for the community
|
||||||
|
- Showing empathy towards other community members
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
- The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
|
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
- Public or private harassment
|
||||||
|
- Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
|
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at `thebinaryninja [at] proton [dot] me`. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [📄 Contributor Covenant][homepage], version 2.1, available at [https://contributor-covenant.org/version/2/1/][version]
|
||||||
|
|
||||||
|
[homepage]: http://contributor-covenant.org
|
||||||
|
[version]: https://www.contributor-covenant.org/version/2/1/
|
||||||
643
CONTRIBUTING.md
Normal file
@@ -0,0 +1,643 @@
|
|||||||
|
<div align="center">
|
||||||
|
<h6>Contribution Guidelines for BinaryNinja Applications</h6>
|
||||||
|
<h1>♾️ Contributing ♾️</h1>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
[![Version][github-version-img]][github-version-uri]
|
||||||
|
[![Downloads][github-downloads-img]][github-downloads-uri]
|
||||||
|
[![Size][github-size-img]][github-size-img]
|
||||||
|
[![Last Commit][github-commit-img]][github-commit-img]
|
||||||
|
[![Contributors][contribs-all-img]](#contributors-)
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Below are a list of ways that you can help contribute to this project, as well as policies and guides that explain how to get started.
|
||||||
|
|
||||||
|
Please review everything on this page before you submit your contribution.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
- [About](#about)
|
||||||
|
- [Issues, Bugs, Ideas](#issues-bugs-ideas)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [Before Submitting Pull Requests](#before-submitting-pull-requests)
|
||||||
|
- [Conventional Commit Specification](#conventional-commit-specification)
|
||||||
|
- [Types](#types)
|
||||||
|
- [Example 1:](#example-1)
|
||||||
|
- [Example 2:](#example-2)
|
||||||
|
- [Committing](#committing)
|
||||||
|
- [Languages](#languages)
|
||||||
|
- [Python](#python)
|
||||||
|
- [Indentation](#indentation)
|
||||||
|
- [Line Length](#line-length)
|
||||||
|
- [Blank Lines](#blank-lines)
|
||||||
|
- [Imports](#imports)
|
||||||
|
- [Commenting](#commenting)
|
||||||
|
- [Casing](#casing)
|
||||||
|
- [NodeJS](#nodejs)
|
||||||
|
- [Prettier](#prettier)
|
||||||
|
- [ESLint](#eslint)
|
||||||
|
- [v9 \& Newer (Config)](#v9--newer-config)
|
||||||
|
- [v8 \& Older (Config)](#v8--older-config)
|
||||||
|
- [Packages](#packages)
|
||||||
|
- [Indentation](#indentation-1)
|
||||||
|
- [Style](#style)
|
||||||
|
- [Line Length](#line-length-1)
|
||||||
|
- [Commenting](#commenting-1)
|
||||||
|
- [Casing](#casing-1)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Issues, Bugs, Ideas
|
||||||
|
|
||||||
|
Stuff happens, and sometimes as best as we try, there may be issues within this project that we are unaware of. That is the great thing about open-source; anyone can use the program and contribute to making it better.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/thebinaryninja/tvapp2/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/thebinaryninja/tvapp2/issues) and ensure nobody else has already submitted it.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/thebinaryninja/tvapp2/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as:
|
||||||
|
- Bug report
|
||||||
|
- Feature Suggestion
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
When writing a new submission; ensure you fill out any of the questions asked of you. If you do not provide enough information, we cannot help. Be as detailed as possible, and provide any logs or screenshots you may have to help us better understand what you mean. Failure to fill out the submission properly may result in it being closed without a response.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you are submitting a bug report:
|
||||||
|
|
||||||
|
- Explain the issue
|
||||||
|
- Describe how you expect for a feature to work, and what you're seeing instead of what you expected.
|
||||||
|
- List possible options for a resolution or insight
|
||||||
|
- Provide screenshots, logs, or anything else that can visually help track down the issue.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[![Submit Issue][btn-github-submit-img]][btn-github-submit-uri]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you are looking to contribute to this project by actually submit your own code; please review this section completely. There is important information and policies provided below that you must follow for your pull request to get accepted.
|
||||||
|
|
||||||
|
The source is here for everyone to collectively share and collaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty.
|
||||||
|
|
||||||
|
All contributions are made via pull requests. To create a pull request, you need a GitHub account. If you are unclear on this process, see [GitHub's documentation on forking and pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Pull requests should be targeted at the master branch.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Before Submitting Pull Requests
|
||||||
|
|
||||||
|
- Follow the repository's code formatting conventions (see below);
|
||||||
|
- Include tests that prove that the change works as intended and does not add regressions;
|
||||||
|
- Document the changes in the code and/or the project's documentation;
|
||||||
|
- Your PR must pass the CI pipeline;
|
||||||
|
- When submitting your Pull Request, use one of the following branches:
|
||||||
|
- For bug fixes: `main` branch
|
||||||
|
- For features & functionality: `development` branch
|
||||||
|
- Include a proper git commit message following the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification).
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you have completed the above tasks, the pull request is ready to be reviewed and your pull request's label will be changed to "Ready for Review". At this point, a human will need to step in and manually verify your submission.
|
||||||
|
|
||||||
|
Reviewers will approve the pull request once they are satisfied with the patch it will be merged.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Conventional Commit Specification
|
||||||
|
|
||||||
|
When committing your changes, we require you to follow the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>[(optional <scope>)]: <description>
|
||||||
|
|
||||||
|
[optional <body>]
|
||||||
|
|
||||||
|
[optional <footer(s)>]
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### Types
|
||||||
|
|
||||||
|
Our repositories make use of the following commit tags:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `feat` | Introduce new feature |
|
||||||
|
| `fix` | Bug fix |
|
||||||
|
| `chore` | Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintenance purposes.<br/>E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file |
|
||||||
|
| `revert` | Revert a previous commit |
|
||||||
|
| `style` | Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code<br />E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc) |
|
||||||
|
| `docs` | Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator. <br/>E.g: documentation, readme.md or markdown |
|
||||||
|
| `build` | Changes to the build / compilation / packaging process or auxiliary tools such as doc generation<br />E.g: create new build tasks, update release script, etc. |
|
||||||
|
| `refactor` | Change to production code that leads to no behavior difference,<br/>E.g: split files, rename variables, rename package, improve code style, etc. |
|
||||||
|
| `test` | Add or refactor tests, no production code change. Changes the suite of automated tests for the app. |
|
||||||
|
| `ci` | Changes related to Continuous Integration (usually `yml` and other configuration files). |
|
||||||
|
| `perf` | Performance improvement of algorithms or execution time of the app. Does not change an existing feature. |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Example 1:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(core): bug affecting menu [#22]
|
||||||
|
^───^────^ ^────────────────^ ^───^
|
||||||
|
| | | |
|
||||||
|
| | | └───⫸ (ISSUE): Reference issue ID
|
||||||
|
│ │ │
|
||||||
|
│ │ └──────────────────────⫸ (DESC): Summary in present tense. Use lower case not title case!
|
||||||
|
│ │
|
||||||
|
│ └──────────────────────────────⫸ (SCOPE): The package(s) that this change affects
|
||||||
|
│
|
||||||
|
└──────────────────────────────────⫸ (TYPE): See list above
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Example 2:
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <short summary> [issue]
|
||||||
|
| | | |
|
||||||
|
| | | └─⫸ Reference issue id (optional)
|
||||||
|
│ │ │
|
||||||
|
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
||||||
|
│ │
|
||||||
|
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||||
|
│ elements|forms|http|language-service|localize|platform-browser|
|
||||||
|
│ platform-browser-dynamic|platform-server|router|service-worker|
|
||||||
|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
|
||||||
|
│ devtools....
|
||||||
|
│
|
||||||
|
└─⫸ Commit Type: build|ci|doc|docs|feat|fix|perf|refactor|test
|
||||||
|
website|chore|style|type|revert|deprecate
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Committing
|
||||||
|
|
||||||
|
If you are pushing a commit which addresses a submitted issue, reference your issue at the end of the commit message. You may also optionally add the major issue to the end of your commit body.
|
||||||
|
|
||||||
|
References should be on their own line, following the word `Ref` or `Refs`
|
||||||
|
|
||||||
|
```
|
||||||
|
Title: fix(core): fix error message displayed to users. [#22]
|
||||||
|
Description: The description of your commit
|
||||||
|
|
||||||
|
Ref: #22, #34, #37
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Languages
|
||||||
|
|
||||||
|
The formatting of code greatly depends on the language being used for this repository. We provide various different languages below as this guide is utilized across multiple repositories.
|
||||||
|
|
||||||
|
- [Python](#python)
|
||||||
|
- [Javascript / Typescript / NodeJS](#nodejs)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### Python
|
||||||
|
|
||||||
|
The following guidelines apply to any projects written with Python:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Indentation
|
||||||
|
|
||||||
|
Use `4 spaces` per indentation level.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> def Encrypt( key : int, bytestr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> i_blk, left_bytes = divmod( len(bytestr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> def encrypt( key : int, byteStr : bytes ):
|
||||||
|
> Res = b''
|
||||||
|
> iBlk, leftBytes = divmod( len(byteStr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Line Length
|
||||||
|
|
||||||
|
Keep the maximum character count to `100 characters per line`. If you are revising old code which doesn't follow this guideline; please rewrite it to conform.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Blank Lines
|
||||||
|
|
||||||
|
Surround top-level functions and class definitions with a blank in-between.
|
||||||
|
|
||||||
|
Method definitions inside a class are surrounded by a single blank line.
|
||||||
|
|
||||||
|
Extra blank lines may be used (sparingly) to separate groups of functions related to one another. Blank lines may be omitted between a bunch of related one-liners (e.g: set of dummy implementations).
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Imports
|
||||||
|
|
||||||
|
Imports should usually be on separate lines:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> import os
|
||||||
|
> import sys
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> import sys, os
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
The following is acceptable:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> from mypkg import siblingA, siblingB, siblingC
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Commenting
|
||||||
|
|
||||||
|
Comment your code. It helps novice readers to better understand the process. It doesn't have to be painfully obvious explanations, but it helps to give an idea of what something does.
|
||||||
|
|
||||||
|
Please append `#` to the beginning of each line.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# #
|
||||||
|
# byteString : b'1#Aetherx|232#1#233262#0#0#0#'
|
||||||
|
# #
|
||||||
|
|
||||||
|
def Encrypt( key : int, byteString : bytes ):
|
||||||
|
res = bytearray( )
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Casing
|
||||||
|
|
||||||
|
- Stick to `camelCase`; unless:
|
||||||
|
- naming functions, capitalize the first letter
|
||||||
|
- Capitalize enums
|
||||||
|
- If you see code not conforming with this, please revise it in your pull request.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> def Encrypt( key : int, byteStr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> iBlock, leftBytes = divmod( len(byteStr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> def encrypt( key : int, bytestr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> i_blk, left_bytes = divmod( len(bytestr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### NodeJS
|
||||||
|
|
||||||
|
The following allows you to configure ESLint and Prettier.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Prettier
|
||||||
|
|
||||||
|
We have opted to make use of [ESLint](#eslint) over Prettier. We provide a detailed ESLint flag config file with very specific linting rules. Please review that section for more information.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### ESLint
|
||||||
|
|
||||||
|
Within the root folder of the repo, there are several configuration files which you should be using within the project. These files dictate how prettier and eslint will behave and what is acceptable / not acceptable.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Pick the config file below depending on which version of ESLint you are using. The v8 and older `.eslint` may not be there if we have migrated over to an Eslint v9 flat config file:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
###### v9 & Newer (Config)
|
||||||
|
|
||||||
|
Our NodeJS applications require that you utilize ESLint v9 or newer which makes use of a flat config structure. You may find a copy of our flat config at the link below:
|
||||||
|
|
||||||
|
- [📄 eslint.config.mjs](https://github.com/thebinaryninja/tvapp2/blob/main/tvapp2/eslint.config.mjs)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
###### v8 & Older (Config)
|
||||||
|
|
||||||
|
- We no longer utilize any version of ESLint older than version 9.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> When submitting your pull request, these linting and style rules will be verified with all of your files. If you did not follow these rules; the linter tests on your pull request will fail; and you'll be expected to correct these issues before your submission will be transferred over for human review.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Packages
|
||||||
|
|
||||||
|
We use the following packages for linting and prettier.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
| Package | Repo File | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| [@stylistic/eslint-plugin-js](https://npmjs.com/package/@stylistic/eslint-plugin-js) | [package.json](./package.json) | JavaScript stylistic rules for ESLint, migrated from eslint core. |
|
||||||
|
| [@stylistic/eslint-plugin-ts](https://npmjs.com/package/@stylistic/eslint-plugin-ts) | [package.json](./package.json) | TypeScript stylistic rules for ESLint, migrated from typescript-eslint. |
|
||||||
|
| [@stylistic/eslint-plugin-plus](https://npmjs.com/package/@stylistic/eslint-plugin-plus) | [package.json](./package.json) | Supplementary rules introduced by ESLint Stylistic. |
|
||||||
|
| [eslint-plugin-prettier](https://npmjs.com/package/eslint-plugin-prettier) | [package.json](./package.json) | Runs Prettier as an ESLint rule and reports differences as individual ESLint issues. |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
You can add the following to your `package.json` file:
|
||||||
|
|
||||||
|
https://github.com/TheBinaryNinja/tvapp2/blob/1c75f11e9f0506ad3dd05133fdafc3aeb87686ca/tvapp2/package.json#L81-L92
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Indentation
|
||||||
|
|
||||||
|
Use `4 spaces` per indentation level.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Style
|
||||||
|
|
||||||
|
For files that are not controlled by [Prettier](#prettier) or [ESLint](#eslint); use `Allman Style`. Braces should be on their own lines, and any code inside the braces should be indented 4 spaces.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return {
|
||||||
|
status: "failure",
|
||||||
|
user:
|
||||||
|
{
|
||||||
|
id: "1aaa35aa-fb3a-62ae-ffec-a14g7fc401ac",
|
||||||
|
label: "Test String",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (x == y)
|
||||||
|
{
|
||||||
|
foo();
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Line Length
|
||||||
|
|
||||||
|
Keep the maximum character count to `100 characters per line`. The configs on this page have prettier automatically set up to detect more than 100 characters per line.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Commenting
|
||||||
|
|
||||||
|
Comment your code. It helps novice readers to better understand the process. You may use block style commenting, or single lines:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/*
|
||||||
|
tests to decide if the end-user is running on Darwin or another platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
test(`Return true if platform is Darwin`, () => {
|
||||||
|
process.platform = 'darwin';
|
||||||
|
expect(bIsDarwin()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`Return false if platform is not Darwin`, () => {
|
||||||
|
process.platform = 'linux';
|
||||||
|
expect(bIsDarwin()).toBe(false);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Casing
|
||||||
|
|
||||||
|
Stick to `camelCase` as much as possible.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
let myVar = 'one';
|
||||||
|
let secondVar = 'two';
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you are defining a new environment variable; it must be in ALL CAPS in the `Dockerfile`:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
ENV DIR_BUILD=/usr/src/app
|
||||||
|
ENV DIR_RUN=/usr/bin/app
|
||||||
|
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
|
||||||
|
ENV WEB_IP="0.0.0.0"
|
||||||
|
ENV WEB_PORT=4124
|
||||||
|
ENV STREAM_QUALITY="hd"
|
||||||
|
ENV FILE_PLAYLIST="playlist.m3u8"
|
||||||
|
ENV FILE_EPG="xmltv.xml"
|
||||||
|
ENV LOG_LEVEL=4
|
||||||
|
ENV TZ="Etc/UTC"
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Then you may call your new environment variable within the Javascript code; and ensure you define a default value to correct any user misconfigurations:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
|
||||||
|
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
|
||||||
|
const envFileM3U = process.env.FILE_PLAYLIST || 'playlist.m3u8';
|
||||||
|
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
|
||||||
|
const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
|
||||||
|
<!-- BADGE > GENERAL -->
|
||||||
|
[general-npmjs-uri]: https://npmjs.com
|
||||||
|
[general-nodejs-uri]: https://nodejs.org
|
||||||
|
[general-npmtrends-uri]: http://npmtrends.com/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > VERSION > GITHUB -->
|
||||||
|
[github-version-img]: https://img.shields.io/github/v/tag/thebinaryninja/tvapp2?logo=GitHub&label=Version&color=ba5225
|
||||||
|
[github-version-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > LICENSE > MIT -->
|
||||||
|
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
|
||||||
|
[license-mit-uri]: https://github.com/thebinaryninja/tvapp2/blob/main/LICENSE
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
|
||||||
|
[github-downloads-img]: https://img.shields.io/github/downloads/thebinaryninja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
|
||||||
|
[github-downloads-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
|
||||||
|
[github-size-img]: https://img.shields.io/github/repo-size/thebinaryninja/tvapp2?logo=github&label=Size&color=59702a
|
||||||
|
[github-size-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > ALL CONTRIBUTORS -->
|
||||||
|
[contribs-all-img]: https://img.shields.io/github/all-contributors/thebinaryninja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
|
||||||
|
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > NPM -->
|
||||||
|
[github-build-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > Pypi -->
|
||||||
|
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-pypi-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/pypi-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > TESTS -->
|
||||||
|
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
|
||||||
|
[github-tests-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-tests.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > COMMIT -->
|
||||||
|
[github-commit-img]: https://img.shields.io/github/last-commit/thebinaryninja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
|
||||||
|
[github-commit-uri]: https://github.com/thebinaryninja/tvapp2/commits/main/
|
||||||
|
|
||||||
|
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
|
||||||
|
[github-docker-version-uri]: https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Dockerhub > Docker Image -->
|
||||||
|
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
|
||||||
|
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
|
||||||
|
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea 2 > Docker Image -->
|
||||||
|
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
|
||||||
|
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
|
||||||
|
|
||||||
|
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
|
||||||
|
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
|
||||||
|
[btn-github-submit-uri]: https://github.com/thebinaryninja/tvapp2/issues
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
96
Dockerfile
@@ -9,55 +9,109 @@
|
|||||||
# https://git.binaryninja.net/BinaryNinja/tvapp2
|
# https://git.binaryninja.net/BinaryNinja/tvapp2
|
||||||
# https://github.com/aetherinox/docker-base-alpine
|
# https://github.com/aetherinox/docker-base-alpine
|
||||||
#
|
#
|
||||||
# you can build your own image by running
|
# build your own image by running
|
||||||
# amd64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 -t tvapp2:1.0.0-amd64 -f Dockerfile .
|
# amd64 docker build --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 -t tvapp2:latest -t tvapp2:1.5.0 -t tvapp2:1.5.0-amd64 -f Dockerfile .
|
||||||
# arm64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:1.0.0-arm64 -f Dockerfile.aarch64 .
|
# arm64 docker build --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 -t tvapp2:1.5.0-arm64 -f Dockerfile.aarch64 .
|
||||||
#
|
#
|
||||||
# if you prefer to use `docker buildx`
|
# OR; build using `docker buildx`
|
||||||
# create docker buildx create --driver docker-container --name container --bootstrap --use
|
# create docker buildx create --driver docker-container --name container --bootstrap --use
|
||||||
# amd64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/amd64 --output type=docker --output type=docker .
|
# amd64 docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
# arm64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/arm64 --output type=docker --output type=docker .
|
# arm64 docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
|
#
|
||||||
|
# OR; build single amd64 image
|
||||||
|
# create docker buildx create --driver docker-container --name container --bootstrap --use
|
||||||
|
# amd64 docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0 --tag ghcr.io/thebinaryninja/tvapp2:1.5 --tag ghcr.io/thebinaryninja/tvapp2:1 --tag ghcr.io/thebinaryninja/tvapp2:latest --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --push .
|
||||||
|
#
|
||||||
|
# OR; build official image (publish)
|
||||||
|
# create docker buildx create --driver docker-container --name container --bootstrap --use
|
||||||
|
# amd64-stable docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
|
# arm64-stable docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=stable --tag ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
|
# amd64-dev docker buildx build --build-arg ARCH=amd64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=development --tag ghcr.io/thebinaryninja/tvapp2:development-amd64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/amd64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
|
# arm64-dev docker buildx build --build-arg ARCH=arm64 --build-arg VERSION=1.5.0 --build-arg BUILDDATE=20260812 --build-arg RELEASE=development --tag ghcr.io/thebinaryninja/tvapp2:development-arm64 --attest type=provenance,disabled=true --attest type=sbom,disabled=true --file Dockerfile --platform linux/arm64 --output type=docker --allow network.host --network host --no-cache --pull --push .
|
||||||
|
# amd64-stable-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.5.0-amd64
|
||||||
|
# arm64-stable-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:1.5.0-arm64
|
||||||
|
# amd64-dev-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-amd64
|
||||||
|
# arm64-dev-hash docker buildx imagetools inspect ghcr.io/thebinaryninja/tvapp2:development-arm64
|
||||||
|
# merge-stable docker buildx imagetools create --tag ghcr.io/thebinaryninja/tvapp2:1.5.0 --tag ghcr.io/thebinaryninja/tvapp2:1.5 --tag ghcr.io/thebinaryninja/tvapp2:1 --tag ghcr.io/thebinaryninja/tvapp2:latest sha256:0abe1b1c119959b3b1ccc23c56a7ee2c4c908c6aaef290d4ab2993859d807a3b sha256:e68b9de8669eac64d4e4d2a8343c56705e05e9a907cf0b542343f9b536d9c473
|
||||||
|
# merge-dev docker buildx imagetools create --tag ghcr.io/thebinaryninja/tvapp2:development sha256:8f36385a28c8f6eb7394d903c9a7a2765b06f94266b32628389ee9e3e3d7e69d sha256:c719ccb034946e3f0625003f25026d001768794e38a1ba8aafc9146291d548c5
|
||||||
# #
|
# #
|
||||||
|
|
||||||
FROM ghcr.io/aetherinox/alpine-base:3.20-amd64
|
# #
|
||||||
|
# FROM
|
||||||
|
# any args defined before FROM cannot be called after FROM and the ARE is classified outside the build process.
|
||||||
|
# You will have to re-define the arg after FROM to utilize it anywhere else in the build process.
|
||||||
|
#
|
||||||
|
# @ref https://docs.docker.com/reference/dockerfile/#understand-how-arg-and-from-interact
|
||||||
|
# #
|
||||||
|
|
||||||
|
ARG ARCH=amd64
|
||||||
|
ARG ALPINE_VERSION=3.22
|
||||||
|
FROM --platform=linux/${ARCH} ghcr.io/aetherinox/alpine-base:${ALPINE_VERSION}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Set Args
|
# Set Args
|
||||||
# #
|
# #
|
||||||
|
|
||||||
|
ARG ARCH=amd64
|
||||||
|
ARG ALPINE_VERSION=3.22
|
||||||
ARG BUILDDATE
|
ARG BUILDDATE
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
|
ARG RELEASE
|
||||||
|
ARG GIT_SHA1=0000000000000000000000000000000000000000
|
||||||
|
ARG REGISTRY=local
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Set Labels
|
# Set Labels
|
||||||
# #
|
# #
|
||||||
|
|
||||||
LABEL maintainer="aetherinox, iFlip721"
|
LABEL org.opencontainers.image.authors="Aetherinox, iFlip721, Optx"
|
||||||
LABEL org.opencontainers.image.authors="aetherinox, iFlip721"
|
|
||||||
LABEL org.opencontainers.image.vendor="BinaryNinja"
|
LABEL org.opencontainers.image.vendor="BinaryNinja"
|
||||||
LABEL org.opencontainers.image.title="TVApp2"
|
LABEL org.opencontainers.image.title="TVApp2"
|
||||||
LABEL org.opencontainers.image.description="Automatic m3u and xml guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client."
|
LABEL org.opencontainers.image.description="Automatic m3u and xml guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client."
|
||||||
LABEL org.opencontainers.image.source="https://github.com/TheBinaryNinja/tvapp2"
|
LABEL org.opencontainers.image.source="https://github.com/thebinaryninja/tvapp2"
|
||||||
LABEL org.opencontainers.image.repo.1="https://github.com/TheBinaryNinja/tvapp2"
|
LABEL org.opencontainers.image.repo.1="https://github.com/thebinaryninja/tvapp2"
|
||||||
LABEL org.opencontainers.image.repo.2="https://git.binaryninja.net/BinaryNinja/tvapp2"
|
LABEL org.opencontainers.image.repo.2="https://git.binaryninja.net/binaryninja/tvapp2"
|
||||||
LABEL org.opencontainers.image.repo.3="https://github.com/aetherinox/docker-base-alpine"
|
LABEL org.opencontainers.image.repo.3="https://github.com/aetherinox/docker-base-alpine"
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/TheBinaryNinja/tvapp2/wiki"
|
LABEL org.opencontainers.image.documentation="https://thebinaryninja.github.io/tvapp2"
|
||||||
LABEL org.opencontainers.image.url="https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2"
|
LABEL org.opencontainers.image.url="https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2"
|
||||||
LABEL org.opencontainers.image.licenses="MIT"
|
LABEL org.opencontainers.image.licenses="MIT"
|
||||||
LABEL BUILDVERSION="TVApp2 v${VERSION} Build ${BUILDDATE}"
|
LABEL org.opencontainers.image.architecture="${ARCH:-amd64}"
|
||||||
|
LABEL org.opencontainers.image.ref.name="main"
|
||||||
|
LABEL org.opencontainers.image.registry="${REGISTRY:-local}"
|
||||||
|
LABEL org.opencontainers.image.release="${RELEASE:-stable}"
|
||||||
|
LABEL org.tvapp2.image.maintainers="Aetherinox, iFlip721, Optx"
|
||||||
|
LABEL org.tvapp2.image.build-version="Version:- ${VERSION} Date:- ${BUILDDATE:-3.21}"
|
||||||
|
LABEL org.tvapp2.image.build-version-alpine="${ALPINE_VERSION:-3.21}"
|
||||||
|
LABEL org.tvapp2.image.build-architecture="${ARCH:-amd64}"
|
||||||
|
LABEL org.tvapp2.image.build-release="${RELEASE:-stable}"
|
||||||
|
LABEL org.tvapp2.image.build-sha1="${GIT_SHA1:-0000000000000000000000000000000000000000}"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Set Env Var
|
# Set Env Var
|
||||||
# #
|
# #
|
||||||
|
|
||||||
ENV TZ="Etc/UTC"
|
ENV NODE_VERSION=22.16.0
|
||||||
ENV URL_REPO="https://git.binaryninja.net/BinaryNinja/"
|
|
||||||
ENV WEB_IP="0.0.0.0"
|
|
||||||
ENV WEB_PORT=4124
|
|
||||||
ENV NODE_VERSION=18.20.5
|
|
||||||
ENV YARN_VERSION=1.22.22
|
ENV YARN_VERSION=1.22.22
|
||||||
|
ENV NPM_VERSION=10.9.2
|
||||||
|
ENV RELEASE="${RELEASE:-stable}"
|
||||||
ENV DIR_BUILD=/usr/src/app
|
ENV DIR_BUILD=/usr/src/app
|
||||||
ENV DIR_RUN=/usr/bin/app
|
ENV DIR_RUN=/usr/bin/app
|
||||||
|
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
|
||||||
|
ENV WEB_IP="0.0.0.0"
|
||||||
|
ENV WEB_PORT=4124
|
||||||
|
ENV HDHR_PORT=6077
|
||||||
|
ENV WEB_ENCODING="deflate, br"
|
||||||
|
ENV WEB_PROXY_HEADER="x-forwarded-for"
|
||||||
|
ENV STREAM_QUALITY="hd"
|
||||||
|
ENV FILE_URL="urls.txt"
|
||||||
|
ENV FILE_M3U="playlist.m3u8"
|
||||||
|
ENV FILE_EPG="xmltv.xml"
|
||||||
|
ENV FILE_TAR="xmltv.xml.gz"
|
||||||
|
ENV HEALTH_TIMER=600000
|
||||||
|
ENV TASK_CRON_SYNC="0 0 */3 * *"
|
||||||
|
ENV LOG_LEVEL=4
|
||||||
|
ENV TZ="Etc/UTC"
|
||||||
|
ENV GIT_SHA1=${GIT_SHA1:-0000000000000000000000000000000000000000}
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Install
|
# Install
|
||||||
@@ -66,8 +120,10 @@ ENV DIR_RUN=/usr/bin/app
|
|||||||
RUN \
|
RUN \
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
wget \
|
wget \
|
||||||
|
curl \
|
||||||
bash \
|
bash \
|
||||||
nano \
|
nano \
|
||||||
|
git \
|
||||||
npm \
|
npm \
|
||||||
openssl
|
openssl
|
||||||
|
|
||||||
|
|||||||
@@ -1,115 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1
|
|
||||||
|
|
||||||
# #
|
|
||||||
# @project TVApp2
|
|
||||||
# @usage docker image which allows you to download a m3u playlist and EPG guide data from
|
|
||||||
# multiple IPTV services.
|
|
||||||
# @file Dockerfile.aarch64
|
|
||||||
# @repo https://github.com/TheBinaryNinja/tvapp2
|
|
||||||
# https://git.binaryninja.net/BinaryNinja/tvapp2
|
|
||||||
# https://github.com/aetherinox/docker-base-alpine
|
|
||||||
#
|
|
||||||
# you can build your own image by running
|
|
||||||
# amd64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 -t tvapp2:1.0.0-amd64 -f Dockerfile .
|
|
||||||
# arm64 docker build --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:1.0.0-arm64 -f Dockerfile.aarch64 .
|
|
||||||
#
|
|
||||||
# if you prefer to use `docker buildx`
|
|
||||||
# create docker buildx create --driver docker-container --name container --bootstrap --use
|
|
||||||
# amd64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/amd64 --output type=docker --output type=docker .
|
|
||||||
# arm64 docker buildx build --no-cache --pull --build-arg VERSION=1.0.0 --build-arg BUILDDATE=20250218 -t tvapp2:latest -t tvapp2:1.0.0 --platform=linux/arm64 --output type=docker --output type=docker .
|
|
||||||
# #
|
|
||||||
|
|
||||||
FROM ghcr.io/aetherinox/alpine-base:3.20-arm64
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Set Args
|
|
||||||
# #
|
|
||||||
|
|
||||||
ARG BUILDDATE
|
|
||||||
ARG VERSION
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Set Labels
|
|
||||||
# #
|
|
||||||
|
|
||||||
LABEL maintainer="aetherinox, iFlip721"
|
|
||||||
LABEL org.opencontainers.image.authors="aetherinox, iFlip721"
|
|
||||||
LABEL org.opencontainers.image.vendor="BinaryNinja"
|
|
||||||
LABEL org.opencontainers.image.title="TVApp2"
|
|
||||||
LABEL org.opencontainers.image.description="Automatic m3u and xml guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client."
|
|
||||||
LABEL org.opencontainers.image.source="https://github.com/TheBinaryNinja/tvapp2"
|
|
||||||
LABEL org.opencontainers.image.repo.1="https://github.com/TheBinaryNinja/tvapp2"
|
|
||||||
LABEL org.opencontainers.image.repo.2="https://git.binaryninja.net/BinaryNinja/tvapp2"
|
|
||||||
LABEL org.opencontainers.image.repo.3="https://github.com/aetherinox/docker-base-alpine"
|
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/TheBinaryNinja/tvapp2/wiki"
|
|
||||||
LABEL org.opencontainers.image.url="https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2"
|
|
||||||
LABEL org.opencontainers.image.licenses="MIT"
|
|
||||||
LABEL BUILDVERSION="TVApp2 v${VERSION} Build ${BUILDDATE}"
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Set Env Var
|
|
||||||
# #
|
|
||||||
|
|
||||||
ENV TZ="Etc/UTC"
|
|
||||||
ENV URL_REPO="https://git.binaryninja.net/BinaryNinja/"
|
|
||||||
ENV WEB_IP="0.0.0.0"
|
|
||||||
ENV WEB_PORT=4124
|
|
||||||
ENV NODE_VERSION=18.20.5
|
|
||||||
ENV YARN_VERSION=1.22.22
|
|
||||||
ENV DIR_BUILD=/usr/src/app
|
|
||||||
ENV DIR_RUN=/usr/bin/app
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Install
|
|
||||||
# #
|
|
||||||
|
|
||||||
RUN \
|
|
||||||
apk add --no-cache \
|
|
||||||
wget \
|
|
||||||
bash \
|
|
||||||
nano \
|
|
||||||
npm \
|
|
||||||
openssl
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Copy docker-entrypoint
|
|
||||||
# #
|
|
||||||
|
|
||||||
COPY docker-entrypoint.sh /usr/local/bin/
|
|
||||||
|
|
||||||
# #
|
|
||||||
# copy s6-overlays root to image root
|
|
||||||
# #
|
|
||||||
|
|
||||||
COPY root/ /
|
|
||||||
|
|
||||||
# #
|
|
||||||
# set work directory
|
|
||||||
# #
|
|
||||||
|
|
||||||
WORKDIR ${DIR_BUILD}
|
|
||||||
|
|
||||||
# #
|
|
||||||
# copy tvapp2 project to workdir
|
|
||||||
# #
|
|
||||||
|
|
||||||
COPY tvapp2/ ./
|
|
||||||
|
|
||||||
# #
|
|
||||||
# set work dir to built app
|
|
||||||
# #
|
|
||||||
|
|
||||||
WORKDIR ${DIR_RUN}
|
|
||||||
|
|
||||||
# #
|
|
||||||
# Ports and volumes
|
|
||||||
# #
|
|
||||||
|
|
||||||
EXPOSE ${WEB_PORT}/tcp
|
|
||||||
|
|
||||||
# #
|
|
||||||
# In case user sets up the cron for a longer duration, do a first run
|
|
||||||
# and then keep the container running. Hacky, but whatever.
|
|
||||||
# #
|
|
||||||
|
|
||||||
ENTRYPOINT ["/init"]
|
|
||||||
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2025 BinaryNinja
|
Copyright (c) 2025-2026 BinaryNinja
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -44,3 +44,7 @@ services:
|
|||||||
memlock:
|
memlock:
|
||||||
soft: -1
|
soft: -1
|
||||||
hard: -1
|
hard: -1
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "--fail", "http://127.0.0.1:4124/api/health?silent=true" ]
|
||||||
|
interval: 30s
|
||||||
|
retries: 5
|
||||||
|
|||||||
@@ -6,21 +6,197 @@ tags:
|
|||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
This section outlines all releases of TVApp2, including the version of the release, and the changes made for that release.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
<p align="center" markdown="1">
|
<p align="center" markdown="1">
|
||||||
|
|
||||||

|
<!-- prettier-ignore-start -->
|
||||||

|
[![Version][github-version-img]][github-version-uri]
|
||||||

|
[![Downloads][github-downloads-img]][github-downloads-uri]
|
||||||

|
[![Size][github-size-img]][github-size-img]
|
||||||
|
[![Last Commit][github-commit-img]][github-commit-img]
|
||||||
|
[![Contributors][contribs-all-img]](#contributors)
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
### <!-- md:version stable- --> 1.0.0 <small>Feb 24, 2025</small> { id="1.0.0" }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:version stable- --> 1.4.0 <small>Apr 10, 2025</small> { id="1.4.0" }
|
||||||
|
|
||||||
|
- `feat`: add new environment variable `HEALTH_TIMER` _(See feature below)_
|
||||||
|
- `feat`: new health check icon in top right; triggers every `10 minutes` and reports back to the web interface as a toast notification
|
||||||
|
- health check shows timer until next health check is performed.
|
||||||
|
- `feat`: added bootstramp toast notifications and modals
|
||||||
|
- `feat`: new modal dialog when when user triggers a re-sync of the m3u and epg data
|
||||||
|
- `feat`: footer of web interface how discloses which build is being ran; `stable` or `development`
|
||||||
|
- `refactor`: console logging system overhauled with new syntax for how logs are displayed
|
||||||
|
- `refactor`: additional logs added for `LOG_LEVEL=5` or higher
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:version stable- --> 1.3.0 <small>Apr 9, 2025</small> { id="1.3.0" }
|
||||||
|
|
||||||
|
- `feat`: new button to upper-right side of header which allows you to **force re-sync** your m3u and xml data.
|
||||||
|
- `feat`: new api endpoint `/api/resync`; utilized to resync M3U and EPG data
|
||||||
|
- `feat`: new api endpoint `/api/health`; utilized in your `docker-compose.yml` health check
|
||||||
|
- `feat`: new env variable `WEB_ENCODING`; allows you to customize the HTTP `Accept-Encoding` request and response header
|
||||||
|
- `feat`: new env variable `IP_GATEWAY`; stores assigned container gateway ip
|
||||||
|
- `feat`: new env variable `IP_CONTAINER`; stores assigned container ip
|
||||||
|
- `refactor`: env variables re-named
|
||||||
|
- `FILE_TAR` → `FILE_GZP`
|
||||||
|
- `refactor`: errors and success messages now use api endpoint; lists timestamp, error code, etc.
|
||||||
|
- `build`: bump bootstrap from `v4` to `v5`
|
||||||
|
- `fix`: bug in Jellyfin which caused EPG data syncing to error out for hosts which cannot support gzip compression
|
||||||
|
- Error: _[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F, is an invalid character. Line 1, position 1._
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:version stable- --> 1.2.0 <small>Apr 5, 2025</small> { id="1.2.0" }
|
||||||
|
|
||||||
|
- `feat`: add support for additional mime types and default file type
|
||||||
|
- `style`: rename env variable `FILE_PLAYLIST` to `FILE_M3U`
|
||||||
|
- `build`: add new env vars to `Dockerfile`
|
||||||
|
- `FILE_TAR`
|
||||||
|
- `FILE_URL`
|
||||||
|
- `refactor`: m3u and epg files now stored in `www` folder
|
||||||
|
- `fix`: html template links pointing to old repo
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:version stable- --> 1.1.0 <small>Mar 25, 2025</small> { id="1.1.0" }
|
||||||
|
|
||||||
|
- `feat`: new interface & theme for web ui
|
||||||
|
- integrated bootstrap 4.x
|
||||||
|
- new dark theme
|
||||||
|
- all hosted files now display `date`, `download url`, `size`, and `description`
|
||||||
|
- automatic viewport resizing depending on the device used
|
||||||
|
- new favicon
|
||||||
|
- localized css, js, and image support instead of relying on externally hosted resources
|
||||||
|
- `feat`: app now offers a compressed `gzip` for EPG guide data
|
||||||
|
- `feat`: add multiple url paths to download each asset
|
||||||
|
- `/guide`, `/epg`, `xml`
|
||||||
|
- `/playlist`, `/m3u`, `/m3u8`
|
||||||
|
- `/gzip`, `/gz`
|
||||||
|
- `feat`: add mew environment variables
|
||||||
|
- `LOG_LEVEL`: specifies what level of logs you will see in console
|
||||||
|
- `STREAM_QUALITY`: specifies the quality of the stream; options: `hd` and `sd`
|
||||||
|
- `FILE_PLAYLIST`: filename that M3U playlist data will be stored to
|
||||||
|
- `FILE_EPG`: filename that EPG / XML guide data will be stored to
|
||||||
|
- `FILE_GZIP`: filename that compressed gzip guide data will be stored to
|
||||||
|
- `build`: app migrated from CommonJS to ES Modules
|
||||||
|
- `build`: bump alpine base image from v3.20 to v3.21
|
||||||
|
- `build`: migrated html template to independent file in `www` folder; utilizes `ejs` module
|
||||||
|
- `build`: **amd64** and **arm64** docker images merged into one image with architecture support
|
||||||
|
- `fix`: resolved bug where local server could not be started using nodejs; related to ip address variable
|
||||||
|
- `build(deps)`: add package `ejs` 3.1.10
|
||||||
|
- `build(deps)`: add package `chalk` 5.3.0
|
||||||
|
- `build(deps)`: add package `moment` 2.30.1
|
||||||
|
- `build(deps-dev)`: add package `eslint` 9.17.0
|
||||||
|
- `build(deps-dev)`: add package `eslint-plugin-chai-friendly` 1.0.1
|
||||||
|
- `build(deps-dev)`: add package `eslint-plugin-import` 2.31.0
|
||||||
|
- `build(deps-dev)`: add package `eslint-plugin-n` 17.15.0
|
||||||
|
- `build(deps-dev)`: add package `eslint-plugin-promise` 7.2.1
|
||||||
|
- `build(deps-dev)`: add package `@stylistic/eslint-plugin-js` 3.1.0
|
||||||
|
- `remove`: tvapp2.fonts.min.js
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:version stable- --> 1.0.0 <small>Feb 24, 2025</small> { id="1.0.0" }
|
||||||
|
|
||||||
|
- Initial release
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
|
||||||
|
<!-- BADGE > GENERAL -->
|
||||||
|
[general-npmjs-uri]: https://npmjs.com
|
||||||
|
[general-nodejs-uri]: https://nodejs.org
|
||||||
|
[general-npmtrends-uri]: http://npmtrends.com/csf-firewall
|
||||||
|
|
||||||
|
<!-- BADGE > VERSION > GITHUB -->
|
||||||
|
[github-version-img]: https://img.shields.io/github/v/tag/TheBinaryNinja/tvapp2?logo=GitHub&label=Version&color=ba5225
|
||||||
|
[github-version-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > LICENSE > MIT -->
|
||||||
|
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
|
||||||
|
[license-mit-uri]: https://github.com/TheBinaryNinja/tvapp2/blob/main/LICENSE
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
|
||||||
|
[github-downloads-img]: https://img.shields.io/github/downloads/TheBinaryNinja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
|
||||||
|
[github-downloads-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
|
||||||
|
[github-size-img]: https://img.shields.io/github/repo-size/TheBinaryNinja/tvapp2?logo=github&label=Size&color=59702a
|
||||||
|
[github-size-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > ALL CONTRIBUTORS -->
|
||||||
|
[contribs-all-img]: https://img.shields.io/github/all-contributors/TheBinaryNinja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
|
||||||
|
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > NPM -->
|
||||||
|
[github-build-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > Pypi -->
|
||||||
|
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-pypi-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/pypi-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > TESTS -->
|
||||||
|
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
|
||||||
|
[github-tests-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-tests.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > COMMIT -->
|
||||||
|
[github-commit-img]: https://img.shields.io/github/last-commit/TheBinaryNinja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
|
||||||
|
[github-commit-uri]: https://github.com/TheBinaryNinja/tvapp2/commits/main/
|
||||||
|
|
||||||
|
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
|
||||||
|
[github-docker-version-uri]: https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Dockerhub > Docker Image -->
|
||||||
|
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
|
||||||
|
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
|
||||||
|
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea 2 > Docker Image -->
|
||||||
|
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
|
||||||
|
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
|
||||||
|
|
||||||
|
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
|
||||||
|
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
|
||||||
|
[btn-github-submit-uri]: https://github.com/TheBinaryNinja/tvapp2/issues
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
|||||||
652
docs/docs/about/contributing.md
Normal file
@@ -0,0 +1,652 @@
|
|||||||
|
---
|
||||||
|
title: Contributing to TVApp2
|
||||||
|
tags:
|
||||||
|
- info
|
||||||
|
---
|
||||||
|
|
||||||
|
<div align="center" markdown="1">
|
||||||
|
<h1>♾️ Contributing ♾️</h1>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<p align="center" markdown="1">
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
[![Version][github-version-img]][github-version-uri]
|
||||||
|
[![Downloads][github-downloads-img]][github-downloads-uri]
|
||||||
|
[![Size][github-size-img]][github-size-img]
|
||||||
|
[![Last Commit][github-commit-img]][github-commit-img]
|
||||||
|
[![Contributors][contribs-all-img]](#contributors)
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Below are a list of ways that you can help contribute to this project, as well as policies and guides that explain how to get started.
|
||||||
|
|
||||||
|
Please review everything on this page before you submit your contribution.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
- [About](#about)
|
||||||
|
- [Issues, Bugs, Ideas](#issues-bugs-ideas)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [Before Submitting Pull Requests](#before-submitting-pull-requests)
|
||||||
|
- [Conventional Commit Specification](#conventional-commit-specification)
|
||||||
|
- [Types](#types)
|
||||||
|
- [Example 1:](#example-1)
|
||||||
|
- [Example 2:](#example-2)
|
||||||
|
- [Committing](#committing)
|
||||||
|
- [Languages](#languages)
|
||||||
|
- [Python](#python)
|
||||||
|
- [Indentation](#indentation)
|
||||||
|
- [Line Length](#line-length)
|
||||||
|
- [Blank Lines](#blank-lines)
|
||||||
|
- [Imports](#imports)
|
||||||
|
- [Commenting](#commenting)
|
||||||
|
- [Casing](#casing)
|
||||||
|
- [NodeJS](#nodejs)
|
||||||
|
- [Prettier](#prettier)
|
||||||
|
- [ESLint](#eslint)
|
||||||
|
- [v9 \& Newer (Config)](#v9--newer-config)
|
||||||
|
- [v8 \& Older (Config)](#v8--older-config)
|
||||||
|
- [Packages](#packages)
|
||||||
|
- [Indentation](#indentation-1)
|
||||||
|
- [Style](#style)
|
||||||
|
- [Line Length](#line-length-1)
|
||||||
|
- [Commenting](#commenting-1)
|
||||||
|
- [Casing](#casing-1)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Issues, Bugs, Ideas
|
||||||
|
|
||||||
|
Stuff happens, and sometimes as best as we try, there may be issues within this project that we are unaware of. That is the great thing about open-source; anyone can use the program and contribute to making it better.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you have found a bug, have an issue, or maybe even a cool idea; you can let us know by [submitting it](https://github.com/thebinaryninja/tvapp2/issues). However, before you submit your new issue, bug report, or feature request; head over to the [Issues Section](https://github.com/thebinaryninja/tvapp2/issues) and ensure nobody else has already submitted it.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Once you are sure that your issue has not already being dealt with; you may submit a new issue at [here](https://github.com/thebinaryninja/tvapp2/issues/new/choose). You'll be asked to specify exactly what your new submission targets, such as:
|
||||||
|
- Bug report
|
||||||
|
- Feature Suggestion
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
When writing a new submission; ensure you fill out any of the questions asked of you. If you do not provide enough information, we cannot help. Be as detailed as possible, and provide any logs or screenshots you may have to help us better understand what you mean. Failure to fill out the submission properly may result in it being closed without a response.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you are submitting a bug report:
|
||||||
|
|
||||||
|
- Explain the issue
|
||||||
|
- Describe how you expect for a feature to work, and what you're seeing instead of what you expected.
|
||||||
|
- List possible options for a resolution or insight
|
||||||
|
- Provide screenshots, logs, or anything else that can visually help track down the issue.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[![Submit Issue][btn-github-submit-img]][btn-github-submit-uri]
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you are looking to contribute to this project by actually submit your own code; please review this section completely. There is important information and policies provided below that you must follow for your pull request to get accepted.
|
||||||
|
|
||||||
|
The source is here for everyone to collectively share and collaborate on. If you think you have a possible solution to a problem; don't be afraid to get your hands dirty.
|
||||||
|
|
||||||
|
All contributions are made via pull requests. To create a pull request, you need a GitHub account. If you are unclear on this process, see [GitHub's documentation on forking and pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Pull requests should be targeted at the master branch.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Before Submitting Pull Requests
|
||||||
|
|
||||||
|
- Follow the repository's code formatting conventions (see below);
|
||||||
|
- Include tests that prove that the change works as intended and does not add regressions;
|
||||||
|
- Document the changes in the code and/or the project's documentation;
|
||||||
|
- Your PR must pass the CI pipeline;
|
||||||
|
- When submitting your Pull Request, use one of the following branches:
|
||||||
|
- For bug fixes: `main` branch
|
||||||
|
- For features & functionality: `development` branch
|
||||||
|
- Include a proper git commit message following the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification).
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you have completed the above tasks, the pull request is ready to be reviewed and your pull request's label will be changed to "Ready for Review". At this point, a human will need to step in and manually verify your submission.
|
||||||
|
|
||||||
|
Reviewers will approve the pull request once they are satisfied with the patch it will be merged.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Conventional Commit Specification
|
||||||
|
|
||||||
|
When committing your changes, we require you to follow the [Conventional Commit Specification](https://conventionalcommits.org/en/v1.0.0/#specification). The **Conventional Commits** is a specification for the format and content of a commit message. The concept behind Conventional Commits is to provide a rich commit history that can be read and understood by both humans and automated tools. Conventional Commits have the following format:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>[(optional <scope>)]: <description>
|
||||||
|
|
||||||
|
[optional <body>]
|
||||||
|
|
||||||
|
[optional <footer(s)>]
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### Types
|
||||||
|
|
||||||
|
Our repositories make use of the following commit tags:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
| Type | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `feat` | <sup><sub>Introduce new feature</sub></sup> |
|
||||||
|
| `fix` | <sup><sub>Bug fix</sub></sup> |
|
||||||
|
| `chore` | <sup><sub>Includes technical or preventative maintenance task that is necessary for managing the app or repo, such as updating grunt tasks, but is not tied to any specific feature. Usually done for maintenance purposes.<br/>E.g: Edit .gitignore, .prettierrc, .prettierignore, .gitignore, eslint.config.js file</sub></sup> |
|
||||||
|
| `revert` | <sup><sub>Revert a previous commit</sub></sup> |
|
||||||
|
| `style` | <sup><sub>Update / reformat style of source code. Does not change the way app is implemented. Changes that do not affect the meaning of the code<br />E.g: white-space, formatting, missing semi-colons, change tabs to spaces, etc)</sub></sup> |
|
||||||
|
| `docs` | <sup><sub>Change website or markdown documents. Does not mean changes to the documentation generator script itself, only the documents created from the generator. <br/>E.g: documentation, readme.md or markdown |
|
||||||
|
| `build` | <sup><sub>Changes to the build / compilation / packaging process or auxiliary tools such as doc generation<br />E.g: create new build tasks, update release script, etc.</sub></sup> |
|
||||||
|
| `refactor` | <sup><sub>Change to production code that leads to no behavior difference,<br/>E.g: split files, rename variables, rename package, improve code style, etc.</sub></sup> |
|
||||||
|
| `test` | <sup><sub>Add or refactor tests, no production code change. Changes the suite of automated tests for the app.</sub></sup> |
|
||||||
|
| `ci` | <sup><sub>Changes related to Continuous Integration (usually `yml` and other configuration files).</sub></sup> |
|
||||||
|
| `perf` | <sup><sub>Performance improvement of algorithms or execution time of the app. Does not change an existing feature.</sub></sup> |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Example 1:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(core): bug affecting menu [#22]
|
||||||
|
^───^────^ ^────────────────^ ^───^
|
||||||
|
| | | |
|
||||||
|
| | | └───⫸ (ISSUE): Reference issue ID
|
||||||
|
│ │ │
|
||||||
|
│ │ └──────────────────────⫸ (DESC): Summary in present tense. Use lower case not title case!
|
||||||
|
│ │
|
||||||
|
│ └──────────────────────────────⫸ (SCOPE): The package(s) that this change affects
|
||||||
|
│
|
||||||
|
└──────────────────────────────────⫸ (TYPE): See list above
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Example 2:
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <short summary> [issue]
|
||||||
|
| | | |
|
||||||
|
| | | └─⫸ Reference issue id (optional)
|
||||||
|
│ │ │
|
||||||
|
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
|
||||||
|
│ │
|
||||||
|
│ └─⫸ Commit Scope: animations|bazel|benchpress|common|compiler|compiler-cli|core|
|
||||||
|
│ elements|forms|http|language-service|localize|platform-browser|
|
||||||
|
│ platform-browser-dynamic|platform-server|router|service-worker|
|
||||||
|
│ upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
|
||||||
|
│ devtools....
|
||||||
|
│
|
||||||
|
└─⫸ Commit Type: build|ci|doc|docs|feat|fix|perf|refactor|test
|
||||||
|
website|chore|style|type|revert|deprecate
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Committing
|
||||||
|
|
||||||
|
If you are pushing a commit which addresses a submitted issue, reference your issue at the end of the commit message. You may also optionally add the major issue to the end of your commit body.
|
||||||
|
|
||||||
|
References should be on their own line, following the word `Ref` or `Refs`
|
||||||
|
|
||||||
|
```
|
||||||
|
Title: fix(core): fix error message displayed to users. [#22]
|
||||||
|
Description: The description of your commit
|
||||||
|
|
||||||
|
Ref: #22, #34, #37
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Languages
|
||||||
|
|
||||||
|
The formatting of code greatly depends on the language being used for this repository. We provide various different languages below as this guide is utilized across multiple repositories.
|
||||||
|
|
||||||
|
- [Python](#python)
|
||||||
|
- [Javascript / Typescript / NodeJS](#nodejs)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### Python
|
||||||
|
|
||||||
|
The following guidelines apply to any projects written with Python:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Indentation
|
||||||
|
|
||||||
|
Use `4 spaces` per indentation level.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> def Encrypt( key : int, bytestr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> i_blk, left_bytes = divmod( len(bytestr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> def encrypt( key : int, byteStr : bytes ):
|
||||||
|
> Res = b''
|
||||||
|
> iBlk, leftBytes = divmod( len(byteStr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Line Length
|
||||||
|
|
||||||
|
Keep the maximum character count to `100 characters per line`. If you are revising old code which doesn't follow this guideline; please rewrite it to conform.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Blank Lines
|
||||||
|
|
||||||
|
Surround top-level functions and class definitions with a blank in-between.
|
||||||
|
|
||||||
|
Method definitions inside a class are surrounded by a single blank line.
|
||||||
|
|
||||||
|
Extra blank lines may be used (sparingly) to separate groups of functions related to one another. Blank lines may be omitted between a bunch of related one-liners (e.g: set of dummy implementations).
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Imports
|
||||||
|
|
||||||
|
Imports should usually be on separate lines:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> import os
|
||||||
|
> import sys
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> import sys, os
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
The following is acceptable:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> from mypkg import siblingA, siblingB, siblingC
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Commenting
|
||||||
|
|
||||||
|
Comment your code. It helps novice readers to better understand the process. It doesn't have to be painfully obvious explanations, but it helps to give an idea of what something does.
|
||||||
|
|
||||||
|
Please append `#` to the beginning of each line.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# #
|
||||||
|
# byteString : b'1#Aetherx|232#1#233262#0#0#0#'
|
||||||
|
# #
|
||||||
|
|
||||||
|
def Encrypt( key : int, byteString : bytes ):
|
||||||
|
res = bytearray( )
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Casing
|
||||||
|
|
||||||
|
- Stick to `camelCase`; unless:
|
||||||
|
- naming functions, capitalize the first letter
|
||||||
|
- Capitalize enums
|
||||||
|
- If you see code not conforming with this, please revise it in your pull request.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> ✅ Correct
|
||||||
|
> ```python
|
||||||
|
> def Encrypt( key : int, byteStr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> iBlock, leftBytes = divmod( len(byteStr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> ❌ Wrong
|
||||||
|
> ```python
|
||||||
|
> def encrypt( key : int, bytestr : bytes ):
|
||||||
|
> res = b''
|
||||||
|
> i_blk, left_bytes = divmod( len(bytestr), 3 )
|
||||||
|
> ```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
#### NodeJS
|
||||||
|
|
||||||
|
The following allows you to configure ESLint and Prettier.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Prettier
|
||||||
|
|
||||||
|
We have opted to make use of [ESLint](#eslint) over Prettier. We provide a detailed ESLint flag config file with very specific linting rules. Please review that section for more information.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### ESLint
|
||||||
|
|
||||||
|
Within the root folder of the repo, there are several configuration files which you should be using within the project. These files dictate how prettier and eslint will behave and what is acceptable / not acceptable.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Pick the config file below depending on which version of ESLint you are using. The v8 and older `.eslint` may not be there if we have migrated over to an Eslint v9 flat config file:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
###### v9 & Newer (Config)
|
||||||
|
|
||||||
|
Our NodeJS applications require that you utilize ESLint v9 or newer which makes use of a flat config structure. You may find a copy of our flat config at the link below:
|
||||||
|
|
||||||
|
- [📄 eslint.config.mjs](https://github.com/thebinaryninja/tvapp2/blob/main/tvapp2/eslint.config.mjs)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
###### v8 & Older (Config)
|
||||||
|
|
||||||
|
- We no longer utilize any version of ESLint older than version 9.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> When submitting your pull request, these linting and style rules will be verified with all of your files. If you did not follow these rules; the linter tests on your pull request will fail; and you'll be expected to correct these issues before your submission will be transferred over for human review.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Packages
|
||||||
|
|
||||||
|
We use the following packages for linting and prettier.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
| Package | Repo File | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| [@stylistic/eslint-plugin-js](https://npmjs.com/package/@stylistic/eslint-plugin-js) | [package.json](./package.json) | JavaScript stylistic rules for ESLint, migrated from eslint core. |
|
||||||
|
| [@stylistic/eslint-plugin-ts](https://npmjs.com/package/@stylistic/eslint-plugin-ts) | [package.json](./package.json) | TypeScript stylistic rules for ESLint, migrated from typescript-eslint. |
|
||||||
|
| [@stylistic/eslint-plugin-plus](https://npmjs.com/package/@stylistic/eslint-plugin-plus) | [package.json](./package.json) | Supplementary rules introduced by ESLint Stylistic. |
|
||||||
|
| [eslint-plugin-prettier](https://npmjs.com/package/eslint-plugin-prettier) | [package.json](./package.json) | Runs Prettier as an ESLint rule and reports differences as individual ESLint issues. |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
You can add the following to your `package.json` file:
|
||||||
|
|
||||||
|
https://github.com/TheBinaryNinja/tvapp2/blob/1c75f11e9f0506ad3dd05133fdafc3aeb87686ca/tvapp2/package.json#L81-L92
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Indentation
|
||||||
|
|
||||||
|
Use `4 spaces` per indentation level.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Style
|
||||||
|
|
||||||
|
For files that are not controlled by [Prettier](#prettier) or [ESLint](#eslint); use `Allman Style`. Braces should be on their own lines, and any code inside the braces should be indented 4 spaces.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
return {
|
||||||
|
status: "failure",
|
||||||
|
user:
|
||||||
|
{
|
||||||
|
id: "1aaa35aa-fb3a-62ae-ffec-a14g7fc401ac",
|
||||||
|
label: "Test String",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (x == y)
|
||||||
|
{
|
||||||
|
foo();
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Line Length
|
||||||
|
|
||||||
|
Keep the maximum character count to `100 characters per line`. The configs on this page have prettier automatically set up to detect more than 100 characters per line.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Commenting
|
||||||
|
|
||||||
|
Comment your code. It helps novice readers to better understand the process. You may use block style commenting, or single lines:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/*
|
||||||
|
tests to decide if the end-user is running on Darwin or another platform.
|
||||||
|
*/
|
||||||
|
|
||||||
|
test(`Return true if platform is Darwin`, () => {
|
||||||
|
process.platform = 'darwin';
|
||||||
|
expect(bIsDarwin()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`Return false if platform is not Darwin`, () => {
|
||||||
|
process.platform = 'linux';
|
||||||
|
expect(bIsDarwin()).toBe(false);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
##### Casing
|
||||||
|
|
||||||
|
Stick to `camelCase` as much as possible.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
let myVar = 'one';
|
||||||
|
let secondVar = 'two';
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
If you are defining a new environment variable; it must be in ALL CAPS in the `Dockerfile`:
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
ENV DIR_BUILD=/usr/src/app
|
||||||
|
ENV DIR_RUN=/usr/bin/app
|
||||||
|
ENV URL_REPO="https://git.binaryninja.net/binaryninja/"
|
||||||
|
ENV WEB_IP="0.0.0.0"
|
||||||
|
ENV WEB_PORT=4124
|
||||||
|
ENV STREAM_QUALITY="hd"
|
||||||
|
ENV FILE_PLAYLIST="playlist.m3u8"
|
||||||
|
ENV FILE_EPG="xmltv.xml"
|
||||||
|
ENV LOG_LEVEL=4
|
||||||
|
ENV TZ="Etc/UTC"
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Then you may call your new environment variable within the Javascript code; and ensure you define a default value to correct any user misconfigurations:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const envUrlRepo = process.env.URL_REPO || 'https://git.binaryninja.net/binaryninja';
|
||||||
|
const envStreamQuality = process.env.STREAM_QUALITY || 'hd';
|
||||||
|
const envFileM3U = process.env.FILE_PLAYLIST || 'playlist.m3u8';
|
||||||
|
const envFileXML = process.env.FILE_EPG || 'xmltv.xml';
|
||||||
|
const envFileTAR = process.env.FILE_TAR || 'xmltv.xml.gz';
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
**[`^ back to top ^`](#about)**
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
|
||||||
|
<!-- BADGE > GENERAL -->
|
||||||
|
[general-npmjs-uri]: https://npmjs.com
|
||||||
|
[general-nodejs-uri]: https://nodejs.org
|
||||||
|
[general-npmtrends-uri]: http://npmtrends.com/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > VERSION > GITHUB -->
|
||||||
|
[github-version-img]: https://img.shields.io/github/v/tag/thebinaryninja/tvapp2?logo=GitHub&label=Version&color=ba5225
|
||||||
|
[github-version-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > LICENSE > MIT -->
|
||||||
|
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
|
||||||
|
[license-mit-uri]: https://github.com/thebinaryninja/tvapp2/blob/main/LICENSE
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
|
||||||
|
[github-downloads-img]: https://img.shields.io/github/downloads/thebinaryninja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
|
||||||
|
[github-downloads-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
|
||||||
|
[github-size-img]: https://img.shields.io/github/repo-size/thebinaryninja/tvapp2?logo=github&label=Size&color=59702a
|
||||||
|
[github-size-uri]: https://github.com/thebinaryninja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > ALL CONTRIBUTORS -->
|
||||||
|
[contribs-all-img]: https://img.shields.io/github/all-contributors/thebinaryninja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
|
||||||
|
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > NPM -->
|
||||||
|
[github-build-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > Pypi -->
|
||||||
|
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-pypi-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/pypi-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > TESTS -->
|
||||||
|
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/thebinaryninja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
|
||||||
|
[github-tests-uri]: https://github.com/thebinaryninja/tvapp2/actions/workflows/npm-tests.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > COMMIT -->
|
||||||
|
[github-commit-img]: https://img.shields.io/github/last-commit/thebinaryninja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
|
||||||
|
[github-commit-uri]: https://github.com/thebinaryninja/tvapp2/commits/main/
|
||||||
|
|
||||||
|
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
|
||||||
|
[github-docker-version-uri]: https://github.com/thebinaryninja/tvapp2/pkgs/container/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Dockerhub > Docker Image -->
|
||||||
|
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
|
||||||
|
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
|
||||||
|
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea 2 > Docker Image -->
|
||||||
|
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
|
||||||
|
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
|
||||||
|
|
||||||
|
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
|
||||||
|
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
|
||||||
|
[btn-github-submit-uri]: https://github.com/thebinaryninja/tvapp2/issues
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
@@ -9,8 +9,9 @@ conventions:
|
|||||||
|
|
||||||
The tag symbol in conjunction with a version number denotes when a specific feature or behavior was added. Make sure you're at least on this version if you want to use it.
|
The tag symbol in conjunction with a version number denotes when a specific feature or behavior was added. Make sure you're at least on this version if you want to use it.
|
||||||
|
|
||||||
|
: <!-- md:version --> default
|
||||||
: <!-- md:version stable- --> stable
|
: <!-- md:version stable- --> stable
|
||||||
: <!-- md:version beta- --> beta
|
: <!-- md:version development- --> development
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -19,11 +20,13 @@ The tag symbol in conjunction with a version number denotes when a specific feat
|
|||||||
These icons define what type of control a specified setting uses.
|
These icons define what type of control a specified setting uses.
|
||||||
|
|
||||||
: <!-- md:control toggle --> toggle
|
: <!-- md:control toggle --> toggle
|
||||||
|
: <!-- md:control toggle_on --> toggle on
|
||||||
|
: <!-- md:control toggle_off --> toggle off
|
||||||
: <!-- md:control textbox --> textbox
|
: <!-- md:control textbox --> textbox
|
||||||
: <!-- md:control dropdown --> dropdown
|
: <!-- md:control dropdown --> dropdown
|
||||||
: <!-- md:control button --> button
|
: <!-- md:control button --> button
|
||||||
: <!-- md:control slider --> slider
|
: <!-- md:control slider --> slider
|
||||||
: <!-- md:control color --> color wheel
|
: <!-- md:control color #E5E5E5 #121315 --> color wheel
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -45,40 +48,42 @@ This defines a command
|
|||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
### <!-- md:flag experimental --> – Experimental { data-toc-label="Experimental" }
|
### <!-- md:flag --> – Flags { #flags data-toc-label="Flags" }
|
||||||
|
|
||||||
|
: <!-- md:flag --> Default
|
||||||
|
: <!-- md:flag experimental --> Experimental
|
||||||
|
: <!-- md:flag required --> Required
|
||||||
|
: <!-- md:flag customization --> Customization
|
||||||
|
: <!-- md:flag metadata --> Metadata
|
||||||
|
: <!-- md:flag dangerous --> Dangerous
|
||||||
|
: <!-- md:flag multiple --> Multiple
|
||||||
|
: <!-- md:flag setting --> Setting
|
||||||
|
|
||||||
Anything listed with this icon are features or functionality that are still in development and may change in future versions.
|
Anything listed with this icon are features or functionality that are still in development and may change in future versions.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
### <!-- md:flag required --> – Required value { #required data-toc-label="Required value" }
|
|
||||||
|
|
||||||
Items listed with this symbol indicate that they are required to be set.
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
### <!-- md:flag customization --> – Customization { #customization data-toc-label="Customization" }
|
|
||||||
|
|
||||||
This symbol denotes that the item described is a customization which affects the overall look of the app.
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
### <!-- md:3rdparty --> – 3rd Party { data-toc-label="3rd Party" }
|
### <!-- md:3rdparty --> – 3rd Party { data-toc-label="3rd Party" }
|
||||||
|
|
||||||
This symbol denotes that the item described is classified as something that changes the overall functionality of the plugin.
|
This symbol denotes that the item described is classified as something that changes the overall functionality of the plugin.
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
### <!-- md:flag metadata --> – Metadata property { #metadata data-toc-label="Metadata property" }
|
### <!-- md:flag setting --> – Configurable Settings { #setting data-toc-label="Configurable Setting" }
|
||||||
|
|
||||||
This symbol denotes that the item described is a metadata property, which can
|
The following denotes a configurable setting. These can also be broken up into individual settings as shown below:
|
||||||
be used in Markdown documents as part of the front matter definition.
|
|
||||||
|
|
||||||
<br />
|
#### <!-- md:setting example.setting.enabled -->
|
||||||
|
<!-- md:version 1.0.0 -->
|
||||||
|
<!-- md:default `true` -->
|
||||||
|
|
||||||
### <!-- md:flag setting --> – Configurable Setting { #setting data-toc-label="Configurable Setting" }
|
This is an example setting
|
||||||
|
|
||||||
This symbol denotes that an item is configurable by the user
|
#### <!-- md:setting example.setting.other -->
|
||||||
|
<!-- md:version 1.0.0 -->
|
||||||
|
<!-- md:default `true` -->
|
||||||
|
|
||||||
|
This is another example setting
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -91,9 +96,23 @@ can be used multiple times in the `plugins` setting in `mkdocs.yml`.
|
|||||||
|
|
||||||
### <!-- md:feature --> – Optional feature { #feature data-toc-label="Optional feature" }
|
### <!-- md:feature --> – Optional feature { #feature data-toc-label="Optional feature" }
|
||||||
|
|
||||||
Most of the features are hidden behind feature flags, which means they must
|
Some features may be hidden behind feature flags, which means they must
|
||||||
be explicitly enabled via `mkdocs.yml`. This allows for the existence of
|
be explicitly enabled first before they can be configured. This allows
|
||||||
potentially orthogonal features.
|
for the existence of potentially orthogonal features.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:markdown --> – Markdown extension { data-toc-label="Markdown extension" #extension }
|
||||||
|
|
||||||
|
This symbol denotes that the thing described is a Markdown element.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### <!-- md:flag dangerous --> – Dangerous { #danger data-toc-label="Dangerous Property" }
|
||||||
|
|
||||||
|
This symbol denotes that the item described is a metadata property, which can
|
||||||
|
be used in Markdown documents as part of the front matter definition.
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@@ -107,3 +126,58 @@ available to backers. Normal users will not have access to this particular item.
|
|||||||
---
|
---
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## Other Tags
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Example Download { #example data-toc-label="Dangerous Property" }
|
||||||
|
<!-- md:example my-example-file -->
|
||||||
|
|
||||||
|
The following denotes a downloadable file.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
<!-- md:command `-s, --start` -->
|
||||||
|
|
||||||
|
The above denotes a command which can be executed in a terminal / command prompt.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
Options are another form of setting which lists what the option does, and then examples of how it works.
|
||||||
|
|
||||||
|
<!-- md:option rss.enabled -->
|
||||||
|
|
||||||
|
: <!-- md:default `true` --> This option specifies whether
|
||||||
|
the plugin is enabled when building your project. If you want to speed up
|
||||||
|
local builds, you can use an [environment variable][mkdocs.env]:
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
plugins:
|
||||||
|
- rss:
|
||||||
|
enabled: !ENV [CI, false]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- md:option rss.match_path -->
|
||||||
|
|
||||||
|
: <!-- md:default `.*` --> This option specifies which
|
||||||
|
pages should be included in the feed. For example, to only include blog
|
||||||
|
posts in the feed, use the following regular expression:
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
plugins:
|
||||||
|
- rss:
|
||||||
|
match_path: blog/posts/.*
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|||||||
236
docs/docs/about/what_is_tvapp.md
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
---
|
||||||
|
title: About TVApp2
|
||||||
|
tags:
|
||||||
|
- info
|
||||||
|
---
|
||||||
|
|
||||||
|
# About
|
||||||
|
|
||||||
|
<figure markdown="span">
|
||||||
|
{ width="60%" }
|
||||||
|
<figcaption>TVApp2 Main Interface</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<h1 align="center"><b>TVApp2: M3U Playlist & Data Guides</b></h1>
|
||||||
|
|
||||||
|
<p align="center" markdown="1">
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
[![Version][github-version-img]][github-version-uri]
|
||||||
|
[![Downloads][github-downloads-img]][github-downloads-uri]
|
||||||
|
[![Size][github-size-img]][github-size-img]
|
||||||
|
[![Last Commit][github-commit-img]][github-commit-img]
|
||||||
|
[![Contributors][contribs-all-img]](#contributors)
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
## What is TVApp2?
|
||||||
|
|
||||||
|
**TVApp2** is a docker image which allows you to download M3U playlists and EPG guide data from various online IPTV services such as **TheTVApp**, **TVPass**, and **MoveOnJoy**. The playlist and guide data files can be imported into your favorite IPTV applications such as Jellyfin, Plex, and Emby.
|
||||||
|
|
||||||
|
Once the docker container is started; a fresh copy of the channel list and TV guide data will be downloaded and generated within your docker container. You can then visit the website URL associated with your docker container; which will give you direct links to the files that you can utilize with the above listed IPTV apps.
|
||||||
|
|
||||||
|
All channels contain multiple sources so that you have a reliable streaming experience, and helps you combat moments when one channel source goes offline.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Image Sources
|
||||||
|
|
||||||
|
This project contains several repositories which all share the same code; use them as backups:
|
||||||
|
|
||||||
|
- [🔀 dockerhub:thebinaryninja/tvapp2](https://hub.docker.com/r/thebinaryninja/tvapp2)
|
||||||
|
- [🔀 github:thebinaryninja/tvapp2](https://github.com/thebinaryninja/tvapp2)
|
||||||
|
- [🔀 gitea:git.binaryninja.net/binaryninja/tvapp2](https://git.binaryninja.net/binaryninja/tvapp2)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
| Pull URL | Registry | Arch | Version |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `ghcr.io/thebinaryninja/tvapp2:latest`<br />`ghcr.io/thebinaryninja/tvapp2:development` | Github | amd64<br/>arm64 | [![Github][github-docker-version-img]][github-docker-version-uri] |
|
||||||
|
| `thebinaryninja/tvapp2:latest`<br />`thebinaryninja/tvapp2:development` | Dockerhub | amd64<br/>arm64 | [![Dockerhub][dockerhub-docker-version-img]][dockerhub-docker-version-uri] |
|
||||||
|
| `git.binaryninja.net/binaryninja/tvapp2:latest`<br />`git.binaryninja.net/binaryninja/tvapp2:development` | Gitea | amd64<br/>arm64 | [![Gitea][gitea-docker-version-img]][gitea-docker-version-uri] |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
The following is a small list of the features available with the TVApp2 container:
|
||||||
|
|
||||||
|
- Multiple IPTV service sources:
|
||||||
|
- TheTVApp
|
||||||
|
- TVPass
|
||||||
|
- MoveOnJoy
|
||||||
|
- Channel playlists can be downloaded as a `.m38u` or a compressed `.gzip` archive.
|
||||||
|
- Compressed gzip compatible with 3rd party apps like Cabernet and Jellyfin.
|
||||||
|
- Tracking statistics which show the last update time, size, and a description for each file's purpose.
|
||||||
|
- API endpoints:
|
||||||
|
- **Resync All Files**
|
||||||
|
- http://127.0.0.1:4124/api/resync
|
||||||
|
- http://127.0.0.1:4124/api/restart
|
||||||
|
- **Health check**
|
||||||
|
- http://127.0.0.1:4124/api/health
|
||||||
|
- http://127.0.0.1:4124/api/status
|
||||||
|
- Direct access to download each of the generated files, including multiple easy-to-remember URLs for each file type.
|
||||||
|
- **M3U Playlist**:
|
||||||
|
- http://127.0.0.1:4124/playlist
|
||||||
|
- http://127.0.0.1:4124/m3u
|
||||||
|
- http://127.0.0.1:4124/m38u
|
||||||
|
- **EPG Guide Data (Uncompressed)**:
|
||||||
|
- http://127.0.0.1:4124/guide
|
||||||
|
- http://127.0.0.1:4124/epg
|
||||||
|
- http://127.0.0.1:4124/xml
|
||||||
|
- **EPG Guide Data (Compressed)**:
|
||||||
|
- http://127.0.0.1:4124/gzip
|
||||||
|
- http://127.0.0.1:4124/gz
|
||||||
|
- Video sources include both quality options `hd` and `sd`.
|
||||||
|
- Easily mountable docker volumes to access the generated files quickly.
|
||||||
|
- Wide variety of docker environment variables to change the binding IP, port, app root directory, quality, timezone, etc.
|
||||||
|
- Small docker image size; based on Alpine 3.x which averages `40MB`.
|
||||||
|
- Compatible with architectures `amd64` and `arm64/aarm64`.
|
||||||
|
- Example configurations for 3rd party apps such as Traefik and Authentik.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## ✨ Contributors
|
||||||
|
|
||||||
|
We are always looking for contributors. If you feel that you can provide something useful to Gistr, then we'd love to review your suggestion. Before submitting your contribution, please review the following resources:
|
||||||
|
|
||||||
|
- [Pull Request Procedure](https://github.com/TheBinaryNinja/tvapp2/blob/main/.github/PULL_REQUEST_TEMPLATE.md)
|
||||||
|
- [Contributor Policy](https://github.com/TheBinaryNinja/tvapp2/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Want to help but can't write code?
|
||||||
|
- Review [active questions by our community](https://github.com/TheBinaryNinja/tvapp2/labels/help%20wanted) and answer the ones you know.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center" markdown="1">
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
The following people have helped get this project going:
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<div align="center" markdown="1">
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||||
|
[![Contributors][contribs-all-img]](#contributors)
|
||||||
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="center" valign="top"><a href="https://github.com/Aetherinox">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/118329232?v=4?s=40" width="80px;" alt="Aetherinox"/><br /><sub><b>Aetherinox</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=Aetherinox" title="Code">💻</a>
|
||||||
|
</td>
|
||||||
|
<td align="center" valign="top"><a href="https://github.com/iFlip721">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/28721588?v=4" width="80px;" alt="iFlip721"/><br /><sub><b>iFlip721</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=iFlip721" title="Code">💻</a>
|
||||||
|
</td>
|
||||||
|
<td align="center" valign="top"><a href="https://github.com/Nvmdfth">
|
||||||
|
<img src="https://avatars.githubusercontent.com/u/32874812?v=4" width="80px;" alt="Nvmdfth"/><br /><sub><b>Optx</b></sub></a><br /><a href="https://github.com/TheBinaryNinja/tvapp2/commits?author=Nvmdfth" title="Code">💻</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
|
||||||
|
<!-- BADGE > GENERAL -->
|
||||||
|
[general-npmjs-uri]: https://npmjs.com
|
||||||
|
[general-nodejs-uri]: https://nodejs.org
|
||||||
|
[general-npmtrends-uri]: http://npmtrends.com/csf-firewall
|
||||||
|
|
||||||
|
<!-- BADGE > VERSION > GITHUB -->
|
||||||
|
[github-version-img]: https://img.shields.io/github/v/tag/TheBinaryNinja/tvapp2?logo=GitHub&label=Version&color=ba5225
|
||||||
|
[github-version-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > LICENSE > MIT -->
|
||||||
|
[license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons&logoColor=FFFFFF&label=License&color=9d29a0
|
||||||
|
[license-mit-uri]: https://github.com/TheBinaryNinja/tvapp2/blob/main/LICENSE
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD COUNT -->
|
||||||
|
[github-downloads-img]: https://img.shields.io/github/downloads/TheBinaryNinja/tvapp2/total?logo=github&logoColor=FFFFFF&label=Downloads&color=376892
|
||||||
|
[github-downloads-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > DOWNLOAD SIZE -->
|
||||||
|
[github-size-img]: https://img.shields.io/github/repo-size/TheBinaryNinja/tvapp2?logo=github&label=Size&color=59702a
|
||||||
|
[github-size-uri]: https://github.com/TheBinaryNinja/tvapp2/releases
|
||||||
|
|
||||||
|
<!-- BADGE > ALL CONTRIBUTORS -->
|
||||||
|
[contribs-all-img]: https://img.shields.io/github/all-contributors/TheBinaryNinja/tvapp2?logo=contributorcovenant&color=de1f6f&label=contributors
|
||||||
|
[contribs-all-uri]: https://github.com/all-contributors/all-contributors
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > NPM -->
|
||||||
|
[github-build-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-release.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > BUILD > Pypi -->
|
||||||
|
[github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/release-pypi.yml?logo=github&logoColor=FFFFFF&label=Build&color=%23278b30
|
||||||
|
[github-build-pypi-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/pypi-release.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > TESTS -->
|
||||||
|
[github-tests-img]: https://img.shields.io/github/actions/workflow/status/TheBinaryNinja/tvapp2/npm-tests.yml?logo=github&label=Tests&color=2c6488
|
||||||
|
[github-tests-uri]: https://github.com/TheBinaryNinja/tvapp2/actions/workflows/npm-tests.yml
|
||||||
|
|
||||||
|
<!-- BADGE > GITHUB > COMMIT -->
|
||||||
|
[github-commit-img]: https://img.shields.io/github/last-commit/TheBinaryNinja/tvapp2?logo=conventionalcommits&logoColor=FFFFFF&label=Last%20Commit&color=313131
|
||||||
|
[github-commit-uri]: https://github.com/TheBinaryNinja/tvapp2/commits/main/
|
||||||
|
|
||||||
|
<!-- BADGE > Github > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[github-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=development-amd64%2Cdevelopment%2Cdevelopment-arm64%2Clatest&label=version&trim=
|
||||||
|
[github-docker-version-uri]: https://github.com/TheBinaryNinja/tvapp2/pkgs/container/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Dockerhub > Docker Image -->
|
||||||
|
[dockerhub-docker-version-img]: https://img.shields.io/docker/v/thebinaryninja/tvapp2?sort=semver&arch=arm64
|
||||||
|
[dockerhub-docker-version-uri]: https://hub.docker.com/repository/docker/thebinaryninja/tvapp2/general
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea > Docker Image > SELFHOSTED BADGES -->
|
||||||
|
[gitea-docker-version-img]: https://badges-ghcr.onrender.com/thebinaryninja/tvapp2/latest_tag?color=%233d9e18&ignore=latest&label=version&trim=
|
||||||
|
[gitea-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/tvapp2
|
||||||
|
|
||||||
|
<!-- BADGE > Gitea 2 > Docker Image -->
|
||||||
|
[gitea2-docker-version-img]: https://img.shields.io/gitea/v/release/binaryninja/tvapp2?gitea_url=https%3A%2F%2Fgit.binaryninja.net
|
||||||
|
[gitea2-docker-version-uri]: https://git.binaryninja.net/BinaryNinja/-/packages/container/tvapp2/latest
|
||||||
|
|
||||||
|
<!-- BADGE > BUTTON > SUBMIT ISSUES -->
|
||||||
|
[btn-github-submit-img]: https://img.shields.io/badge/submit%20new%20issue-de1f5c?style=for-the-badge&logo=github&logoColor=FFFFFF
|
||||||
|
[btn-github-submit-uri]: https://github.com/TheBinaryNinja/tvapp2/issues
|
||||||
|
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
title: About TVApp2
|
|
||||||
tags:
|
|
||||||
- info
|
|
||||||
---
|
|
||||||
|
|
||||||
# About TVApp2
|
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<br />
|
|
||||||
BIN
docs/docs/assets/images/health-toast.gif
Normal file
|
After Width: | Height: | Size: 16 KiB |
521
docs/docs/config/env.md
Normal file
@@ -0,0 +1,521 @@
|
|||||||
|
---
|
||||||
|
title: Environment Variables
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
---
|
||||||
|
|
||||||
|
# Environment Variables
|
||||||
|
|
||||||
|
Environment variables allow you to modify how TVApp2 functions within a docker container. Ensure that
|
||||||
|
you understand the setting you are changing before you modify these values, otherwise, TVApp2 may fail to
|
||||||
|
start due to misconfigurations.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## TZ
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `Etc/UTC` -->
|
||||||
|
|
||||||
|
The `TZ` environment variable specifies the timezone that your docker container will
|
||||||
|
utilize. This is useful for syncing your local time with console outputs such as
|
||||||
|
our logging system.
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- TZ=Etc/UTC # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this env variable will change the time for anything
|
||||||
|
related to the TVApp2 docker container.
|
||||||
|
|
||||||
|
=== "Timezones"
|
||||||
|
|
||||||
|
``` yaml
|
||||||
|
Etc/UTC
|
||||||
|
Africa/Cairo
|
||||||
|
Africa/Johannesburg
|
||||||
|
Africa/Lagos
|
||||||
|
America/Argentina/Buenos_Aires
|
||||||
|
America/Bogota
|
||||||
|
America/Caracas
|
||||||
|
America/Chicago
|
||||||
|
America/El_Salvador
|
||||||
|
America/Juneau
|
||||||
|
America/Lima
|
||||||
|
America/Los_Angeles
|
||||||
|
America/Mexico_City
|
||||||
|
America/New_York
|
||||||
|
America/Phoenix
|
||||||
|
America/Santiago
|
||||||
|
America/Sao_Paulo
|
||||||
|
America/Toronto
|
||||||
|
America/Vancouver
|
||||||
|
Asia/Almaty
|
||||||
|
Asia/Ashkhabad
|
||||||
|
Asia/Bahrain
|
||||||
|
Asia/Bangkok
|
||||||
|
Asia/Chongqing
|
||||||
|
Asia/Dubai
|
||||||
|
Asia/Ho_Chi_Minh
|
||||||
|
Asia/Hong_Kong
|
||||||
|
Asia/Jakarta
|
||||||
|
Asia/Jerusalem
|
||||||
|
Asia/Kathmandu
|
||||||
|
Asia/Kolkata
|
||||||
|
Asia/Kuwait
|
||||||
|
Asia/Muscat
|
||||||
|
Asia/Qatar
|
||||||
|
Asia/Riyadh
|
||||||
|
Asia/Seoul
|
||||||
|
Asia/Shanghai
|
||||||
|
Asia/Singapore
|
||||||
|
Asia/Taipei
|
||||||
|
Asia/Tehran
|
||||||
|
Asia/Tokyo
|
||||||
|
Atlantic/Reykjavik
|
||||||
|
Australia/ACT
|
||||||
|
Australia/Adelaide
|
||||||
|
Australia/Brisbane
|
||||||
|
Australia/Sydney
|
||||||
|
Europe/Athens
|
||||||
|
Europe/Belgrade
|
||||||
|
Europe/Berlin
|
||||||
|
Europe/Copenhagen
|
||||||
|
Europe/Helsinki
|
||||||
|
Europe/Istanbul
|
||||||
|
Europe/London
|
||||||
|
Europe/Luxembourg
|
||||||
|
Europe/Madrid
|
||||||
|
Europe/Moscow
|
||||||
|
Europe/Paris
|
||||||
|
Europe/Riga
|
||||||
|
Europe/Rome
|
||||||
|
Europe/Stockholm
|
||||||
|
Europe/Tallinn
|
||||||
|
Europe/Vilnius
|
||||||
|
Europe/Warsaw
|
||||||
|
Europe/Zurich
|
||||||
|
Pacific/Auckland
|
||||||
|
Pacific/Chatham
|
||||||
|
Pacific/Fakaofo
|
||||||
|
Pacific/Honolulu
|
||||||
|
Pacific/Norfolk
|
||||||
|
US/Mountain
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## WEB_IP
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `0.0.0.0` -->
|
||||||
|
|
||||||
|
The `WEB_IP` environment variable allows you to define what IP address will be
|
||||||
|
bound to the TVApp2 docker image.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- WEB_IP=0.0.0.0 # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Specify `0.0.0.0` to bind to all local IP addresses.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## WEB_PORT
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `4124` -->
|
||||||
|
|
||||||
|
The `WEB_PORT` environment variable allows you to define what port the TVApp2
|
||||||
|
docker container will listen to.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- WEB_IP=4124 # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: The default port is `4124`
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## WEB_ENCODING
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.3.0 -->
|
||||||
|
<!-- md:default `deflate, br` -->
|
||||||
|
|
||||||
|
The `WEB_ENCODING` environment variable allows you to customize the HTTP `Accept-Encoding` request and response header. This value specifies what content encoding the sender can understand when sending these requests.
|
||||||
|
|
||||||
|
Most users will not need to modify this value unless you are running Jellyfin and receive the following error when attempting to sync EPG data between Jellyfin and the TVApp2 container:
|
||||||
|
|
||||||
|
!!! warning "Jellyfin Error"
|
||||||
|
|
||||||
|
```
|
||||||
|
[ERR] [27] Jellyfin.LiveTv.Guide.GuideManager: Error getting programs for channel
|
||||||
|
XXXXXXXXXXXXXXX (Source 2) System.Xml.XmlException: '', hexadecimal value 0x1F,
|
||||||
|
is an invalid character. Line 1, position 1.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you receive the above error and you have already customized this environment variable to include `gzip`, you must remove it from your accepted encoders string to fix the error.
|
||||||
|
|
||||||
|
=== "Old"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- WEB_ENCODING: 'gzip, deflate, br'
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "New"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- WEB_ENCODING: 'deflate, br'
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## URL_REPO
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `https://git.binaryninja.net/binaryninja` -->
|
||||||
|
<!-- md:flag dangerous -->
|
||||||
|
|
||||||
|
The `URL_REPO` environment variable allows you to specify what Github repo is used to communicate
|
||||||
|
with in order to fetch IPTV data. This is used as an internal environment variable by the developers
|
||||||
|
and should not be changed by the end-user; otherwise you will be unable to fetch IPTV data.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- URL_REPO=https://git.binaryninja.net/binaryninja # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :warning: It is highly recommended that you do not change this value
|
||||||
|
otherwise you will not be able to download the latest M3U playlists
|
||||||
|
and EPG guide data.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## FILE_URL
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.2.0 -->
|
||||||
|
<!-- md:default `urls.txt` -->
|
||||||
|
|
||||||
|
The `FILE_URL` environment variable allows you to specify what the name of the downloaded `urls.txt` cache file. This file is downloaded when you first spin up the TVApp2 container.
|
||||||
|
|
||||||
|
There should be no need to utilize this environment variable unless you have a specific reason.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- FILE_URL=urls.txt # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :warning: There is really no reason to modify this environment variable
|
||||||
|
unless you have a specific purpose.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## FILE_M3U
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.1.0 -->
|
||||||
|
<!-- md:default `playlist.m3u8` -->
|
||||||
|
|
||||||
|
The `FILE_M3U` environment variable allows you to specify what the name of the downloaded `playlist.m3u8` file will be. This file is downloaded when you first spin up the TVApp2 container, and contains a list of what channels you can pick from.
|
||||||
|
|
||||||
|
There should be no need to utilize this environment variable unless you have a specific reason.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- FILE_M3U=playlist.m3u8 # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :warning: There is really no reason to modify this environment variable
|
||||||
|
unless you have a specific purpose.
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## FILE_EPG
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.1.0 -->
|
||||||
|
<!-- md:default `xmltv.xml` -->
|
||||||
|
|
||||||
|
The `FILE_EPG` environment variable specifies the filename that will be utilized when
|
||||||
|
your .xml EPG playlist file is generated.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- FILE_EPG=xmltv.xml # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this file only changes the filename locally; it does
|
||||||
|
not affect the server-side fetching mechanism.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## FILE_GZIP
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.1.0 -->
|
||||||
|
<!-- md:default `xmltv.xml.gz` -->
|
||||||
|
|
||||||
|
The `FILE_GZIP` environment variable specifies the filename that will be utilized when
|
||||||
|
a compressed `.gzip` is generated and when you download the file.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- FILE_GZIP=xmltv.xml.gz # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this file only changes the filename locally for
|
||||||
|
generation and downloading. It does not affect the server-side fetching
|
||||||
|
mechanism.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## STREAM_QUALITY
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.1.0 -->
|
||||||
|
<!-- md:default `hd` -->
|
||||||
|
|
||||||
|
The `STREAM_QUALITY` environment variable specifies the default stream quality that will
|
||||||
|
be used when you initiate a new channel to view.
|
||||||
|
|
||||||
|
Available Options:
|
||||||
|
|
||||||
|
* `hd` High Definition
|
||||||
|
* `sd` Standard Definition
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- STREAM_QUALITY=hd # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: This environment variable has the following options:
|
||||||
|
- hd
|
||||||
|
- sd
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## DIR_BUILD
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `/usr/src/app` -->
|
||||||
|
<!-- md:flag dangerous -->
|
||||||
|
|
||||||
|
The `DIR_BUILD` environment variable specifies what local folder will be utilized
|
||||||
|
by the TVApp2 docker container when the container builds the app.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- DIR_BUILD=/usr/src/app # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :warning: You should not change this unless you are an advanced user.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## DIR_RUN
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
<!-- md:default `/usr/src/app` -->
|
||||||
|
<!-- md:flag dangerous -->
|
||||||
|
|
||||||
|
The `DIR_RUN` environment variable specifies what local folder will be utilized
|
||||||
|
by the TVApp2 docker container when the container has built the app and placed it
|
||||||
|
into a production folder.
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- DIR_RUN=/usr/bin/app # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :warning: You should not change this unless you are an advanced user.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## LOG_LEVEL
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.1.0 -->
|
||||||
|
<!-- md:default `4` -->
|
||||||
|
|
||||||
|
The `LOG_LEVEL` environment variable allows you specify how deep logs should go
|
||||||
|
when being output to your console.
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- LOG_LEVEL=4 # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: The default log level is `4` (info).
|
||||||
|
|
||||||
|
=== "Log Levels"
|
||||||
|
|
||||||
|
| Log Level | Name | Description |
|
||||||
|
| --------------- | ----------- | ------------------------------------------------------------------------------- |
|
||||||
|
| `6` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-trace-color) " } Trace | Displays all possible logs in console, along with anything below this line. |
|
||||||
|
| `5` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-debug-color) " } Debug | Displays debug / developer logs, along with anything below this line. |
|
||||||
|
| `4` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-info-color) " } Info | Displays informative logs, along with anything below this line. |
|
||||||
|
| `3` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-notice-color) " } Notice | Displays important notices, along with anything below this line. |
|
||||||
|
| `2` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-warn-color) " } Warn | Displays warnings, along with anything below this line. |
|
||||||
|
| `1` | :material-checkbox-blank-circle:{ style="color: var(--md-loglevel-error-color) " } Error | Displays only errors, none of the log levels above this line will be shown |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
109
docs/docs/config/volumes.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
---
|
||||||
|
title: Environment Variables
|
||||||
|
tags:
|
||||||
|
- config
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mountable Volumes
|
||||||
|
|
||||||
|
Mountable volumes in Docker allow you to share folders within a docker container with your host machine. This allows you to access these specific files without having to bash into the container and using the terminal to navigate around.
|
||||||
|
|
||||||
|
The TVApp2 docker image provides a few different paths that you can mount to your host machine; as outlined below.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 📁 /usr/bin/app
|
||||||
|
|
||||||
|
<!-- md:control volume -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
|
||||||
|
The mountable volume `/usr/bin/app` is where TVApp2 files will be placed once the app has been built when your docker container spins up. The files in this folder include:
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `📁 node_modules` | List of all NodeJS packages utilized by TVApp2 |
|
||||||
|
| `📁 www` | Main storage folder for TVApp2. Contains website files and M3U / EPG synced files |
|
||||||
|
| `📄 package.json` | NodeJS package file |
|
||||||
|
| `📄 playlist.m3u8` | Generated playlist containing channels |
|
||||||
|
| `📄 urls.txt` | List containing cached URLs utilized by TVApp2 |
|
||||||
|
| `📄 xmltv.xml` | EPG guide data in uncompressed XML format |
|
||||||
|
| `📄 xmltv.xml.gz` | EPG guide data in compressed GZ archive |
|
||||||
|
| `📄 index.js` | Main source code file for TVApp2 |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./app:/usr/bin/app # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this env variable will change the time for anything
|
||||||
|
related to the TVApp2 docker container.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
This folder path can be changed by specifying a new path with the environment variable `DIR_RUN`
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./app:/usr/bin/app # (1) (2)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this env variable will change the folder within the docker container which stores the fully built TVApp2 files.
|
||||||
|
|
||||||
|
2. This should not be used unless you know what you're doing
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 📁 /config
|
||||||
|
|
||||||
|
<!-- md:control volume -->
|
||||||
|
<!-- md:version stable-1.0.0 -->
|
||||||
|
|
||||||
|
The mountable volume `/config` defines where the TVApp2 application will store SSL certificates related to the TVApp2 web interface being ran using https instead of http. The files in this folder include:
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `📁 keys` | Folder which stores the SSL cert and keys |
|
||||||
|
| `📄 keys/cert.crt` | SSL public certificate |
|
||||||
|
| `📄 keys/key.crt` | SSL private key |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="7" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./config:/config # (1) (2)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Changing this env variable will change the folder within the docker container which stores the fully built TVApp2 files.
|
||||||
|
|
||||||
|
2. This should not be used unless you know what you're doing
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
13
docs/docs/includes/abbreviations.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[mkdocs]: https://www.mkdocs.org
|
||||||
|
[mkdocs.dotfiles]: https://www.mkdocs.org/dev-guide/themes/#dot-files
|
||||||
|
[mkdocs.metadata]: https://www.mkdocs.org/user-guide/writing-your-docs/#yaml-style-meta-data
|
||||||
|
[mkdocs.env]: https://www.mkdocs.org/user-guide/configuration/#environment-variables
|
||||||
|
[mkdocs.docs_dir]: https://www.mkdocs.org/user-guide/configuration/#docs_dir
|
||||||
|
[mkdocs.extra_templates]: https://www.mkdocs.org/user-guide/configuration/#extra_templates
|
||||||
|
[mkdocs.site_dir]: https://www.mkdocs.org/user-guide/configuration/#site_dir
|
||||||
|
[mkdocs.site_url]: https://www.mkdocs.org/user-guide/configuration/#site_url
|
||||||
|
[mkdocs.site_description]: https://www.mkdocs.org/user-guide/configuration/#site_description
|
||||||
|
[mkdocs.nav]: https://www.mkdocs.org/user-guide/configuration/#nav
|
||||||
|
[mkdocs.plugins]: https://www.mkdocs.org/user-guide/configuration/#plugins
|
||||||
|
[mkdocs.strict]: https://www.mkdocs.org/user-guide/configuration/#strict
|
||||||
|
[mkdocs.use_directory_urls]: https://www.mkdocs.org/user-guide/configuration/#use_directory_urls
|
||||||
125
docs/docs/install/docker-run.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
---
|
||||||
|
title: "Install: docker-run"
|
||||||
|
tags:
|
||||||
|
- install
|
||||||
|
---
|
||||||
|
|
||||||
|
# docker run
|
||||||
|
|
||||||
|
Our documentation provides two ways that you may start up a TVApp2 docker container:
|
||||||
|
|
||||||
|
<div class="grid cards" markdown>
|
||||||
|
|
||||||
|
- :material-circle: [docker run](docker-run.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Spin up the TVApp2 container using the `docker run` command.
|
||||||
|
This is useful for quick launches, but is not time efficient
|
||||||
|
if you plan to use this container long-term.
|
||||||
|
|
||||||
|
This requires a longer command that must be used each time
|
||||||
|
you wish to bring the container up.
|
||||||
|
|
||||||
|
- :material-circle: [docker compose](docker-compose.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Spin up the TVApp2 container by creating a `📄 docker-compose.yml`
|
||||||
|
file which will store all of your options such as env variables,
|
||||||
|
mounted volumes, and labels.
|
||||||
|
|
||||||
|
To bring the container up, `cd` into the folder with the
|
||||||
|
`📄 docker-compose.yml` file, and run the
|
||||||
|
command `docker compose up -d`.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
The `🗔 docker run` command allows you to start up a docker container by providing a set of [options](#command-options) which define how the container should operate, including the environment variables, mounted volumes, assigned IP address, etc.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Start TVApp2
|
||||||
|
|
||||||
|
Pulling the image if needed and starting the container. To spin up a TVApp2 container using this method; run a command similar to the below example. See the section [Options](#options) below for a list of what you can specify.
|
||||||
|
|
||||||
|
=== "Terminal"
|
||||||
|
|
||||||
|
```shell
|
||||||
|
docker run -d \
|
||||||
|
--restart=unless-stopped \ # (1)!
|
||||||
|
--name tvapp2 \ # (2)!
|
||||||
|
-p 4124:4124 \ # (3)!
|
||||||
|
-e "TZ=Etc/UTC" \ # (4)!
|
||||||
|
-v ${PWD}/app:/usr/bin/app \ # (5)!
|
||||||
|
ghcr.io/thebinaryninja/tvapp2:latest # (6)!
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Specifies what happens if the container becomes unresponsive or goes down.
|
||||||
|
2. Name to assign the container; otherwise, a random id will be given.
|
||||||
|
3. Port that will be used for the container
|
||||||
|
4. Environment variable which specifies the timezone to use for the container.
|
||||||
|
5. Mount the container volume `/usr/bin/app` to your host machine in the subfolder `./app`
|
||||||
|
6. Specifies what docker image to spin up.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
To confirm that the container has been brought up, run the command `docker ps | grep tvapp2`. If you have the app [Portainer](https://portainer.io/), you can sign into your admin interface and view your TVApp2 container details, instead of using a command-line.
|
||||||
|
|
||||||
|
```
|
||||||
|
e95236c42b43 binaryninja/tvapp2:1.4.0 "/init" 3 seconds ago Up 3 seconds 4124/tcp tvapp2
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
Review the list of docker run options below. These allow you to define how a docker container will start up.
|
||||||
|
|
||||||
|
???- note "Official Docker Documentation"
|
||||||
|
To view a full list of the available docker parameters, view the official docker documentation at:
|
||||||
|
|
||||||
|
- https://docs.docker.com/reference/cli/docker/container/run/
|
||||||
|
|
||||||
|
| Parameter / Flag | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| `-d, --detach` | Run container in background and print container ID |
|
||||||
|
| `-e, --env` | Set environment variable |
|
||||||
|
| `--env-file` | Read in a file of environment variables |
|
||||||
|
| `--expose` | Expose a port or a range of ports |
|
||||||
|
| `--health-cmd` | Command to run to check health |
|
||||||
|
| `--health-interval` | Time between running the check<br/>`ms|s|m|h` (default 0s) |
|
||||||
|
| `--health-retries` | Consecutive failures needed to report unhealthy |
|
||||||
|
| `--health-start-interval` | Time between running the check during the start period<br/>`ms|s|m|h` (default 0s) |
|
||||||
|
| `--health-start-period` | Start period for the container to initialize before starting health-retries countdown<br/>`ms|s|m|h` (default 0s) |
|
||||||
|
| `--health-timeout` | Maximum time to allow one check to run<br/>`ms|s|m|h` (default 0s) |
|
||||||
|
| `-h, --hostname` | Container host name |
|
||||||
|
| `--ip` | IPv4 address (e.g., 172.30.100.104) |
|
||||||
|
| `--ip6` | IPv6 address (e.g., 2001:db8::33) |
|
||||||
|
| `-l, --label` | Set meta data on a container |
|
||||||
|
| `--mount` | Attach a filesystem mount to the container |
|
||||||
|
| `--name` | Assign a name to the container |
|
||||||
|
| `--network` | Connect a container to a network |
|
||||||
|
| `--privileged` | Give extended privileges to this container |
|
||||||
|
| `-p, --publish` | Publish a container's port(s) to the host |
|
||||||
|
| `--pull` | Pull image before running<br/>`always`, `missing`, `never` |
|
||||||
|
| `--restart` | Restart policy to apply when a container exits <br/> `on-failure[:max-retries]`, `always`, `unless-stopped` |
|
||||||
|
| `-u, --user` | Username or UID <br/>`<name|uid>[:<group|gid>]` |
|
||||||
|
| `-v, --volume` | Bind mount a volume |
|
||||||
|
| `-w, --workdir` | Working directory inside the container |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
47
docs/docs/install/index.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
title: Install
|
||||||
|
tags:
|
||||||
|
- install
|
||||||
|
---
|
||||||
|
|
||||||
|
# Installing TVApp2
|
||||||
|
|
||||||
|
To install TVApp2 using docker; you will need to use either the `🗔 docker run` command, or create a `📄 docker-compose.yml` file which contains information about how to pull the latest image and spin the container up. We have provided instructions for both.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
{==
|
||||||
|
|
||||||
|
Select your desired option to bring up the TVApp2 container with:
|
||||||
|
|
||||||
|
==}
|
||||||
|
|
||||||
|
<div class="grid cards" markdown>
|
||||||
|
|
||||||
|
- :material-circle: [docker run](docker-run.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Spin up the TVApp2 container using the `docker run` command.
|
||||||
|
This is useful for quick launches, but is not time efficient
|
||||||
|
if you plan to use this container long-term.
|
||||||
|
|
||||||
|
This requires a longer command that must be used each time
|
||||||
|
you wish to bring the container up.
|
||||||
|
|
||||||
|
- :material-circle: [docker compose](docker-compose.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Spin up the TVApp2 container by creating a `📄 docker-compose.yml`
|
||||||
|
file which will store all of your options such as env variables,
|
||||||
|
mounted volumes, and labels.
|
||||||
|
|
||||||
|
To bring the container up, `cd` into the folder with the
|
||||||
|
`📄 docker-compose.yml` file, and run the
|
||||||
|
command `docker compose up -d`.
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
6
docs/docs/javascripts/tablesort.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
document$.subscribe(function() {
|
||||||
|
var tables = document.querySelectorAll("article table:not([class])")
|
||||||
|
tables.forEach(function(table) {
|
||||||
|
new Tablesort(table)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -5,6 +5,16 @@
|
|||||||
[ data-md-color-scheme="default" ]
|
[ data-md-color-scheme="default" ]
|
||||||
{
|
{
|
||||||
|
|
||||||
|
--md-accent-fg-color--transparent: #1b1b1b2f;
|
||||||
|
--md-typeset-a-color: #568afa;
|
||||||
|
--md-badge-icon-color: #2b2b2b;
|
||||||
|
--md-badge-icon-hover-color: #568afa;
|
||||||
|
--md-badge-bg-color--transparent: #1b1b1b2f;
|
||||||
|
--md-badge-bg-hover-color: #1b1b1b2f;
|
||||||
|
--md-table-head-bg-color: #597dd2;
|
||||||
|
--md-table-body-bg-color: rgb(221, 221, 221);
|
||||||
|
--md-table-body-text-color: rgb(20, 20, 20);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tag > Background Color
|
Tag > Background Color
|
||||||
*/
|
*/
|
||||||
@@ -24,15 +34,6 @@
|
|||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Badge > Left Box (Icon
|
|
||||||
*/
|
|
||||||
|
|
||||||
.md-typeset .mdx-badge__icon
|
|
||||||
{
|
|
||||||
background-color: var(--md-accent-fg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Badges > Right Box
|
Badges > Right Box
|
||||||
*/
|
*/
|
||||||
@@ -52,15 +53,6 @@
|
|||||||
color: #FFF;
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Badge > Icon Color
|
|
||||||
*/
|
|
||||||
|
|
||||||
.md-typeset .mdx-badge svg
|
|
||||||
{
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Make <small>text</small> opaque. used for changelog to show date
|
Make <small>text</small> opaque. used for changelog to show date
|
||||||
*/
|
*/
|
||||||
@@ -84,16 +76,10 @@
|
|||||||
margin-inline-end: 5px;
|
margin-inline-end: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 .mdx-badge svg
|
|
||||||
{
|
|
||||||
padding-left: 2px;
|
|
||||||
padding-top: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-box {
|
.color-box {
|
||||||
float: left;
|
float: left;
|
||||||
height: 24px;
|
height: 21px;
|
||||||
width: 24px;
|
width: 21px;
|
||||||
border: 1px solid rgba( 255, 255, 255, 0.2 );
|
border: 1px solid rgba( 255, 255, 255, 0.2 );
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
@@ -111,11 +97,6 @@
|
|||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-typeset table:not([class]) tbody tr
|
|
||||||
{
|
|
||||||
background-color: rgb(255, 255, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Table > Outter Border / Background
|
Table > Outter Border / Background
|
||||||
*/
|
*/
|
||||||
@@ -125,6 +106,17 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md-typeset table:not([class]) td
|
||||||
|
{
|
||||||
|
border-top: 2px solid var(--md-typeset-table-color);
|
||||||
|
padding: .9375em 1.25em;
|
||||||
|
padding-top: 0.9375em;
|
||||||
|
padding-bottom: 0.9375em;
|
||||||
|
padding-left: 1.25em;
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Table > Outter Border / Background
|
Table > Outter Border / Background
|
||||||
*/
|
*/
|
||||||
@@ -156,15 +148,6 @@
|
|||||||
{
|
{
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/*background-color: var(--md-code-bg-color);*/
|
/*background-color: var(--md-code-bg-color);*/
|
||||||
min-width: 25%;
|
|
||||||
border-right: 1px solid rgba( 255, 255, 255, 0.14);
|
|
||||||
background-color: rgba(194, 194, 194, 0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-typeset__table thead
|
|
||||||
{
|
|
||||||
background-color: var(--md-accent-fg-color);
|
|
||||||
color: #FFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -196,6 +179,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[dir="ltr"] .md-typeset table th[role="columnheader"]::after
|
||||||
|
{
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Theme > Main
|
Theme > Main
|
||||||
*/
|
*/
|
||||||
@@ -208,6 +196,13 @@
|
|||||||
--md-tooltip-width: 400px;
|
--md-tooltip-width: 400px;
|
||||||
--glow-color: hsl(186 100% 69%);
|
--glow-color: hsl(186 100% 69%);
|
||||||
|
|
||||||
|
--md-loglevel-error-color: #f06090;
|
||||||
|
--md-loglevel-warn-color: #e6695b;
|
||||||
|
--md-loglevel-notice-color: #e2d55e;
|
||||||
|
--md-loglevel-info-color: #6791e0;
|
||||||
|
--md-loglevel-debug-color: #c973d9;
|
||||||
|
--md-loglevel-trace-color: hsla(225deg,15%,90%,0.56);
|
||||||
|
|
||||||
--md-default-fg-color: hsla(var(--md-hue),15%,90%,0.82);
|
--md-default-fg-color: hsla(var(--md-hue),15%,90%,0.82);
|
||||||
--md-default-fg-color--light: hsla(var(--md-hue),15%,90%,0.56);
|
--md-default-fg-color--light: hsla(var(--md-hue),15%,90%,0.56);
|
||||||
--md-default-fg-color--lighter: hsla(var(--md-hue),15%,90%,0.32);
|
--md-default-fg-color--lighter: hsla(var(--md-hue),15%,90%,0.32);
|
||||||
@@ -233,29 +228,42 @@
|
|||||||
--md-code-hl-generic-color: var(--md-default-fg-color--light);
|
--md-code-hl-generic-color: var(--md-default-fg-color--light);
|
||||||
--md-code-hl-variable-color: var(--md-default-fg-color--light);
|
--md-code-hl-variable-color: var(--md-default-fg-color--light);
|
||||||
--md-typeset-color: var(--md-default-fg-color);
|
--md-typeset-color: var(--md-default-fg-color);
|
||||||
--md-typeset-a-color: #568afa;
|
--md-typeset-a-color: #f91d5b;
|
||||||
|
--md-badge-icon-color: #d0d0d0;
|
||||||
|
--md-badge-icon-hover-color: #568afa;
|
||||||
|
--md-badge-bg-color--transparent: #ffffff1c;
|
||||||
|
--md-badge-bg-hover-color: #FFFFFF2E;
|
||||||
--md-typeset-kbd-color: hsla(var(--md-hue),15%,90%,0.12);
|
--md-typeset-kbd-color: hsla(var(--md-hue),15%,90%,0.12);
|
||||||
--md-typeset-kbd-accent-color: hsla(var(--md-hue),15%,90%,0.2);
|
--md-typeset-kbd-accent-color: hsla(var(--md-hue),15%,90%,0.2);
|
||||||
--md-typeset-kbd-border-color: hsla(var(--md-hue),15%,14%,1);
|
--md-typeset-kbd-border-color: hsla(var(--md-hue),15%,14%,1);
|
||||||
--md-typeset-mark-color: #4287ff4d;
|
--md-typeset-mark-color: #4287ff4d;
|
||||||
--md-typeset-table-color: hsla(var(--md-hue),15%,95%,0.12);
|
--md-typeset-table-color: hsla(0%, 0%, 40%, 0.12);
|
||||||
--md-typeset-table-color--light: hsla(var(--md-hue),15%,95%,0.035);
|
--md-typeset-table-color--light: hsla(var(--md-hue),15%,95%,0.035);
|
||||||
--md-admonition-fg-color: var(--md-default-fg-color);
|
--md-admonition-fg-color: var(--md-default-fg-color);
|
||||||
--md-admonition-bg-color: var(--md-default-bg-color);
|
--md-admonition-bg-color: var(--md-default-bg-color);
|
||||||
--md-footer-bg-color: rgba( 34, 34, 34, 1 );
|
--md-footer-bg-color: rgba( 17, 17, 17, 1 );
|
||||||
--md-footer-bg-color--dark: rgba( 15, 15, 15, 1 );
|
--md-footer-bg-color--dark: rgba( 13, 13, 13, 1 );
|
||||||
--md-shadow-z1: 0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;
|
--md-shadow-z1: 0 0.2rem 0.5rem #0000000d,0 0 0.05rem #0000001a;
|
||||||
--md-shadow-z2: 0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;
|
--md-shadow-z2: 0 0.2rem 0.5rem #00000040,0 0 0.05rem #00000040;
|
||||||
--md-shadow-z3: 0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;
|
--md-shadow-z3: 0 0.2rem 0.5rem #0006,0 0 0.05rem #00000059;
|
||||||
|
--md-table-head-bg-color: #860038;
|
||||||
|
--md-table-body-text-color: rgb(231, 231, 231);
|
||||||
|
--md-accent-fg-color--transparent: #FFFFFF2E;
|
||||||
--md-admonition-icon--pied-piper: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9zm135.9 197.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM340.8 177c6.6 2.8 11.5 9.2 22.7 22.1 2-1.4 7.5-5.2 7.5-8.6 0-4.9-11.8-13.2-13.2-23 11.2-5.7 25.2-6 37.6-8.9 68.1-16.4 116.3-52.9 146.8-116.7C548.3 29.3 554 16.1 554.6 2l-2 2.6c-28.4 50-33 63.2-81.3 100-31.9 24.4-69.2 40.2-106.6 54.6l-6.3-.3v-21.8c-19.6 1.6-19.7-14.6-31.6-23-18.7 20.6-31.6 40.8-58.9 51.1-12.7 4.8-19.6 10-25.9 21.8 34.9-16.4 91.2-13.5 98.8-10zM555.5 0l-.6 1.1-.3.9.6-.6zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46.1v27.2l11.8-3.4-2.9-23.8zm-68.7-150.4l24.1 61.2 21-13.8-31.3-50.9zm84.4 154.9l2 12.4c9-1.5 58.4-6.6 58.4-14.1 0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3z"/></svg>');
|
--md-admonition-icon--pied-piper: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9zm135.9 197.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM340.8 177c6.6 2.8 11.5 9.2 22.7 22.1 2-1.4 7.5-5.2 7.5-8.6 0-4.9-11.8-13.2-13.2-23 11.2-5.7 25.2-6 37.6-8.9 68.1-16.4 116.3-52.9 146.8-116.7C548.3 29.3 554 16.1 554.6 2l-2 2.6c-28.4 50-33 63.2-81.3 100-31.9 24.4-69.2 40.2-106.6 54.6l-6.3-.3v-21.8c-19.6 1.6-19.7-14.6-31.6-23-18.7 20.6-31.6 40.8-58.9 51.1-12.7 4.8-19.6 10-25.9 21.8 34.9-16.4 91.2-13.5 98.8-10zM555.5 0l-.6 1.1-.3.9.6-.6zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46.1v27.2l11.8-3.4-2.9-23.8zm-68.7-150.4l24.1 61.2 21-13.8-31.3-50.9zm84.4 154.9l2 12.4c9-1.5 58.4-6.6 58.4-14.1 0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3z"/></svg>');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Tag > Background Color
|
Navigation > Tabs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.md-typeset .md-tag
|
.md-tabs
|
||||||
{
|
{
|
||||||
background-color: var(--md-primary-fg-color);
|
background-color: #860038;
|
||||||
|
color: var(--md-primary-bg-color);
|
||||||
|
display: block;
|
||||||
|
line-height: 1.3;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -264,8 +272,8 @@
|
|||||||
|
|
||||||
.md-nav
|
.md-nav
|
||||||
{
|
{
|
||||||
font-size: .6rem;
|
font-size: .7rem;
|
||||||
line-height: 1.3;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdx-container
|
.mdx-container
|
||||||
@@ -276,12 +284,18 @@
|
|||||||
|
|
||||||
.md-main
|
.md-main
|
||||||
{
|
{
|
||||||
background-color: hsla(140, 0%, 5%, 1) !important;
|
background-color: #161618 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-main__inner
|
||||||
|
{
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-typeset table:not([ class ] ) tbody tr
|
.md-typeset table:not([ class ] ) tbody tr
|
||||||
{
|
{
|
||||||
background-color: rgb( 17, 15, 15 );
|
background-color: rgb( 15, 15, 15 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -315,14 +329,6 @@
|
|||||||
{
|
{
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/*background-color: var(--md-code-bg-color);*/
|
/*background-color: var(--md-code-bg-color);*/
|
||||||
min-width: 25%;
|
|
||||||
border-right: 1px solid rgba( 255, 255, 255, 0.14);
|
|
||||||
background-color: rgba(70, 65, 77, 0.36);
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-typeset__table thead
|
|
||||||
{
|
|
||||||
background-color: #b10f52;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -417,16 +423,28 @@
|
|||||||
|
|
||||||
.md-typeset .tabbed-labels
|
.md-typeset .tabbed-labels
|
||||||
{
|
{
|
||||||
background-color: #090909;
|
background-color: #0b0b0b;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-left: 1px solid #242735;
|
||||||
|
border-top: 1px solid #242735;
|
||||||
|
border-right: 1px solid #242735;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
.tabbed-labels::before
|
||||||
Badge > Left Box (Icon
|
|
||||||
*/
|
|
||||||
|
|
||||||
.md-typeset .mdx-badge__icon
|
|
||||||
{
|
{
|
||||||
background-color: #3f4faa;
|
background: hsla(343.1, 87.9%, 51.6%, 0.82);
|
||||||
|
bottom: 0;
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
height: 2px;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
transform: translateX(var(--md-indicator-x));
|
||||||
|
transition: width 225ms,background-color .25s,transform .25s;
|
||||||
|
transition-timing-function: ease, ease, ease;
|
||||||
|
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||||
|
width: var(--md-indicator-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -453,8 +471,7 @@
|
|||||||
|
|
||||||
h3 .mdx-badge svg
|
h3 .mdx-badge svg
|
||||||
{
|
{
|
||||||
padding-left: 2px;
|
padding-left: 0px;
|
||||||
padding-top: 1px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -476,15 +493,6 @@
|
|||||||
color: #FFF;
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Badge > Icon Color
|
|
||||||
*/
|
|
||||||
|
|
||||||
.md-typeset .mdx-badge svg
|
|
||||||
{
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -509,6 +517,14 @@ h4:has(.twemoji) .twemoji
|
|||||||
margin-left: -7px;
|
margin-left: -7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md-typeset .emojione, .md-typeset .gemoji, .md-typeset .twemoji
|
||||||
|
{
|
||||||
|
--md-icon-size: 1.125em;
|
||||||
|
display: inline-flex;
|
||||||
|
height: var(--md-icon-size);
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Badge > Header Padding
|
Badge > Header Padding
|
||||||
if a badge is used in a header, add padding between the badge and text
|
if a badge is used in a header, add padding between the badge and text
|
||||||
@@ -523,12 +539,18 @@ h4:has(.twemoji) .twemoji
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.md-nav--primary .md-nav__title
|
||||||
|
{
|
||||||
|
background: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Navigation > Spacer
|
Navigation > Spacer
|
||||||
Add a gap between the last "File" item in nav menu, and the folders under.
|
Add a gap between the last "File" item in nav menu, and the folders under.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
li:has(a[href*="about_patcher"])
|
.md-sidebar--primary li:has(a[href*="about_tvapp2"])
|
||||||
{
|
{
|
||||||
margin-bottom: 28px !important;
|
margin-bottom: 28px !important;
|
||||||
}
|
}
|
||||||
@@ -563,6 +585,53 @@ li:has(a[href*="about_patcher"])
|
|||||||
transition: none !important;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.md-typeset .mdx-badge--dangerous
|
||||||
|
{
|
||||||
|
--md-badge-icon-color: #fff;
|
||||||
|
--md-badge-icon-hover-color: #ff1058;
|
||||||
|
--md-badge-bg-color--transparent: #7B1532 !important;
|
||||||
|
color: #f9f9f9;
|
||||||
|
--md-typeset-bg-color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes health
|
||||||
|
{
|
||||||
|
0%, 40%, 80%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
color: #FFF;
|
||||||
|
fill: #FFF !important;
|
||||||
|
}
|
||||||
|
20%, 60% {
|
||||||
|
transform: scale(1.15);
|
||||||
|
color: #FF6593;
|
||||||
|
fill: #FF6593 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.heart
|
||||||
|
{
|
||||||
|
animation: health 1000ms infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset .mdx-badge--heart {
|
||||||
|
--md-badge-icon-color: #e92063;
|
||||||
|
--md-badge-icon-hover-color: #FFFFFF;
|
||||||
|
--md-accent-fg-color: #ff4281;
|
||||||
|
--md-accent-fg-color--transparent: #e920631a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset .mdx-badge--heart .twemoji {
|
||||||
|
animation: heart 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset .mdx-badge--command
|
||||||
|
{
|
||||||
|
--md-typeset-a-color: #ff2d72;
|
||||||
|
--md-accent-fg-color: #fff;
|
||||||
|
--md-accent-fg-color--transparent: #ffffff1a;
|
||||||
|
color: #e91e63;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Badge > Header Positioning
|
Badge > Header Positioning
|
||||||
This is mainly for the conventions page
|
This is mainly for the conventions page
|
||||||
@@ -584,7 +653,6 @@ h2:has(.mdx-badge) > .mdx-badge svg
|
|||||||
|
|
||||||
:is(h1, h2, h3, h4, h5, h6) .mdx-badge__icon svg
|
:is(h1, h2, h3, h4, h5, h6) .mdx-badge__icon svg
|
||||||
{
|
{
|
||||||
padding-top: 3px !important;
|
|
||||||
padding-right: 1px;
|
padding-right: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,6 +666,22 @@ h2:has(.mdx-badge) > .mdx-badge svg
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Table > Header
|
||||||
|
*/
|
||||||
|
|
||||||
|
.md-typeset__table table thead, .md-typeset__table > table
|
||||||
|
{
|
||||||
|
background-color: var(--md-table-head-bg-color);
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-typeset table:not([class]) tbody tr
|
||||||
|
{
|
||||||
|
background-color: var(--md-table-body-bg-color);
|
||||||
|
color: var(--md-table-body-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
.mdx-badge__text a
|
.mdx-badge__text a
|
||||||
{
|
{
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
@@ -614,20 +698,40 @@ small
|
|||||||
font-size: 60%;
|
font-size: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Navigation > Category Gap
|
||||||
|
|
||||||
|
if you have multiple sub-folders for a group of pages, add a gap between categories on left-side navigation
|
||||||
|
*/
|
||||||
|
|
||||||
|
.md-nav__item--section
|
||||||
|
{
|
||||||
|
display: block;
|
||||||
|
margin: 2.00em 0;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Menu Navigation > FontAwesome Folder Icons (for folders)
|
Menu Navigation > FontAwesome Folder Icons (for folders)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
label.md-nav__link
|
||||||
|
{
|
||||||
|
color: #ffffff59 !important;
|
||||||
|
}
|
||||||
|
|
||||||
label.md-nav__link::before
|
label.md-nav__link::before
|
||||||
{
|
{
|
||||||
content: ".";
|
opacity: 0.6;
|
||||||
|
content: "";
|
||||||
background-color: currentColor;
|
background-color: currentColor;
|
||||||
padding-right: 0.6rem;
|
padding-right: 0.6rem;
|
||||||
margin-right: 0.1rem;
|
margin-right: 0.1rem;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-size: contain;
|
mask-size: 20px;
|
||||||
|
padding-inline: 4px;
|
||||||
|
mask-position: center;
|
||||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512' fill='currentColor' width='16px' height='16px'%3E%3C!-- --%3E%3Cdefs%3E%3Cstyle%3E.fa-secondary%7Bopacity:.4%7D%3C/style%3E%3C/defs%3E%3Cpath class='fa-primary' d='M160 384H512c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H394.5c-17 0-33.3-6.7-45.3-18.7L322.7 50.7c-12-12-28.3-18.7-45.3-18.7H160c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64z'%3E%3C/path%3E%3Cpath class='fa-secondary' d='M24 96c13.3 0 24 10.7 24 24V344c0 48.6 39.4 88 88 88H456c13.3 0 24 10.7 24 24s-10.7 24-24 24H136C60.9 480 0 419.1 0 344V120c0-13.3 10.7-24 24-24z'%3E%3C/path%3E%3C/svg%3E");
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512' fill='currentColor' width='16px' height='16px'%3E%3C!-- --%3E%3Cdefs%3E%3Cstyle%3E.fa-secondary%7Bopacity:.4%7D%3C/style%3E%3C/defs%3E%3Cpath class='fa-primary' d='M160 384H512c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H394.5c-17 0-33.3-6.7-45.3-18.7L322.7 50.7c-12-12-28.3-18.7-45.3-18.7H160c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64z'%3E%3C/path%3E%3Cpath class='fa-secondary' d='M24 96c13.3 0 24 10.7 24 24V344c0 48.6 39.4 88 88 88H456c13.3 0 24 10.7 24 24s-10.7 24-24 24H136C60.9 480 0 419.1 0 344V120c0-13.3 10.7-24 24-24z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
opacity: 0.6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
li.md-nav__item--nested > a > span::before
|
li.md-nav__item--nested > a > span::before
|
||||||
@@ -652,10 +756,56 @@ nav.md-nav > ul.md-nav__list > li.md-nav__item > a.md-nav__link > span::before
|
|||||||
padding-right: 0.6rem;
|
padding-right: 0.6rem;
|
||||||
margin-right: 0.1rem;
|
margin-right: 0.1rem;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-size: contain;
|
mask-size: 9px;
|
||||||
|
padding-inline: 4px;
|
||||||
|
mask-position: center;
|
||||||
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512' fill='currentColor' width='16px' height='16px'%3E%3C!-- --%3E%3Cdefs%3E%3Cstyle%3E.fa-secondary%7Bopacity:.4%7D%3C/style%3E%3C/defs%3E%3Cpath class='fa-primary' d=''%3E%3C/path%3E%3Cpath class='fa-secondary' d='M0 256a160 160 0 1 1 320 0A160 160 0 1 1 0 256z'%3E%3C/path%3E%3C/svg%3E");
|
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512' fill='currentColor' width='16px' height='16px'%3E%3C!-- --%3E%3Cdefs%3E%3Cstyle%3E.fa-secondary%7Bopacity:.4%7D%3C/style%3E%3C/defs%3E%3Cpath class='fa-primary' d=''%3E%3C/path%3E%3Cpath class='fa-secondary' d='M0 256a160 160 0 1 1 320 0A160 160 0 1 1 0 256z'%3E%3C/path%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Menu Navigation > Secondary > Text Size
|
||||||
|
*/
|
||||||
|
|
||||||
|
nav.md-nav--secondary li
|
||||||
|
{
|
||||||
|
font-size: 0.6rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Badge > Override Icon Color
|
||||||
|
*/
|
||||||
|
|
||||||
|
.mdx-badge a
|
||||||
|
{
|
||||||
|
color: var(--md-badge-icon-color);
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdx-badge a:hover
|
||||||
|
{
|
||||||
|
color: var(--md-badge-icon-hover-color);
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdx-badge .mdx-badge__icon
|
||||||
|
{
|
||||||
|
background-color: var(--md-badge-bg-color--transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mdx-badge .mdx-badge__icon:hover
|
||||||
|
{
|
||||||
|
background-color: var(--md-badge-bg-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tag > Background Color
|
||||||
|
*/
|
||||||
|
|
||||||
|
.md-typeset .md-tag
|
||||||
|
{
|
||||||
|
background-color: var(--md-primary-fg-color);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Lightbox border
|
Lightbox border
|
||||||
*/
|
*/
|
||||||
@@ -727,6 +877,12 @@ figure img
|
|||||||
transition: border .25s,box-shadow .25s;
|
transition: border .25s,box-shadow .25s;
|
||||||
border: 2px solid rgba( 255, 255, 255, 0.1 );
|
border: 2px solid rgba( 255, 255, 255, 0.1 );
|
||||||
background-color: var(--md-default-fg-color--lightest);
|
background-color: var(--md-default-fg-color--lightest);
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
margin-top: 5px;
|
||||||
|
width: clamp(200px, 100%, 75%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mkde-embed-container:hover
|
.mkde-embed-container:hover
|
||||||
@@ -815,14 +971,14 @@ figure img
|
|||||||
|
|
||||||
.mkde-right
|
.mkde-right
|
||||||
{
|
{
|
||||||
padding: 8px 10px;
|
padding: 0px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media ( min-width: 360px )
|
@media ( min-width: 360px )
|
||||||
{
|
{
|
||||||
.mkde-right
|
.mkde-right
|
||||||
{
|
{
|
||||||
padding: 12px 15px;
|
padding: 0px 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,7 +986,7 @@ figure img
|
|||||||
{
|
{
|
||||||
.mkde-right
|
.mkde-right
|
||||||
{
|
{
|
||||||
padding: 12px 12px;
|
padding: 0px 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,10 +996,12 @@ figure img
|
|||||||
|
|
||||||
._lc._sm:not( .xd ) .mkde-left
|
._lc._sm:not( .xd ) .mkde-left
|
||||||
{
|
{
|
||||||
min-width: 100px;
|
min-width: 70px;
|
||||||
width: 100px;
|
width: 70px;
|
||||||
min-height: 100px;
|
min-height: 70px;
|
||||||
padding: 10px;
|
height: 70px;
|
||||||
|
padding: 5px;
|
||||||
|
align-self: center;
|
||||||
background: rgba( 255, 255, 255, 0.10 );
|
background: rgba( 255, 255, 255, 0.10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,9 +1009,11 @@ figure img
|
|||||||
{
|
{
|
||||||
._lc._sm:not( .xd ) .mkde-left
|
._lc._sm:not( .xd ) .mkde-left
|
||||||
{
|
{
|
||||||
min-width: 110px;
|
min-width: 80px;
|
||||||
width: 110px;
|
width: 80px;
|
||||||
min-height: 110px;
|
min-height: 80px;
|
||||||
|
height: 80px;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,9 +1021,11 @@ figure img
|
|||||||
{
|
{
|
||||||
._lc._sm:not( .xd ) .mkde-left
|
._lc._sm:not( .xd ) .mkde-left
|
||||||
{
|
{
|
||||||
min-width: 140px;
|
min-width: 110px;
|
||||||
width: 140px;
|
width: 110px;
|
||||||
min-height: 140px;
|
min-height: 110px;
|
||||||
|
height: 110px;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,9 +1033,11 @@ figure img
|
|||||||
{
|
{
|
||||||
._lc._sm:not( .xd ) .mkde-left
|
._lc._sm:not( .xd ) .mkde-left
|
||||||
{
|
{
|
||||||
min-width: 160px;
|
min-width: 110px;
|
||||||
width: 160px;
|
width: 110px;
|
||||||
min-height: 160px;
|
min-height: 110px;
|
||||||
|
height: 110px;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1049,24 +1213,24 @@ figure img
|
|||||||
._fs-x,
|
._fs-x,
|
||||||
._fs-m
|
._fs-m
|
||||||
{
|
{
|
||||||
font-size: 12px;
|
font-size: clamp(7px, 2.0vw, 12px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._f1p
|
._f1p
|
||||||
{
|
{
|
||||||
font-size: 13px;
|
font-size: clamp(10px, 2.5vw, 13px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media ( min-width: 360px )
|
@media ( min-width: 360px )
|
||||||
{
|
{
|
||||||
._fs-x
|
._fs-x
|
||||||
{
|
{
|
||||||
font-size: 13px;
|
font-size: clamp(10px, 2.5vw, 13px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._f1p
|
._f1p
|
||||||
{
|
{
|
||||||
font-size: 14px;
|
font-size: clamp(10px, 2.5vw, 14px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1074,17 +1238,17 @@ figure img
|
|||||||
{
|
{
|
||||||
._fs-m
|
._fs-m
|
||||||
{
|
{
|
||||||
font-size: 13px;
|
font-size: clamp(10px, 2.5vw, 13px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._fs-x
|
._fs-x
|
||||||
{
|
{
|
||||||
font-size: 14px;
|
font-size: clamp(10px, 2.5vw, 14px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._f1p
|
._f1p
|
||||||
{
|
{
|
||||||
font-size: 15px;
|
font-size: clamp(10px, 2.5vw, 15px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,17 +1256,17 @@ figure img
|
|||||||
{
|
{
|
||||||
._fs-m
|
._fs-m
|
||||||
{
|
{
|
||||||
font-size: 14px;
|
font-size: clamp(10px, 2.5vw, 13px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._fs-x
|
._fs-x
|
||||||
{
|
{
|
||||||
font-size: 15px;
|
font-size: clamp(10px, 2.5vw, 14px);
|
||||||
}
|
}
|
||||||
|
|
||||||
._f1p
|
._f1p
|
||||||
{
|
{
|
||||||
font-size: 17px;
|
font-size: clamp(10px, 2.5vw, 15px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,13 +1380,12 @@ figure img
|
|||||||
.item-link
|
.item-link
|
||||||
{
|
{
|
||||||
color: var( --md-typeset-a-color );
|
color: var( --md-typeset-a-color );
|
||||||
font-size: 12px;
|
font-size: clamp(8px, 2.5vw, 12px);
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-footer
|
.item-footer
|
||||||
{
|
{
|
||||||
padding-block-start: 12px;
|
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,14 +1418,14 @@ figure img
|
|||||||
{
|
{
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
margin-block-end: -5px;
|
margin-block-end: -7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-box
|
.color-box
|
||||||
{
|
{
|
||||||
float: left;
|
float: left;
|
||||||
height: 20px;
|
height: 21px;
|
||||||
width: 20px;
|
width: 21px;
|
||||||
border: 1px solid rgba( 255, 255, 255, 0.2 );
|
border: 1px solid rgba( 255, 255, 255, 0.2 );
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
@@ -1276,3 +1439,187 @@ figure img
|
|||||||
clear: both;
|
clear: both;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tools > Icon Search
|
||||||
|
*/
|
||||||
|
|
||||||
|
.md-typeset .mdx-iconsearch {
|
||||||
|
background-color:var(--md-default-bg-color);
|
||||||
|
border-radius:.1rem;
|
||||||
|
box-shadow:var(--md-shadow-z1);
|
||||||
|
position:relative;
|
||||||
|
transition:box-shadow 125ms
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch:focus-within,
|
||||||
|
.md-typeset .mdx-iconsearch:hover {
|
||||||
|
box-shadow:var(--md-shadow-z2)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch .md-input {
|
||||||
|
background:var(--md-default-bg-color);
|
||||||
|
box-shadow:none
|
||||||
|
}
|
||||||
|
[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch .md-input {
|
||||||
|
background:var(--md-code-bg-color)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result {
|
||||||
|
-webkit-backface-visibility:hidden;
|
||||||
|
backface-visibility:hidden;
|
||||||
|
max-height:50vh;
|
||||||
|
overflow-y:auto;
|
||||||
|
scrollbar-color:var(--md-default-fg-color--lighter) #0000;
|
||||||
|
scrollbar-width:thin;
|
||||||
|
touch-action:pan-y
|
||||||
|
}
|
||||||
|
.md-tooltip .md-typeset .mdx-iconsearch-result {
|
||||||
|
max-height:10.25rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result::-webkit-scrollbar {
|
||||||
|
height:.2rem;
|
||||||
|
width:.2rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb {
|
||||||
|
background-color:var(--md-default-fg-color--lighter)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color:var(--md-accent-fg-color)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__meta {
|
||||||
|
color:var(--md-default-fg-color--lighter);
|
||||||
|
font-size:.64rem;
|
||||||
|
position:absolute;
|
||||||
|
right:.6rem;
|
||||||
|
top:.4rem
|
||||||
|
}
|
||||||
|
@media screen and (max-width:29.984375em) {
|
||||||
|
.md-typeset .mdx-iconsearch-result__meta {
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__select {
|
||||||
|
background-color:var(--md-default-fg-color--lightest);
|
||||||
|
border:none;
|
||||||
|
border-radius:.1rem;
|
||||||
|
color:var(--md-default-fg-color--light);
|
||||||
|
font-size:.64rem;
|
||||||
|
padding-bottom:.15em;
|
||||||
|
padding-top:.15em;
|
||||||
|
position:absolute;
|
||||||
|
right:.6rem;
|
||||||
|
top:.4rem;
|
||||||
|
transition:color 125ms,background-color 125ms
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__select:focus,
|
||||||
|
.md-typeset .mdx-iconsearch-result__select:hover {
|
||||||
|
background-color:var(--md-accent-fg-color);
|
||||||
|
color:var(--md-accent-bg-color);
|
||||||
|
outline:none
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__select+.mdx-iconsearch-result__meta {
|
||||||
|
right:4.1rem
|
||||||
|
}
|
||||||
|
[dir=ltr] .md-typeset .mdx-iconsearch-result__list {
|
||||||
|
margin-left:0
|
||||||
|
}
|
||||||
|
[dir=rtl] .md-typeset .mdx-iconsearch-result__list {
|
||||||
|
margin-right:0
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__list {
|
||||||
|
list-style:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0
|
||||||
|
}
|
||||||
|
[dir=ltr] .md-typeset .mdx-iconsearch-result__item {
|
||||||
|
margin-left:0
|
||||||
|
}
|
||||||
|
[dir=rtl] .md-typeset .mdx-iconsearch-result__item {
|
||||||
|
margin-right:0
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__item {
|
||||||
|
border-bottom:.05rem solid var(--md-default-fg-color--lightest);
|
||||||
|
margin:0;
|
||||||
|
padding:.2rem .6rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__item:last-child {
|
||||||
|
border-bottom:none
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__item>* {
|
||||||
|
margin-right:.6rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-iconsearch-result__item img {
|
||||||
|
height:.9rem;
|
||||||
|
width:.9rem
|
||||||
|
}
|
||||||
|
[data-md-color-scheme=slate] .md-typeset .mdx-iconsearch-result__item img[src*=squidfunk] {
|
||||||
|
filter:invert(1)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-premium p {
|
||||||
|
margin:2em 0;
|
||||||
|
text-align:center
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-premium img {
|
||||||
|
height:3.25rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-premium p:last-child {
|
||||||
|
display:flex;
|
||||||
|
flex-wrap:wrap;
|
||||||
|
justify-content:center
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-premium p:last-child>a {
|
||||||
|
display:block;
|
||||||
|
flex-shrink:0
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__list {
|
||||||
|
margin:2em 0
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__list:after {
|
||||||
|
clear:both;
|
||||||
|
content:"";
|
||||||
|
display:block
|
||||||
|
}
|
||||||
|
[dir=ltr] .md-typeset .mdx-sponsorship__item {
|
||||||
|
float:left
|
||||||
|
}
|
||||||
|
[dir=rtl] .md-typeset .mdx-sponsorship__item {
|
||||||
|
float:right
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__item {
|
||||||
|
border-radius:100%;
|
||||||
|
display:block;
|
||||||
|
height:1.6rem;
|
||||||
|
margin:.2rem;
|
||||||
|
overflow:hidden;
|
||||||
|
transform:scale(1);
|
||||||
|
transition:color 125ms,transform 125ms;
|
||||||
|
width:1.6rem
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__item:focus,
|
||||||
|
.md-typeset .mdx-sponsorship__item:hover {
|
||||||
|
transform:scale(1.1)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__item:focus img,
|
||||||
|
.md-typeset .mdx-sponsorship__item:hover img {
|
||||||
|
filter:grayscale(0)
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__item--private {
|
||||||
|
background:var(--md-default-fg-color--lightest);
|
||||||
|
color:var(--md-default-fg-color--lighter);
|
||||||
|
font-size:.6rem;
|
||||||
|
font-weight:700;
|
||||||
|
line-height:1.6rem;
|
||||||
|
text-align:center
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship__item img {
|
||||||
|
display:block;
|
||||||
|
filter:grayscale(100%) opacity(75%);
|
||||||
|
height:auto;
|
||||||
|
transition:filter 125ms;
|
||||||
|
width:100%
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship-button {
|
||||||
|
font-weight:400
|
||||||
|
}
|
||||||
|
.md-typeset .mdx-sponsorship-count,
|
||||||
|
.md-typeset .mdx-sponsorship-total {
|
||||||
|
font-weight:700
|
||||||
|
}
|
||||||
|
|||||||
164
docs/docs/usage/healthcheck.md
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
---
|
||||||
|
title: Healthcheck
|
||||||
|
tags:
|
||||||
|
- usage
|
||||||
|
---
|
||||||
|
|
||||||
|
# Healthcheck
|
||||||
|
|
||||||
|
This docker container includes the ability to run health checks between the container api and outside services such as Portainer, or any other app that has the ability to query the endpoint `api/health`.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## API
|
||||||
|
<!-- md:version stable-1.4.0 -->
|
||||||
|
|
||||||
|
This container includes the ability to run health checks utilizing the built-in API. You can directly access the health check and view a json formatted result with the url `https://tvapp2.domain.lan/api/health`
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="/api/health" linenums="1" }
|
||||||
|
{
|
||||||
|
"ip": "172.18.2.1",
|
||||||
|
"gateway": "172.18.0.1",
|
||||||
|
"uptime": 5903.549082501,
|
||||||
|
"message": "healthy",
|
||||||
|
"status": "healthy",
|
||||||
|
"ref": "/api/health",
|
||||||
|
"method": "GET",
|
||||||
|
"code": 200,
|
||||||
|
"timestamp": 1744386346242
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
Numerous aliases have been added; you can use any of the following URLs to access the same health check results as they go to the same endpoint:
|
||||||
|
|
||||||
|
- https://tvapp2.domain.lan/api/health
|
||||||
|
- https://tvapp2.domain.lan/api/status
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Portainer
|
||||||
|
<!-- md:version stable-1.3.0 -->
|
||||||
|
|
||||||
|
To run a health check between TVApp2 and Portainer, apply the following lines of code to your TVApp2 `docker-compose.yml`. Two examples have been provided, you can use either one; `wget` or `curl`:
|
||||||
|
|
||||||
|
=== "Using CURL"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="14-18" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- TZ=Etc/UTC
|
||||||
|
health check:
|
||||||
|
test: "curl --fail --silent http://127.0.0.1:4124/api/health | grep -i healthy || exit 1"
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Using WGET"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="14-18" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- TZ=Etc/UTC
|
||||||
|
health check:
|
||||||
|
test: "wget -qO- http://127.0.0.1:4124/api/health | grep -i healthy || exit 1"
|
||||||
|
interval: 15s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## Web Interface
|
||||||
|
<!-- md:version stable-1.4.0 -->
|
||||||
|
|
||||||
|
The TVApp2 web interface is equip with its own health check which is ran every `10 minutes` by default. Users will notice a health indicator in the top right of the header navigation bar which is represented by the :octicons-heart-fill-24:{ .heart } icon.
|
||||||
|
|
||||||
|
When the health check is ran every 10 minutes; a toast notification will appear in the lower-right side of the page:
|
||||||
|
|
||||||
|
<figure markdown="span">
|
||||||
|
{ width="80%" }
|
||||||
|
<figcaption>Health check toast notification</figcaption>
|
||||||
|
</figure>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
### Health Check Duration
|
||||||
|
<!-- md:control env -->
|
||||||
|
<!-- md:version stable-1.4.0 -->
|
||||||
|
<!-- md:default `600000` -->
|
||||||
|
|
||||||
|
By default, a health check between the TVApp2 container and the web interface is done every `10 minutes`, but you can change this duration to something less or more. Be aware that if you set the time too low, you will constantly be spammed with toast notifications.
|
||||||
|
|
||||||
|
To change the health check delay, add the environment variable `HEALTH_TIMER` to your TVApp2 `docker-compose.yml`. Duration is in milliseconds.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
=== "Example"
|
||||||
|
|
||||||
|
``` { .yaml .copy .select title="docker-compose.yml" linenums="1" hl_lines="13" }
|
||||||
|
services:
|
||||||
|
tvapp2:
|
||||||
|
container_name: tvapp2
|
||||||
|
image: ghcr.io/thebinaryninja/tvapp2:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./config:/config
|
||||||
|
- ./app:/usr/bin/app
|
||||||
|
environment:
|
||||||
|
- HEALTH_TIMER=600000 # (1)
|
||||||
|
```
|
||||||
|
|
||||||
|
1. :information: Defines how often to perform health checks between the container and the web interface. Time is in milliseconds. <br /><br />Default value is `600000` (10 minutes)
|
||||||
|
|
||||||
|
=== "Time Chart"
|
||||||
|
|
||||||
|
| HEALTH_TIMER Value | Delay Between Checks |
|
||||||
|
| --- | --- |
|
||||||
|
| `HEALTH_TIMER=300000` | 5 minutes |
|
||||||
|
| `HEALTH_TIMER=600000` | 10 minutes |
|
||||||
|
| `HEALTH_TIMER=1200000` | 20 minutes |
|
||||||
|
| `HEALTH_TIMER=1800000` | 30 minutes |
|
||||||
|
| `HEALTH_TIMER=3600000` | 1 hour |
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
BIN
docs/img/core/01.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
docs/img/core/02.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
docs/img/core/03.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/img/core/04.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
docs/img/screenshots/01.gif
Normal file
|
After Width: | Height: | Size: 970 KiB |
BIN
docs/img/screenshots/01.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
1
docs/material/overrides/.icons/aetherx/axd/ballot.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 64L0 448c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-384c0-35.3-28.7-64-64-64L64 0C28.7 0 0 28.7 0 64zm64 48c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM192 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16zm0 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16zm0 128c0-8.8 7.2-16 16-16l160 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-160 0c-8.8 0-16-7.2-16-16z"/><path class="fa-primary" d="M64 112c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zm0 128c0-8.8 7.2-16 16-16l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32zM80 352l32 0c8.8 0 16 7.2 16 16l0 32c0 8.8-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16l0-32c0-8.8 7.2-16 16-16z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M264.8 64C277.6 64 288 74.4 288 87.2c0 9.2-5.8 17.3-13.2 22.8c-11.6 8.7-18.8 20.7-18.8 34c0 26.5 28.7 48 64 48s64-21.5 64-48c0-13.3-7.2-25.3-18.8-34c-7.4-5.5-13.2-13.6-13.2-22.8C352 74.4 362.4 64 375.2 64L464 64c26.5 0 48 21.5 48 48l0 88.8c0 12.8 10.4 23.2 23.2 23.2c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2c-12.8 0-23.2 10.4-23.2 23.2l0 88.8c0 26.5-21.5 48-48 48l-88.8 0c-12.8 0-23.2-10.4-23.2-23.2c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8c0 12.8-10.4 23.2-23.2 23.2L176 448c-26.5 0-48-21.5-48-48l0-88.8c0-12.8-10.4-23.2-23.2-23.2c-9.2 0-17.3 5.8-22.8 13.2C73.3 312.8 61.3 320 48 320c-26.5 0-48-28.7-48-64s21.5-64 48-64c13.3 0 25.3 7.2 34 18.8c5.5 7.4 13.6 13.2 22.8 13.2c12.8 0 23.2-10.4 23.2-23.2l0-88.8c0-26.5 21.5-48 48-48l88.8 0z"/><path class="fa-primary" d=""/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 104.8c0-9.2-5.8-17.3-13.2-22.8C167.2 73.3 160 61.3 160 48c0-26.5 28.7-48 64-48s64 21.5 64 48c0 13.3-7.2 25.3-18.8 34c-7.4 5.5-13.2 13.6-13.2 22.8c0 12.8 10.4 23.2 23.2 23.2l56.8 0c26.5 0 48 21.5 48 48l0 56.8c0 12.8 10.4 23.2 23.2 23.2c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2c-12.8 0-23.2 10.4-23.2 23.2L384 464c0 26.5-21.5 48-48 48l-56.8 0c-12.8 0-23.2-10.4-23.2-23.2c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8c0 12.8-10.4 23.2-23.2 23.2L48 512c-26.5 0-48-21.5-48-48L0 343.2C0 330.4 10.4 320 23.2 320c9.2 0 17.3 5.8 22.8 13.2C54.7 344.8 66.7 352 80 352c26.5 0 48-28.7 48-64s-21.5-64-48-64c-13.3 0-25.3 7.2-34 18.8C40.5 250.2 32.4 256 23.2 256C10.4 256 0 245.6 0 232.8L0 176c0-26.5 21.5-48 48-48l120.8 0c12.8 0 23.2-10.4 23.2-23.2z"/><path class="fa-primary" d=""/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
1
docs/material/overrides/.icons/aetherx/axd/puzzle.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 288L0 448c0 35.3 28.7 64 64 64l160 0 0-64c0-8.8-7.2-16-16-16l-16 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l16 0c8.8 0 16-7.2 16-16l0-64-64 0c-8.8 0-16-7.2-16-16l0-16c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 16c0 8.8-7.2 16-16 16L0 288zM304 16l0 48c0 8.8 7.2 16 16 16l16 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-16 0c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l36 0c6.6 0 12 5.4 12 12l0 4c0 17.7 14.3 32 32 32s32-14.3 32-32l0-4c0-6.6 5.4-12 12-12l52 0c8.8 0 16-7.2 16-16l0-128c0-35.3-28.7-64-64-64L320 0c-8.8 0-16 7.2-16 16z"/><path class="fa-primary" d="M0 288l64 0c8.8 0 16-7.2 16-16l0-16c0-17.7 14.3-32 32-32s32 14.3 32 32l0 16c0 8.8 7.2 16 16 16l64 0 0-68c0-6.6 5.4-12 12-12l4 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-4 0c-6.6 0-12-5.4-12-12l0-52c0-8.8-7.2-16-16-16L64 64C28.7 64 0 92.7 0 128L0 288zm224 0l0 64c0 8.8-7.2 16-16 16l-16 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l16 0c8.8 0 16 7.2 16 16l0 64 160 0c35.3 0 64-28.7 64-64l0-144c0-8.8-7.2-16-16-16l-48 0c-8.8 0-16 7.2-16 16l0 16c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-16c0-8.8-7.2-16-16-16l-64 0z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M3.4 273.7c-7.9 15.8-1.5 35 14.3 42.9L152.4 384 17.7 451.4C1.9 459.3-4.5 478.5 3.4 494.3C9 505.5 20.3 512 32 512c4.8 0 9.7-1.1 14.3-3.4L224 419.8l177.7 88.8c4.6 2.3 9.5 3.4 14.3 3.4c11.7 0 23-6.5 28.6-17.7c7.9-15.8 1.5-35-14.3-42.9L295.6 384l134.8-67.4c15.8-7.9 22.2-27.1 14.3-42.9C439 262.5 427.7 256 416 256c-4.8 0-9.7 1.1-14.3 3.4L224 348.2 46.3 259.4c-4.6-2.3-9.5-3.4-14.3-3.4c-11.7 0-23 6.5-28.6 17.7z"/><path class="fa-primary" d="M304 234.4c38.6-23 64-62.1 64-106.4C368 57.3 303.5 0 224 0S80 57.3 80 128c0 44.4 25.4 83.5 64 106.4l0 21.6c0 17.7 14.3 32 32 32l96 0c17.7 0 32-14.3 32-32l0-21.6zM136 144a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm144-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1006 B |
1
docs/material/overrides/.icons/aetherx/axd/tv.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 64C0 28.7 28.7 0 64 0L576 0c35.3 0 64 28.7 64 64l0 288c0 35.3-28.7 64-64 64L64 416c-35.3 0-64-28.7-64-64L0 64zm64 0l0 288 512 0 0-288L64 64zM96 480c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-384 0c-17.7 0-32-14.3-32-32z"/><path class="fa-primary" d="M64 64H576V352H64V64z"/></svg>
|
||||||
|
After Width: | Height: | Size: 617 B |
1
docs/material/overrides/.icons/aetherx/axd/volume.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 96C0 60.7 28.7 32 64 32l384 0c35.3 0 64 28.7 64 64l0 224c0 5.5-.7 10.8-2 16c-3.6-13.8-11.6-25.8-22.5-34.4c-5.4-4.3-11.6-7.7-18.2-10c-3.3-1.2-6.8-2.1-10.3-2.7c-1.8-.3-3.6-.5-5.4-.7c-.9-.1-1.8-.1-2.8-.2s-1.8-.1-2.8-.1L64 288c-29.8 0-54.9 20.4-62 48c-1.3-5.1-2-10.5-2-16L0 96zM352 384a32 32 0 1 1 -64 0 32 32 0 1 1 64 0z"/><path class="fa-primary" d="M0 352c0-35.3 28.7-64 64-64l384 0c35.3 0 64 28.7 64 64l0 64c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64l0-64zm352 32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm64 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z"/></svg>
|
||||||
|
After Width: | Height: | Size: 872 B |
1
docs/material/overrides/.icons/aetherx/axs/clock.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM232 120c.1-13.4 10.8-24 24-24c6.6 0 12.6 2.7 17 7c2.2 2.2 3.9 4.8 5.1 7.6c.6 1.4 1.1 2.9 1.4 4.5c.2 .8 .3 1.6 .4 2.4s.1 1.6 .1 2.5c0 41 0 82.1 0 123.2L365.3 300c6.9 4.6 10.7 12.2 10.7 20c0 4.6-1.3 9.2-4 13.3c-4.6 6.9-12.2 10.7-20 10.7c-4.6 0-9.2-1.3-13.3-4c-32-21.3-64-42.7-96-64C236 271.5 232 264 232 256c0-45.3 0-90.7 0-136z"/><path class="fa-primary" d="M256 96c-13.3 0-24 10.7-24 24l0 136c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2 280 120c0-13.3-10.7-24-24-24z"/></svg>
|
||||||
|
After Width: | Height: | Size: 870 B |
1
docs/material/overrides/.icons/aetherx/axs/code.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M225.2 471.2c-4.9 17 5 34.7 22 39.6c2.9 .8 5.9 1.2 8.8 1.2c13.9 0 26.7-9.2 30.7-23.2l128-448c.8-2.9 1.2-5.9 1.2-8.8c0-13.9-9.2-26.7-23.2-30.8c-17-4.9-34.7 5-39.6 22l-128 448z"/><path class="fa-primary" d="M473.4 121.4c-12.5 12.5-12.5 32.8 0 45.3L562.7 256l-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z"/></svg>
|
||||||
|
After Width: | Height: | Size: 879 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc. --><defs><style>.fa-secondary{opacity:.4}</style></defs><path class="fa-secondary" d="M192 104.8c0-9.2-5.8-17.3-13.2-22.8C167.2 73.3 160 61.3 160 48c0-26.5 28.7-48 64-48s64 21.5 64 48c0 13.3-7.2 25.3-18.8 34c-7.4 5.5-13.2 13.6-13.2 22.8c0 12.8 10.4 23.2 23.2 23.2l56.8 0c26.5 0 48 21.5 48 48l0 56.8c0 12.8 10.4 23.2 23.2 23.2c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2c-12.8 0-23.2 10.4-23.2 23.2L384 464c0 26.5-21.5 48-48 48l-56.8 0c-12.8 0-23.2-10.4-23.2-23.2c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8c0 12.8-10.4 23.2-23.2 23.2L48 512c-26.5 0-48-21.5-48-48L0 343.2C0 330.4 10.4 320 23.2 320c9.2 0 17.3 5.8 22.8 13.2C54.7 344.8 66.7 352 80 352c26.5 0 48-28.7 48-64s-21.5-64-48-64c-13.3 0-25.3 7.2-34 18.8C40.5 250.2 32.4 256 23.2 256C10.4 256 0 245.6 0 232.8L0 176c0-26.5 21.5-48 48-48l120.8 0c12.8 0 23.2-10.4 23.2-23.2z"/><path class="fa-primary" d=""/></svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -71,9 +71,9 @@ class clr():
|
|||||||
MAGENTA = '\033[35m'
|
MAGENTA = '\033[35m'
|
||||||
CYAN = '\033[36m'
|
CYAN = '\033[36m'
|
||||||
WHITE = '\033[37m'
|
WHITE = '\033[37m'
|
||||||
|
GREY = '\033[90m'
|
||||||
UNDERLINE = '\033[4m'
|
UNDERLINE = '\033[4m'
|
||||||
RESET = '\033[0m'
|
RESET = '\033[0m'
|
||||||
GREY = '\033[90m'
|
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Pages
|
# Pages
|
||||||
@@ -87,6 +87,8 @@ PAGE_CONVENTIONS = "about/conventions.md"
|
|||||||
|
|
||||||
# #
|
# #
|
||||||
# Hooks > on_page_markdown
|
# Hooks > on_page_markdown
|
||||||
|
#
|
||||||
|
# do not change this function name
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files: Files):
|
def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files: Files):
|
||||||
@@ -99,28 +101,28 @@ def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files:
|
|||||||
args = args.strip()
|
args = args.strip()
|
||||||
|
|
||||||
if type == "version":
|
if type == "version":
|
||||||
if args.startswith( "beta-" ):
|
if args.startswith( "development-" ):
|
||||||
return Version_Beta(args, page, files)
|
return Version_Development(args, page, files)
|
||||||
elif args.startswith( "stable-" ):
|
elif args.startswith( "stable-" ):
|
||||||
return Version_Stable( args, page, files )
|
return Version_Stable( args, page, files )
|
||||||
else:
|
else:
|
||||||
return Version( args, page, files )
|
return Version( args, page, files )
|
||||||
|
|
||||||
elif type == "backers": return Badge_Backers(page, files)
|
elif type == "control": return badgeControl(args, page, files)
|
||||||
elif type == "control": return Create_Control(args, page, files)
|
elif type == "flag": return badgeFlag(args, page, files)
|
||||||
elif type == "flag": return Create_Flag(args, page, files)
|
elif type == "option": return badgeOption(args)
|
||||||
elif type == "option": return Create_Option(args)
|
elif type == "setting": return badgeSetting(args)
|
||||||
elif type == "setting": return Create_Setting(args)
|
elif type == "backers": return badgeBackers(page, files)
|
||||||
elif type == "command": return Badge_Command(args, page, files)
|
elif type == "command": return badgeCommand(args, page, files)
|
||||||
elif type == "feature": return Badge_Feature(args, page, files)
|
elif type == "feature": return badgeFeature(args, page, files)
|
||||||
elif type == "plugin": return Badge_Plugin(args, page, files)
|
elif type == "plugin": return badgePlugin(args, page, files)
|
||||||
elif type == "extension": return Badge_Extension(args, page, files)
|
elif type == "markdown": return badgeMarkdown(args, page, files)
|
||||||
elif type == "3rdparty": return Badge_3rdparty(args, page, files)
|
elif type == "3rdparty": return badge3rdParty(args, page, files)
|
||||||
elif type == "example": return Badge_Example(args, page, files)
|
elif type == "example": return badgeExample(args, page, files)
|
||||||
elif type == "default":
|
elif type == "default":
|
||||||
if args == "none": return Badge_DefaultValue_None(page, files)
|
if args == "none": return badgeDefaultNone(page, files)
|
||||||
elif args == "computed": return Badge_DefaultValue_Computed(page, files)
|
elif args == "computed": return badgeDefaultVal(page, files)
|
||||||
else: return Badge_DefaultValue_Custom(args, page, files)
|
else: return badgeDefaultCustom(args, page, files)
|
||||||
|
|
||||||
# Otherwise, raise an error
|
# Otherwise, raise an error
|
||||||
raise RuntimeError( f"Error in shortcodes.yp - Specified an unknown shortcode: {type}" )
|
raise RuntimeError( f"Error in shortcodes.yp - Specified an unknown shortcode: {type}" )
|
||||||
@@ -135,31 +137,36 @@ def on_page_markdown(markdown: str, *, page: Page, config: MkDocsConfig, files:
|
|||||||
# Create > Flag
|
# Create > Flag
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Create_Flag(args: str, page: Page, files: Files):
|
def badgeFlag(args: str, page: Page, files: Files):
|
||||||
type, *_ = args.split(" ", 1)
|
type, *_ = args.split(" ", 1)
|
||||||
if type == "experimental": return Badge_Flag_Experimental(page, files)
|
if type == "experimental": return badgeFlagExperimental(page, files)
|
||||||
elif type == "required": return Badge_Flag_Required(page, files)
|
elif type == "required": return badgeFlagRequired(page, files)
|
||||||
elif type == "customization": return Badge_Flag_Customization(page, files)
|
elif type == "customization": return badgeFlagCustomization(page, files)
|
||||||
elif type == "metadata": return Badge_Flag_Metadata(page, files)
|
elif type == "metadata": return badgeFlagMetadata(page, files)
|
||||||
elif type == "multiple": return Badge_Flag_Multiple_Instances(page, files)
|
elif type == "dangerous": return badgeFlagDangerous(page, files)
|
||||||
elif type == "setting": return Badge_Flag_Setting(page, files)
|
elif type == "multiple": return badgeFlagMultiInstances(page, files)
|
||||||
|
elif type == "setting": return badgeFlagSetting(page, files)
|
||||||
|
else: return badgeFlagDefault( page, files )
|
||||||
|
|
||||||
raise RuntimeError(f"Unknown type: {type}")
|
raise RuntimeError(f"Unknown type: {type}")
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Create > Controls
|
# Create > Controls
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Create_Control( args: str, page: Page, files: Files ):
|
def badgeControl( args: str, page: Page, files: Files ):
|
||||||
type, *_ = args.split( " ", 2 )
|
type, *_ = args.split( " ", 2 )
|
||||||
if type == "toggle": return icon_control_toggle( page, files )
|
if type == "toggle": return newControlToggle( page, files )
|
||||||
elif type == "toggle_on": return icon_control_toggle_on( page, files )
|
elif type == "toggle_on": return newControlToggleOn( page, files )
|
||||||
elif type == "toggle_off": return icon_control_toggle_off( page, files )
|
elif type == "toggle_off": return newControlToggleOff( page, files )
|
||||||
elif type == "textbox": return icon_control_textbox( page, files )
|
elif type == "textbox": return newControlTextbox( page, files )
|
||||||
elif type == "dropdown": return icon_control_dropdown( page, files )
|
elif type == "dropdown": return newControlDropdown( page, files )
|
||||||
elif type == "button": return icon_control_button( page, files )
|
elif type == "button": return newControlButton( page, files )
|
||||||
elif type == "slider": return icon_control_slider( page, files )
|
elif type == "slider": return newControlSlider( page, files )
|
||||||
elif type == "color": return icon_control_color( args, page, files )
|
elif type == "env": return newControlEnvVar( page, files )
|
||||||
else: return icon_control_default( page, files )
|
elif type == "volume": return newControlVolume( page, files )
|
||||||
|
elif type == "color": return newControlColor( args, page, files )
|
||||||
|
else: return newControlDefault( page, files )
|
||||||
|
|
||||||
raise RuntimeError(f"Unknown type: {type}")
|
raise RuntimeError(f"Unknown type: {type}")
|
||||||
|
|
||||||
@@ -167,15 +174,19 @@ def Create_Control( args: str, page: Page, files: Files ):
|
|||||||
# Create > Option
|
# Create > Option
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Create_Option(type: str):
|
def badgeOption(type: str):
|
||||||
_, *_, name = re.split(r"[.:]", type)
|
_, *_, name = re.split(r"[.:]", type)
|
||||||
return f"[`{name}`](#+{type}){{ #+{type} }}\n\n"
|
return f"[`{name}`](#+{type}){{ #+{type} }}\n\n"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Create > Setting
|
# Create > Setting
|
||||||
|
#
|
||||||
|
# #### <!-- md:setting example.setting.enabled -->
|
||||||
|
# <!-- md:version 1.0.0 -->
|
||||||
|
# <!-- md:default `true` -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Create_Setting(type: str):
|
def badgeSetting(type: str):
|
||||||
_, *_, name = re.split(r"[.*]", type)
|
_, *_, name = re.split(r"[.*]", type)
|
||||||
return f"`{name}` {{ #{type} }}\n\n[{type}]: #{type}\n\n"
|
return f"`{name}` {{ #{type} }}\n\n[{type}]: #{type}\n\n"
|
||||||
|
|
||||||
@@ -202,7 +213,7 @@ def _resolve(file: File, page: Page):
|
|||||||
# Create > Badge
|
# Create > Badge
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Create_Badge(icon: str, text: str = "", type: str = ""):
|
def badgeCreate(icon: str, text: str = "", type: str = ""):
|
||||||
classes = f"mdx-badge mdx-badge--{type}" if type else "mdx-badge"
|
classes = f"mdx-badge mdx-badge--{type}" if type else "mdx-badge"
|
||||||
return "".join([
|
return "".join([
|
||||||
f"<span class=\"{classes}\">",
|
f"<span class=\"{classes}\">",
|
||||||
@@ -215,7 +226,7 @@ def Create_Badge(icon: str, text: str = "", type: str = ""):
|
|||||||
# Badge > Color Palette
|
# Badge > Color Palette
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_ColorPalette(icon: str, text: str = "", type: str = ""):
|
def badgeColorPalette(icon: str, text: str = "", type: str = ""):
|
||||||
args = type.split( " " )
|
args = type.split( " " )
|
||||||
|
|
||||||
bg1_clr = "#000000"
|
bg1_clr = "#000000"
|
||||||
@@ -252,10 +263,10 @@ def Badge_ColorPalette(icon: str, text: str = "", type: str = ""):
|
|||||||
# <!-- md:sponsors -->
|
# <!-- md:sponsors -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Backers(page: Page, files: Files):
|
def badgeBackers(page: Page, files: Files):
|
||||||
icon = "material-heart"
|
icon = "material-heart"
|
||||||
href = _resolve_path(PAGE_BACKERS, page, files)
|
href = _resolve_path(PAGE_BACKERS, page, files)
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Backers only')",
|
icon = f"[:{icon}:]({href} 'Backers only')",
|
||||||
type = "heart"
|
type = "heart"
|
||||||
)
|
)
|
||||||
@@ -280,8 +291,8 @@ def Version( text: str, page: Page, files: Files ):
|
|||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Mkdocs Release')",
|
icon = f"[:{icon}:]({href} 'TVApp2 Release')",
|
||||||
text = f"[{text}]({_resolve_path(path, page, files)})" if spec else ""
|
text = f"[{text}]({_resolve_path(path, page, files)})" if spec else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -295,7 +306,7 @@ def Version_Stable( text: str, page: Page, files: Files ):
|
|||||||
|
|
||||||
# Return badge
|
# Return badge
|
||||||
icon = "aetherx-axs-tag"
|
icon = "aetherx-axs-tag"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#version-beta", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#version-stable", page, files )
|
||||||
output = ""
|
output = ""
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
@@ -306,22 +317,22 @@ def Version_Stable( text: str, page: Page, files: Files ):
|
|||||||
else:
|
else:
|
||||||
output = f"Stable Release"
|
output = f"Stable Release"
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} '{output}' )",
|
icon = f"[:{icon}:]({href} '{output}' )",
|
||||||
text = f"[{spec}]({_resolve_path(path, page, files)})" if spec else ""
|
text = f"[{spec}]({_resolve_path(path, page, files)})" if spec else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Badge > Version > Beta
|
# Badge > Version > Development
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Version_Beta( text: str, page: Page, files: Files ):
|
def Version_Development( text: str, page: Page, files: Files ):
|
||||||
spec = text.replace( "beta-", "" )
|
spec = text.replace( "development-", "" )
|
||||||
path = f"{PAGE_CHANGELOG}#{spec}"
|
path = f"{PAGE_CHANGELOG}#{spec}"
|
||||||
|
|
||||||
# Return badge
|
# Return badge
|
||||||
icon = "aetherx-axs-b"
|
icon = "aetherx-axs-code"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#version-beta", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#version-development", page, files )
|
||||||
output = ""
|
output = ""
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
@@ -330,9 +341,9 @@ def Version_Beta( text: str, page: Page, files: Files ):
|
|||||||
if spec:
|
if spec:
|
||||||
output = f"Requires version {spec}"
|
output = f"Requires version {spec}"
|
||||||
else:
|
else:
|
||||||
output = f"Beta Release"
|
output = f"Development Release"
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} '{output}' )",
|
icon = f"[:{icon}:]({href} '{output}' )",
|
||||||
text = f"[{text}]({_resolve_path(path, page, files)})" if spec else ""
|
text = f"[{text}]({_resolve_path(path, page, files)})" if spec else ""
|
||||||
)
|
)
|
||||||
@@ -344,13 +355,13 @@ def Version_Beta( text: str, page: Page, files: Files ):
|
|||||||
# <!-- md:feature -->
|
# <!-- md:feature -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Feature(text: str, page: Page, files: Files):
|
def badgeFeature(text: str, page: Page, files: Files):
|
||||||
icon = "material-toggle-switch"
|
icon = "material-toggle-switch"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#feature", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#feature", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Optional feature')",
|
icon = f"[:{icon}:]({href} 'Optional feature')",
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
@@ -364,32 +375,32 @@ def Badge_Feature(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:plugin [typeset] – built-in -->
|
# <!-- md:plugin [typeset] – built-in -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Plugin(text: str, page: Page, files: Files):
|
def badgePlugin(text: str, page: Page, files: Files):
|
||||||
icon = "material-floppy"
|
icon = "material-floppy"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#plugin", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#plugin", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Plugin')",
|
icon = f"[:{icon}:]({href} 'Plugin')",
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Create badge for extension
|
# Create badge for Markdown
|
||||||
#
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:extension [admonition][Admonition] -->
|
# <!-- md:markdown [admonition][Admonition] -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Extension(text: str, page: Page, files: Files):
|
def badgeMarkdown(text: str, page: Page, files: Files):
|
||||||
icon = "material-language-markdown"
|
icon = "material-language-markdown"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#extension", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#markdown", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Markdown extension')",
|
icon = f"[:{icon}:]({href} 'Markdown functionality')",
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -403,13 +414,13 @@ def Badge_Extension(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:3rdparty [mike] -->
|
# <!-- md:3rdparty [mike] -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_3rdparty(text: str, page: Page, files: Files):
|
def badge3rdParty(text: str, page: Page, files: Files):
|
||||||
icon = "material-package-variant"
|
icon = "material-package-variant"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#3rdparty", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#3rdparty", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Third-party utility')",
|
icon = f"[:{icon}:]({href} 'Third-party utility')",
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
@@ -433,30 +444,30 @@ def Badge_3rdparty(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:example my-example-file -->
|
# <!-- md:example my-example-file -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Example(text: str, page: Page, files: Files):
|
def badgeExample(text: str, page: Page, files: Files):
|
||||||
return "\n".join([
|
return "\n".join([
|
||||||
Badge_Example_Download_Zip(text, page, files),
|
badgeExampleDownloadZip(text, page, files),
|
||||||
Badge_Example_View(text, page, files)
|
badgeExampleView(text, page, files)
|
||||||
])
|
])
|
||||||
|
|
||||||
def Badge_Example_View(text: str, page: Page, files: Files):
|
def badgeExampleView(text: str, page: Page, files: Files):
|
||||||
icon = "material-folder-eye"
|
icon = "material-folder-eye"
|
||||||
href = f"https://github.com/TheBinaryNinja/tvapp2/{text}/"
|
href = f"https://github.com/TheBinaryNinja/tvapp2/{text}/"
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'View example')",
|
icon = f"[:{icon}:]({href} 'View example')",
|
||||||
type = "right"
|
type = "right"
|
||||||
)
|
)
|
||||||
|
|
||||||
def Badge_Example_Download_Zip(text: str, page: Page, files: Files):
|
def badgeExampleDownloadZip(text: str, page: Page, files: Files):
|
||||||
icon = "material-folder-download"
|
icon = "material-folder-download"
|
||||||
href = f"https://github.com/TheBinaryNinja/tvapp2/{text}.zip"
|
href = f"https://github.com/TheBinaryNinja/tvapp2/{text}.zip"
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Download example')",
|
icon = f"[:{icon}:]({href} 'Download example')",
|
||||||
text = f"[`.zip`]({href})",
|
text = f"[`.zip`]({href})",
|
||||||
type = "right"
|
type = "right"
|
||||||
@@ -471,15 +482,16 @@ def Badge_Example_Download_Zip(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:command `-s, --start` -->
|
# <!-- md:command `-s, --start` -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Command(text: str, page: Page, files: Files):
|
def badgeCommand(text: str, page: Page, files: Files):
|
||||||
icon = "material-console-line"
|
icon = "material-console-line"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#command", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#command", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Terminal / Console Command')",
|
icon = f"[:{icon}:]({href} 'Terminal / Console Command')",
|
||||||
text = text
|
text = text,
|
||||||
|
type = "command"
|
||||||
)
|
)
|
||||||
|
|
||||||
# #
|
# #
|
||||||
@@ -494,13 +506,13 @@ def Badge_Command(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:default none -->
|
# <!-- md:default none -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_DefaultValue_Custom(text: str, page: Page, files: Files):
|
def badgeDefaultCustom(text: str, page: Page, files: Files):
|
||||||
icon = "material-water"
|
icon = "material-water"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Default value')",
|
icon = f"[:{icon}:]({href} 'Default value')",
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
@@ -517,13 +529,13 @@ def Badge_DefaultValue_Custom(text: str, page: Page, files: Files):
|
|||||||
# <!-- md:default none -->
|
# <!-- md:default none -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_DefaultValue_None(page: Page, files: Files):
|
def badgeDefaultNone(page: Page, files: Files):
|
||||||
icon = "material-water-outline"
|
icon = "material-water-outline"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Default value is empty')"
|
icon = f"[:{icon}:]({href} 'Default value is empty')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -539,53 +551,127 @@ def Badge_DefaultValue_None(page: Page, files: Files):
|
|||||||
# <!-- md:default none -->
|
# <!-- md:default none -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_DefaultValue_Computed(page: Page, files: Files):
|
def badgeDefaultVal(page: Page, files: Files):
|
||||||
icon = "material-water-check"
|
icon = "material-water-check"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#default", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Default value is computed')"
|
icon = f"[:{icon}:]({href} 'Default value is computed')"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Badge > Flag > Default
|
||||||
|
#
|
||||||
|
# This symbol denotes that the specified item is a customizable setting
|
||||||
|
#
|
||||||
|
# MUST add an entry in conventions.md
|
||||||
|
#
|
||||||
|
# use the following tag in your md file:
|
||||||
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
|
# #
|
||||||
|
|
||||||
|
def badgeFlagDefault(page: Page, files: Files):
|
||||||
|
icon = "material-flag"
|
||||||
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#setting", page, files)
|
||||||
|
|
||||||
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
|
return badgeCreate(
|
||||||
|
icon = f"[:{icon}:]({href} 'Configurable Setting')"
|
||||||
|
)
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Badge > Flag > Metadata Property
|
# Badge > Flag > Metadata Property
|
||||||
#
|
#
|
||||||
# This symbol denotes that the item described is a metadata property, which can
|
# This symbol denotes that the item described is a metadata property, which can
|
||||||
# be used in Markdown documents as part of the front matter definition.
|
# be used in Markdown documents as part of the front matter definition.
|
||||||
#
|
#
|
||||||
|
# MUST add an entry in conventions.md
|
||||||
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag metadata -->
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Metadata(page: Page, files: Files):
|
def badgeFlagMetadata(page: Page, files: Files):
|
||||||
icon = "material-list-box-outline"
|
icon = "material-list-box-outline"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#metadata", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#metadata", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Metadata property')"
|
icon = f"[:{icon}:]({href} 'Metadata property')"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Badge > Flag > Dangerous
|
||||||
|
#
|
||||||
|
# This symbol denotes that the item or setting specified may be dangerous to change.
|
||||||
|
#
|
||||||
|
# MUST add an entry in conventions.md
|
||||||
|
#
|
||||||
|
# use the following tag in your md file:
|
||||||
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
|
# #
|
||||||
|
|
||||||
|
def badgeFlagDangerous(page: Page, files: Files):
|
||||||
|
icon = "aetherx-axd-skull-crossbones"
|
||||||
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#dangerous", page, files)
|
||||||
|
|
||||||
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
|
return badgeCreate(
|
||||||
|
icon = f"[:{icon}:]({href} 'This setting is dangerous to change')",
|
||||||
|
type = "dangerous"
|
||||||
|
)
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Badge > Flag > Required
|
# Badge > Flag > Required
|
||||||
#
|
#
|
||||||
# Specifies that a value is required.
|
# Specifies that a value is required.
|
||||||
#
|
#
|
||||||
|
# MUST add an entry in conventions.md
|
||||||
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag required -->
|
# : <!-- md:flag --> Default
|
||||||
# <!-- md:flag required --> This option enables the content tabs
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Required(page: Page, files: Files):
|
def badgeFlagRequired(page: Page, files: Files):
|
||||||
icon = "material-alert"
|
icon = "material-alert"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#required", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#required", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Required value')"
|
icon = f"[:{icon}:]({href} 'Required value')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -594,17 +680,26 @@ def Badge_Flag_Required(page: Page, files: Files):
|
|||||||
#
|
#
|
||||||
# This symbol denotes that the item described is a customization which affects the overall look of the app.
|
# This symbol denotes that the item described is a customization which affects the overall look of the app.
|
||||||
#
|
#
|
||||||
|
# MUST add an entry in conventions.md
|
||||||
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag customization -->
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Customization(page: Page, files: Files):
|
def badgeFlagCustomization(page: Page, files: Files):
|
||||||
icon = "material-brush-variant"
|
icon = "material-brush-variant"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#customization", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#customization", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Customization')"
|
icon = f"[:{icon}:]({href} 'Customization')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -616,16 +711,23 @@ def Badge_Flag_Customization(page: Page, files: Files):
|
|||||||
# MUST add an entry in conventions.md
|
# MUST add an entry in conventions.md
|
||||||
#
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag experimental -->
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Experimental(page: Page, files: Files):
|
def badgeFlagExperimental(page: Page, files: Files):
|
||||||
icon = "material-flask-outline"
|
icon = "material-flask-outline"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#experimental", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#experimental", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Experimental')"
|
icon = f"[:{icon}:]({href} 'Experimental')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -638,16 +740,23 @@ def Badge_Flag_Experimental(page: Page, files: Files):
|
|||||||
# MUST add an entry in conventions.md
|
# MUST add an entry in conventions.md
|
||||||
#
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag multiple -->
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Multiple_Instances(page: Page, files: Files):
|
def badgeFlagMultiInstances(page: Page, files: Files):
|
||||||
icon = "material-inbox-multiple"
|
icon = "material-inbox-multiple"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#multiple-instances", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#multiple-instances", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Multiple instances')"
|
icon = f"[:{icon}:]({href} 'Multiple instances')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -659,16 +768,23 @@ def Badge_Flag_Multiple_Instances(page: Page, files: Files):
|
|||||||
# MUST add an entry in conventions.md
|
# MUST add an entry in conventions.md
|
||||||
#
|
#
|
||||||
# use the following tag in your md file:
|
# use the following tag in your md file:
|
||||||
# <!-- md:flag setting -->
|
# : <!-- md:flag --> Default
|
||||||
|
# : <!-- md:flag experimental --> Experimental
|
||||||
|
# : <!-- md:flag required --> Required
|
||||||
|
# : <!-- md:flag customization --> Customization
|
||||||
|
# : <!-- md:flag metadata --> Metadata
|
||||||
|
# : <!-- md:flag dangerous --> Dangerous
|
||||||
|
# : <!-- md:flag multiple --> Multiple
|
||||||
|
# : <!-- md:flag setting --> Setting
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def Badge_Flag_Setting(page: Page, files: Files):
|
def badgeFlagSetting(page: Page, files: Files):
|
||||||
icon = "material-cog"
|
icon = "material-cog"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#setting", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#setting", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Configurable Setting')"
|
icon = f"[:{icon}:]({href} 'Configurable Setting')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -681,13 +797,13 @@ def Badge_Flag_Setting(page: Page, files: Files):
|
|||||||
# <!-- md:control -->
|
# <!-- md:control -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_default( page: Page, files: Files ):
|
def newControlDefault( page: Page, files: Files ):
|
||||||
icon = "aetherx-axs-hand-pointer"
|
icon = "aetherx-axs-hand-pointer"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Textbox')"
|
icon = f"[:{icon}:]({href} 'Type: Textbox')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -698,13 +814,13 @@ def icon_control_default( page: Page, files: Files ):
|
|||||||
# <!-- md:control textbox -->
|
# <!-- md:control textbox -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_textbox( page: Page, files: Files ):
|
def newControlTextbox( page: Page, files: Files ):
|
||||||
icon = "aetherx-axs-input-text"
|
icon = "aetherx-axs-input-text"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Textbox')"
|
icon = f"[:{icon}:]({href} 'Type: Textbox')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -717,33 +833,33 @@ def icon_control_textbox( page: Page, files: Files ):
|
|||||||
# <!-- md:control toggle_off --> `Disabled`
|
# <!-- md:control toggle_off --> `Disabled`
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_toggle( page: Page, files: Files ):
|
def newControlToggle( page: Page, files: Files ):
|
||||||
icon = "aetherx-axs-toggle-large-on"
|
icon = "aetherx-axs-toggle-large-on"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Toggle Switch')"
|
icon = f"[:{icon}:]({href} 'Type: Toggle Switch')"
|
||||||
)
|
)
|
||||||
|
|
||||||
def icon_control_toggle_on( page: Page, files: Files ):
|
def newControlToggleOn( page: Page, files: Files ):
|
||||||
icon = "aetherx-axd-toggle-on"
|
icon = "aetherx-axd-toggle-on"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Toggle: Enabled')"
|
icon = f"[:{icon}:]({href} 'Toggle: Enabled')"
|
||||||
)
|
)
|
||||||
|
|
||||||
def icon_control_toggle_off( page: Page, files: Files ):
|
def newControlToggleOff( page: Page, files: Files ):
|
||||||
icon = "aetherx-axd-toggle-off"
|
icon = "aetherx-axd-toggle-off"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Toggle: Disabled')"
|
icon = f"[:{icon}:]({href} 'Toggle: Disabled')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -754,13 +870,13 @@ def icon_control_toggle_off( page: Page, files: Files ):
|
|||||||
# <!-- md:control dropdown -->
|
# <!-- md:control dropdown -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_dropdown( page: Page, files: Files ):
|
def newControlDropdown( page: Page, files: Files ):
|
||||||
icon = "aetherx-axs-square-caret-down"
|
icon = "aetherx-axs-square-caret-down"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files)
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Dropdown')"
|
icon = f"[:{icon}:]({href} 'Type: Dropdown')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -771,13 +887,13 @@ def icon_control_dropdown( page: Page, files: Files ):
|
|||||||
# <!-- md:control button -->
|
# <!-- md:control button -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_button( page: Page, files: Files ):
|
def newControlButton( page: Page, files: Files ):
|
||||||
icon = "material-button-pointer"
|
icon = "material-button-pointer"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Button')"
|
icon = f"[:{icon}:]({href} 'Type: Button')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -788,13 +904,13 @@ def icon_control_button( page: Page, files: Files ):
|
|||||||
# <!-- md:control slider -->
|
# <!-- md:control slider -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_slider( page: Page, files: Files ):
|
def newControlSlider( page: Page, files: Files ):
|
||||||
icon = "aetherx-axd-sliders-simple"
|
icon = "aetherx-axd-sliders-simple"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Create_Badge(
|
return badgeCreate(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Slider')"
|
icon = f"[:{icon}:]({href} 'Type: Slider')"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -805,13 +921,49 @@ def icon_control_slider( page: Page, files: Files ):
|
|||||||
# <!-- md:control color #E5E5E5 #121315 -->
|
# <!-- md:control color #E5E5E5 #121315 -->
|
||||||
# #
|
# #
|
||||||
|
|
||||||
def icon_control_color( text: str, page: Page, files: Files ):
|
def newControlColor( text: str, page: Page, files: Files ):
|
||||||
icon = "aetherx-axs-palette"
|
icon = "aetherx-axs-palette"
|
||||||
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
return Badge_ColorPalette(
|
return badgeColorPalette(
|
||||||
icon = f"[:{icon}:]({href} 'Type: Color Wheel')",
|
icon = f"[:{icon}:]({href} 'Type: Color Wheel')",
|
||||||
type = text
|
type = text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Icon : Control : Env Variable
|
||||||
|
#
|
||||||
|
# use the following tag in your md file:
|
||||||
|
# <!-- md:control env -->
|
||||||
|
# #
|
||||||
|
|
||||||
|
def newControlEnvVar( page: Page, files: Files ):
|
||||||
|
icon = "aetherx-axd-puzzle-piece"
|
||||||
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
|
return badgeCreate(
|
||||||
|
icon = f"[:{icon}:]({href} 'Type: Environment Variable')",
|
||||||
|
type = "env"
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Icon : Control : Volume
|
||||||
|
#
|
||||||
|
# use the following tag in your md file:
|
||||||
|
# <!-- md:control volume -->
|
||||||
|
# #
|
||||||
|
|
||||||
|
def newControlVolume( page: Page, files: Files ):
|
||||||
|
icon = "aetherx-axd-volume"
|
||||||
|
href = _resolve_path( f"{PAGE_CONVENTIONS}#control", page, files )
|
||||||
|
|
||||||
|
print(clr.MAGENTA + 'VERBOSE - ' + clr.WHITE + ' Running ' + clr.YELLOW + inspect.stack()[0][3] + clr.WHITE + ' for page ' + clr.GREY + str(href) + clr.WHITE )
|
||||||
|
|
||||||
|
return badgeCreate(
|
||||||
|
icon = f"[:{icon}:]({href} 'Type: Mountable Volume')",
|
||||||
|
type = "volume"
|
||||||
|
)
|
||||||
|
|||||||
127
docs/mkdocs.yml
@@ -1,10 +1,35 @@
|
|||||||
|
# #
|
||||||
|
# Mkdocs Config
|
||||||
|
#
|
||||||
|
# @notes this documentation requires the following plugins to be installed:
|
||||||
|
# pip install mkdocs
|
||||||
|
# pip install mkdocs-material
|
||||||
|
# pip install mike
|
||||||
|
# pip install mkdocs-git-committers-plugin-2
|
||||||
|
# pip install mkdocs-encryptcontent-plugin
|
||||||
|
# pip install mkdocs-embed-external-markdown
|
||||||
|
# pip install mkdocs-redirects mkdocs-glightbox pymdown-extensions mkdocs-git-revision-date-localized-plugin mkdocs-git-authors-plugin mkdocs-link-embeds-plugin
|
||||||
|
# cd docs
|
||||||
|
# mkdocs build
|
||||||
|
#
|
||||||
|
# @update use the following commands to update mkdocs and the mkdocs-material theme:
|
||||||
|
# pip install --upgrade mkdocs
|
||||||
|
# pip install --upgrade --force-reinstall mkdocs-material
|
||||||
|
# #
|
||||||
|
|
||||||
site_name: !!python/object/apply:os.getenv ["DOCS_NAME", "TVApp2"]
|
site_name: !!python/object/apply:os.getenv ["DOCS_NAME", "TVApp2"]
|
||||||
repo_url: https://github.com/TheBinaryNinja/tvapp2
|
repo_url: https://github.com/TheBinaryNinja/tvapp2
|
||||||
repo_name: TheBinaryNinja/tvapp2
|
repo_name: TheBinaryNinja/tvapp2
|
||||||
edit_uri: edit/main/docs/docs/
|
edit_uri: edit/main/docs/docs/
|
||||||
site_author: TheBinaryNinja
|
site_author: TheBinaryNinja
|
||||||
|
site_url: 'https://thebinaryninja.github.io/tvapp2/'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Markdown Extensions
|
||||||
|
# #
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
|
- pymdownx.critic
|
||||||
- markdown.extensions.extra
|
- markdown.extensions.extra
|
||||||
- toc:
|
- toc:
|
||||||
permalink: true
|
permalink: true
|
||||||
@@ -62,11 +87,15 @@ markdown_extensions:
|
|||||||
- pymdownx.keys
|
- pymdownx.keys
|
||||||
- pymdownx.snippets:
|
- pymdownx.snippets:
|
||||||
auto_append:
|
auto_append:
|
||||||
- includes/abbreviations.md
|
- docs/includes/abbreviations.md
|
||||||
url_download: true
|
url_download: true
|
||||||
- pymdownx.arithmatex:
|
- pymdownx.arithmatex:
|
||||||
generic: true
|
generic: true
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Theme
|
||||||
|
# #
|
||||||
|
|
||||||
theme:
|
theme:
|
||||||
highlightjs: true
|
highlightjs: true
|
||||||
hljs_languages:
|
hljs_languages:
|
||||||
@@ -74,6 +103,12 @@ theme:
|
|||||||
- yml
|
- yml
|
||||||
- rust
|
- rust
|
||||||
- markdown
|
- markdown
|
||||||
|
- json
|
||||||
|
- batch
|
||||||
|
- typescript
|
||||||
|
- javascript
|
||||||
|
- lua
|
||||||
|
- python
|
||||||
icon:
|
icon:
|
||||||
note: fontawesome/solid/note-sticky
|
note: fontawesome/solid/note-sticky
|
||||||
abstract: fontawesome/solid/book
|
abstract: fontawesome/solid/book
|
||||||
@@ -88,6 +123,7 @@ theme:
|
|||||||
example: fontawesome/solid/flask
|
example: fontawesome/solid/flask
|
||||||
quote: fontawesome/solid/quote-left
|
quote: fontawesome/solid/quote-left
|
||||||
annotation: material/arrow-right-circle
|
annotation: material/arrow-right-circle
|
||||||
|
hi: aetherx/axs/clock
|
||||||
tag:
|
tag:
|
||||||
html: fontawesome/brands/html5
|
html: fontawesome/brands/html5
|
||||||
js: fontawesome/brands/js
|
js: fontawesome/brands/js
|
||||||
@@ -116,8 +152,10 @@ theme:
|
|||||||
code: Roboto Mono
|
code: Roboto Mono
|
||||||
favicon: assets/favicon.png
|
favicon: assets/favicon.png
|
||||||
icon:
|
icon:
|
||||||
logo: logo
|
logo: /aetherx/axd/tv
|
||||||
features:
|
features:
|
||||||
|
- navigation.tabs
|
||||||
|
- navigation.sections
|
||||||
- announce.dismiss
|
- announce.dismiss
|
||||||
- toc.follow
|
- toc.follow
|
||||||
- content.action.edit
|
- content.action.edit
|
||||||
@@ -138,33 +176,88 @@ theme:
|
|||||||
- navigation.tracking
|
- navigation.tracking
|
||||||
- navigation.path
|
- navigation.path
|
||||||
- navigation.top
|
- navigation.top
|
||||||
|
# #
|
||||||
|
# Section › Hooks
|
||||||
|
# #
|
||||||
|
|
||||||
# Hooks
|
|
||||||
hooks:
|
hooks:
|
||||||
- material/overrides/hooks/shortcodes.py
|
- material/overrides/hooks/shortcodes.py
|
||||||
- material/overrides/hooks/translations.py
|
- material/overrides/hooks/translations.py
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Extra › CSS
|
||||||
|
# #
|
||||||
|
|
||||||
extra_css:
|
extra_css:
|
||||||
- stylesheets/extra.css?v1.000
|
- stylesheets/extra.css?v1.000
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Extra › Javascript
|
||||||
|
# #
|
||||||
|
|
||||||
extra_javascript:
|
extra_javascript:
|
||||||
- https://unpkg.com/tablesort@5.3.0/dist/tablesort.min.js
|
- https://unpkg.com/tablesort@5.3.0/dist/tablesort.min.js
|
||||||
- javascripts/tablesort.js
|
- javascripts/tablesort.js
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Extras
|
||||||
|
# #
|
||||||
|
|
||||||
|
extra:
|
||||||
|
social:
|
||||||
|
- icon: fontawesome/brands/github
|
||||||
|
link: https://github.com/TheBinaryNinja/tvapp2
|
||||||
|
- icon: fontawesome/brands/discord
|
||||||
|
link: https://discord.gg/gTze6hRe
|
||||||
|
tags:
|
||||||
|
HTML5: html
|
||||||
|
JavaScript: js
|
||||||
|
CSS: css
|
||||||
|
generator: false
|
||||||
|
version:
|
||||||
|
default: latest
|
||||||
|
provider: mike
|
||||||
|
alias: true
|
||||||
|
consent:
|
||||||
|
title: Cookie Consent
|
||||||
|
description: >-
|
||||||
|
We use cookies to recognize your repeated visits and preferences, as well
|
||||||
|
as to measure the effectiveness of our documentation and whether users
|
||||||
|
find what they're searching for. With your consent, you're helping us to
|
||||||
|
make our documentation better.
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Navigation
|
||||||
|
# #
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Home: 'home.md'
|
- Home: 'home.md'
|
||||||
- About TVApp2: 'about_tvapp2.md'
|
|
||||||
- About:
|
- About:
|
||||||
|
- What Is TVApp2: 'about/what_is_tvapp.md'
|
||||||
|
- Contributing: 'about/contributing.md'
|
||||||
- License: 'about/license.md'
|
- License: 'about/license.md'
|
||||||
|
- Wiki:
|
||||||
- Conventions: 'about/conventions.md'
|
- Conventions: 'about/conventions.md'
|
||||||
- Tags: 'about/tags.md'
|
- Tags: 'about/tags.md'
|
||||||
|
- Install:
|
||||||
|
- Getting Started: 'install/index.md'
|
||||||
|
- docker run: 'install/docker-run.md'
|
||||||
|
- docker compose: 'install/docker-compose.md'
|
||||||
|
- Config:
|
||||||
|
- Environment Variables: 'config/env.md'
|
||||||
|
- Volumes: 'config/volumes.md'
|
||||||
|
- Usage:
|
||||||
|
- Healthcheck: 'usage/healthcheck.md'
|
||||||
- Changelog: 'about/changelog.md'
|
- Changelog: 'about/changelog.md'
|
||||||
- Backers: 'backers/index.md'
|
- Discord: 'https://discord.gg/gTze6hRe'
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Section › Plugins
|
||||||
|
# #
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- search:
|
- search:
|
||||||
separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
|
separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
|
||||||
- tags:
|
|
||||||
tags_file: about/tags.md
|
|
||||||
- group:
|
- group:
|
||||||
plugins:
|
plugins:
|
||||||
- optimize
|
- optimize
|
||||||
@@ -235,28 +328,12 @@ plugins:
|
|||||||
image_default: "https://github.com/Aetherinox/mkdocs-link-embeds/assets/118329232/c0298d98-0910-4235-a88f-0c3e2f704ba7"
|
image_default: "https://github.com/Aetherinox/mkdocs-link-embeds/assets/118329232/c0298d98-0910-4235-a88f-0c3e2f704ba7"
|
||||||
image_disabled: false
|
image_disabled: false
|
||||||
favicon_default: "https://github.com/Aetherinox/mkdocs-link-embeds/assets/118329232/b37da9c6-6f17-4c3f-9c94-c346a6f31bfa"
|
favicon_default: "https://github.com/Aetherinox/mkdocs-link-embeds/assets/118329232/b37da9c6-6f17-4c3f-9c94-c346a6f31bfa"
|
||||||
favicon_disabled: true
|
favicon_disabled: false
|
||||||
favicon_size: 25
|
favicon_size: 25
|
||||||
target: "blank"
|
target: "blank"
|
||||||
accent: "FFFFFF1A"
|
accent: "FFFFFF1A"
|
||||||
verbose: true
|
verbose: true
|
||||||
|
- external-markdown
|
||||||
extra:
|
|
||||||
tags:
|
|
||||||
HTML5: html
|
|
||||||
JavaScript: js
|
|
||||||
CSS: css
|
|
||||||
generator: false
|
|
||||||
version:
|
|
||||||
default: stable
|
|
||||||
provider: mike
|
|
||||||
consent:
|
|
||||||
title: Cookie Consent
|
|
||||||
description: >-
|
|
||||||
We use cookies to recognize your repeated visits and preferences, as well
|
|
||||||
as to measure the effectiveness of our documentation and whether users
|
|
||||||
find what they're searching for. With your consent, you're helping us to
|
|
||||||
make our documentation better.
|
|
||||||
|
|
||||||
copyright: >
|
copyright: >
|
||||||
Copyright © 2025 - BinaryNinja
|
Copyright © 2025 - BinaryNinja
|
||||||
|
|||||||
@@ -6,15 +6,19 @@ MODE con:cols=125 lines=120
|
|||||||
MODE 125,40
|
MODE 125,40
|
||||||
GOTO comment_end
|
GOTO comment_end
|
||||||
|
|
||||||
Starts up mkdocs from a windows system.
|
@usage Starts up mkdocs from a windows system.
|
||||||
Ensure you have defined `GH_TOKEN` or the git-committers plugin will rate limit you.
|
Ensure you have defined `GH_TOKEN` or the git-committers plugin will rate limit you.
|
||||||
|
|
||||||
setx /m GH_TOKEN "github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
setx /m GH_TOKEN "github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
||||||
|
|
||||||
If using a Github Workflow, create a new secret in the repo settings named `GH_TOKEN`
|
If using a Github Workflow, create a new secret in the repo settings named `GH_TOKEN`
|
||||||
and give it your Github fine-grained personal access token.
|
and give it your Github fine-grained personal access token.
|
||||||
|
|
||||||
The token variable is defined in mkdocs.yml
|
The token variable is defined in mkdocs.yml
|
||||||
|
|
||||||
|
@update use the following commands to update mkdocs and the mkdocs-material theme:
|
||||||
|
pip install --upgrade mkdocs
|
||||||
|
pip install --upgrade --force-reinstall mkdocs-material
|
||||||
|
|
||||||
:comment_end
|
:comment_end
|
||||||
|
|
||||||
@@ -30,28 +34,33 @@ set dir_home=%~dp0
|
|||||||
:: define: env variable
|
:: define: env variable
|
||||||
:: #
|
:: #
|
||||||
|
|
||||||
set TOKEN=%GH_TOKEN2%
|
echo ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
echo --------------------------------------------------------------------------------
|
|
||||||
echo Mkdocs Launcher
|
echo Mkdocs Launcher
|
||||||
echo --------------------------------------------------------------------------------
|
echo ------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
IF [!TOKEN!]==[] (
|
|
||||||
echo --------------------------------------------------------------------------------
|
|
||||||
echo GH_TOKEN not defined. Open %0%
|
|
||||||
echo Create a new one at https://github.com/settings/personal-access-tokens
|
|
||||||
echo --------------------------------------------------------------------------------
|
|
||||||
set /P TOKEN= Enter Github Personal Access Token (fine-grained):
|
|
||||||
|
|
||||||
|
IF "!GH_TOKEN!"=="" (
|
||||||
|
echo GH_TOKEN not defined.
|
||||||
|
echo Open %0%
|
||||||
|
echo Create a new one at:
|
||||||
|
echo https://github.com/settings/personal-access-tokens
|
||||||
|
echo ------------------------------------------------------------------------------------------------
|
||||||
|
set /p TOKEN=" Enter Github Personal Access Token (fine-grained): "
|
||||||
)
|
)
|
||||||
|
|
||||||
echo GH_TOKEN: !TOKEN!
|
echo GH_TOKEN: !GH_TOKEN!
|
||||||
echo.
|
echo.
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
|
echo Creating environment variable GH_TOKEN
|
||||||
|
setx GH_TOKEN "!GH_TOKEN!"
|
||||||
|
|
||||||
|
timeout 2 > NUL
|
||||||
|
|
||||||
:: #
|
:: #
|
||||||
:: start mkdocs
|
:: start mkdocs
|
||||||
:: #
|
:: #
|
||||||
|
|
||||||
echo Starting mkdocs ...
|
echo Starting mkdocs ...
|
||||||
start cmd /k "mkdocs serve --clean"
|
start cmd /k "mkdocs serve --clean"
|
||||||
|
|
||||||
|
timeout 5 > NUL
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
services:
|
services:
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Service › TVApp2 › Traefik Labels
|
# Service › TVApp2
|
||||||
# #
|
# #
|
||||||
|
|
||||||
tvapp2:
|
tvapp2:
|
||||||
@@ -40,7 +40,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- /etc/timezone:/etc/timezone:ro
|
- /etc/timezone:/etc/timezone:ro
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
- ./config:/config
|
- ./config:/config
|
||||||
- ./app:/usr/bin/app
|
- ./app:/usr/bin/app
|
||||||
ulimits:
|
ulimits:
|
||||||
@@ -56,7 +55,7 @@ services:
|
|||||||
- traefik.enable=true
|
- traefik.enable=true
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Scope > http
|
# Routers › Web Interface › http
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- traefik.http.routers.tvapp2-http.rule=Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`) || Host(`www.tvapp2.domain.lan`) || Host(`${SERVICE_IP}`)
|
- traefik.http.routers.tvapp2-http.rule=Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`) || Host(`www.tvapp2.domain.lan`) || Host(`${SERVICE_IP}`)
|
||||||
@@ -66,7 +65,7 @@ services:
|
|||||||
- traefik.http.routers.tvapp2-http.middlewares=https-redirect@file
|
- traefik.http.routers.tvapp2-http.middlewares=https-redirect@file
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Scope > https
|
# Routers › Web Interface › https
|
||||||
#
|
#
|
||||||
# remove the authentik@file line if you do not wish to use Authentik or middleware
|
# remove the authentik@file line if you do not wish to use Authentik or middleware
|
||||||
# - traefik.http.routers.tvapp2-https.middlewares=authentik@file
|
# - traefik.http.routers.tvapp2-https.middlewares=authentik@file
|
||||||
@@ -83,8 +82,26 @@ services:
|
|||||||
- traefik.http.routers.tvapp2-https.middlewares=authentik@file
|
- traefik.http.routers.tvapp2-https.middlewares=authentik@file
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Load Balancer
|
# Routers › HDHomeRun
|
||||||
# #
|
# #
|
||||||
|
|
||||||
- traefik.http.services.tvapp2.loadbalancer.server.port=http
|
- traefik.http.routers.hdhr-https.rule=Host(`hdhr.domain.lan`)
|
||||||
- traefik.http.services.tvapp2.loadbalancer.server.scheme=4124
|
- traefik.http.routers.hdhr-https.service=hdhr
|
||||||
|
- traefik.http.routers.hdhr-https.entrypoints=https
|
||||||
|
- traefik.http.routers.hdhr-https.priority=1
|
||||||
|
- traefik.http.routers.hdhr-https.tls=true
|
||||||
|
- traefik.http.routers.hdhr-https.tls.certresolver=cloudflare
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Services › Main Web Interface
|
||||||
|
# #
|
||||||
|
|
||||||
|
- traefik.http.services.tvapp2.loadbalancer.server.port=4124
|
||||||
|
- traefik.http.services.tvapp2.loadbalancer.server.scheme=http
|
||||||
|
|
||||||
|
# #
|
||||||
|
# Services › HDHomeRun Server (optional)
|
||||||
|
# #
|
||||||
|
|
||||||
|
- traefik.http.services.hdhr.loadbalancer.server.port=6077
|
||||||
|
- traefik.http.services.hdhr.loadbalancer.server.scheme=http
|
||||||
|
|||||||
@@ -295,24 +295,24 @@ http:
|
|||||||
- "*.domain.lan"
|
- "*.domain.lan"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# @container TVApp2
|
# @container TVApp2 › Main
|
||||||
# @desc utomatic M3U playlist and XML guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client.
|
# @desc automatic M3U playlist and XML guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client.
|
||||||
# @url https://github.com/TheBinaryNinja/tvapp2
|
# @url https://github.com/TheBinaryNinja/tvapp2
|
||||||
#
|
#
|
||||||
# remove / comment out the authentik line if you do not plan to use authentik:
|
# remove / comment out the authentik line if you do not plan to use authentik:
|
||||||
# - authentik@file
|
# - authentik@file
|
||||||
# #
|
# #
|
||||||
|
|
||||||
tvapp2-http:
|
tvapp2-server-http:
|
||||||
service: "tvapp2"
|
service: "tvapp2-server"
|
||||||
rule: "Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`)"
|
rule: "Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`)"
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- http
|
- http
|
||||||
middlewares:
|
middlewares:
|
||||||
- https-redirect@file
|
- https-redirect@file
|
||||||
|
|
||||||
tvapp2-https:
|
tvapp2-server-https:
|
||||||
service: "tvapp2"
|
service: "tvapp2-server"
|
||||||
rule: "Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`)"
|
rule: "Host(`tvapp2.localhost`) || Host(`tvapp2.domain.lan`)"
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- https
|
- https
|
||||||
@@ -325,6 +325,37 @@ http:
|
|||||||
- main: "domain.lan"
|
- main: "domain.lan"
|
||||||
sans:
|
sans:
|
||||||
- "*.domain.lan"
|
- "*.domain.lan"
|
||||||
|
# #
|
||||||
|
# @container TVApp2 › HDHomeRun
|
||||||
|
# @desc automatic M3U playlist and XML guide updater for TheTvApp, TVPass, and MoveOnJoy utilized within your IPTV client.
|
||||||
|
# @url https://github.com/TheBinaryNinja/tvapp2
|
||||||
|
#
|
||||||
|
# remove / comment out the authentik line if you do not plan to use authentik:
|
||||||
|
# - authentik@file
|
||||||
|
# #
|
||||||
|
|
||||||
|
tvapp2-hdhr-http:
|
||||||
|
service: "tvapp2-hdhr"
|
||||||
|
rule: "Host(`hdhr.localhost`) || Host(`hdhr.domain.lan`)"
|
||||||
|
entryPoints:
|
||||||
|
- http
|
||||||
|
middlewares:
|
||||||
|
- https-redirect@file
|
||||||
|
|
||||||
|
tvapp2-hdhr-https:
|
||||||
|
service: "tvapp2-hdhr"
|
||||||
|
rule: "Host(`hdhr.localhost`) || Host(`hdhr.domain.lan`)"
|
||||||
|
entryPoints:
|
||||||
|
- https
|
||||||
|
middlewares:
|
||||||
|
- redirect-www@file
|
||||||
|
- authentik@file
|
||||||
|
tls:
|
||||||
|
certResolver: cloudflare
|
||||||
|
domains:
|
||||||
|
- main: "domain.lan"
|
||||||
|
sans:
|
||||||
|
- "*.domain.lan"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# http › Services
|
# http › Services
|
||||||
@@ -351,7 +382,12 @@ http:
|
|||||||
servers:
|
servers:
|
||||||
- url: "http://plex:32400"
|
- url: "http://plex:32400"
|
||||||
|
|
||||||
tvapp2:
|
tvapp2-server:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: "http://tvapp2:4124"
|
||||||
|
|
||||||
|
tvapp2-hdhr:
|
||||||
loadBalancer:
|
loadBalancer:
|
||||||
servers:
|
servers:
|
||||||
- url: "http://tvapp2:4124"
|
- url: "http://tvapp2:4124"
|
||||||
|
|||||||
83
renovate.json
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:recommended",
|
||||||
|
":preserveSemverRanges"
|
||||||
|
],
|
||||||
|
"timezone": "Etc/UTC",
|
||||||
|
"includeForks": true,
|
||||||
|
"forkProcessing": "enabled",
|
||||||
|
"baseBranches": ["main"],
|
||||||
|
"prCreation": "immediate",
|
||||||
|
"rebaseWhen": "conflicted",
|
||||||
|
"rebaseLabel": "AC › Needs Rebase",
|
||||||
|
"gitAuthor": "EuropaServ <161414668+EuropaServ@users.noreply.github.com>",
|
||||||
|
"updatePinnedDependencies": false,
|
||||||
|
"dependencyDashboard": true,
|
||||||
|
"dependencyDashboardTitle": "📁 Dependency Dashboard",
|
||||||
|
"dependencyDashboardLabels": ["📰 Progress Report"],
|
||||||
|
"vulnerabilityAlerts": {
|
||||||
|
"enabled": true,
|
||||||
|
"labels": ["Type ◦ Vulnerability"]
|
||||||
|
},
|
||||||
|
"labels": [
|
||||||
|
"Type ◦ Dependency"
|
||||||
|
],
|
||||||
|
"major": {
|
||||||
|
"automerge": false
|
||||||
|
},
|
||||||
|
"lockFileMaintenance": {
|
||||||
|
"enabled": true,
|
||||||
|
"automerge": true
|
||||||
|
},
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchManagers": [
|
||||||
|
"nodenv",
|
||||||
|
"npm",
|
||||||
|
"nvm"
|
||||||
|
],
|
||||||
|
"addLabels": [
|
||||||
|
"Type ◦ Dependency"
|
||||||
|
],
|
||||||
|
"rangeStrategy": "auto"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": [
|
||||||
|
"nodenv",
|
||||||
|
"npm",
|
||||||
|
"nvm"
|
||||||
|
],
|
||||||
|
"matchUpdateTypes": [
|
||||||
|
"minor",
|
||||||
|
"patch"
|
||||||
|
],
|
||||||
|
"addLabels": [
|
||||||
|
"Type ◦ Dependency"
|
||||||
|
],
|
||||||
|
"automerge": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": [
|
||||||
|
"github-actions"
|
||||||
|
],
|
||||||
|
"addLabels": [
|
||||||
|
"Type ◦ Git Action"
|
||||||
|
],
|
||||||
|
"rangeStrategy": "auto"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": [
|
||||||
|
"github-actions"
|
||||||
|
],
|
||||||
|
"addLabels": [
|
||||||
|
"Type ◦ Git Action"
|
||||||
|
],
|
||||||
|
"matchUpdateTypes": [
|
||||||
|
"minor",
|
||||||
|
"patch"
|
||||||
|
],
|
||||||
|
"automerge": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -9,10 +9,80 @@
|
|||||||
# @repo.3 https://github.com/aetherinox/docker-base-alpine
|
# @repo.3 https://github.com/aetherinox/docker-base-alpine
|
||||||
# #
|
# #
|
||||||
|
|
||||||
|
# #
|
||||||
|
# define > colors
|
||||||
|
#
|
||||||
|
# Use the color table at:
|
||||||
|
# - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A c=(
|
||||||
|
[end]=$'\e[0m'
|
||||||
|
[white]=$'\e[97m'
|
||||||
|
[bold]=$'\e[1m'
|
||||||
|
[dim]=$'\e[2m'
|
||||||
|
[underline]=$'\e[4m'
|
||||||
|
[strike]=$'\e[9m'
|
||||||
|
[blink]=$'\e[5m'
|
||||||
|
[inverted]=$'\e[7m'
|
||||||
|
[hidden]=$'\e[8m'
|
||||||
|
[black]=$'\e[0;30m'
|
||||||
|
[redl]=$'\e[0;91m'
|
||||||
|
[redd]=$'\e[0;31m'
|
||||||
|
[magental]=$'\e[0;95m'
|
||||||
|
[magentad]=$'\e[0;35mm'
|
||||||
|
[bluel]=$'\e[0;94m'
|
||||||
|
[blued]=$'\e[0;34m'
|
||||||
|
[cyanl]=$'\e[0;96m'
|
||||||
|
[cyand]=$'\e[0;36m'
|
||||||
|
[greenl]=$'\e[0;92m'
|
||||||
|
[greend]=$'\e[0;32m'
|
||||||
|
[yellowl]=$'\e[0;93m'
|
||||||
|
[yellowd]=$'\e[0;33m'
|
||||||
|
[greyl]=$'\e[0;37m'
|
||||||
|
[greyd]=$'\e[0;90m'
|
||||||
|
[navy]=$'\e[38;5;62m'
|
||||||
|
[olive]=$'\e[38;5;144m'
|
||||||
|
[peach]=$'\e[38;5;210m'
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# unicode for emojis
|
||||||
|
# https://apps.timwhitlock.info/emoji/tables/unicode
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A icon=(
|
||||||
|
["symbolic link"]=$'\xF0\x9F\x94\x97' # 🔗
|
||||||
|
["regular file"]=$'\xF0\x9F\x93\x84' # 📄
|
||||||
|
["directory"]=$'\xF0\x9F\x93\x81' # 📁
|
||||||
|
["regular empty file"]=$'\xe2\xad\x95' # ⭕
|
||||||
|
["log"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["1"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["2"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["3"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["4"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["5"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["pem"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["pub"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["pfx"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["p12"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["key"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["crt"]=$'\xF0\x9F\xAA\xAA ' # 🪪
|
||||||
|
["gz"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["zip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["gzip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["deb"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["sh"]=$'\xF0\x9F\x97\x94' # 🗔
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# define > general
|
||||||
|
# #
|
||||||
|
|
||||||
PLUGINS_PATH="/config/www/plugins"
|
PLUGINS_PATH="/config/www/plugins"
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# Plugins > Start
|
# Plugins > Start
|
||||||
# #
|
# #
|
||||||
|
|
||||||
echo -e " Loader : Checking tvapp2-plugins"
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}Checking tvapp2-plugins${c[end]}"
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
echo -e " Core : Completed loading container"
|
echo -e " Completed loading container"
|
||||||
|
|||||||
@@ -1,35 +1,173 @@
|
|||||||
#!/usr/bin/with-contenv bash
|
#!/usr/bin/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# #
|
||||||
|
# defaults
|
||||||
|
# #
|
||||||
|
|
||||||
PUID=${PUID:-911}
|
PUID=${PUID:-911}
|
||||||
PGID=${PGID:-911}
|
PGID=${PGID:-911}
|
||||||
|
DIR_BUILD=${DIR_BUILD:-/usr/src/app}
|
||||||
|
DIR_RUN=${DIR_RUN:-/usr/bin/app}
|
||||||
|
bHasError=false
|
||||||
|
|
||||||
|
# #
|
||||||
|
# define > colors
|
||||||
|
#
|
||||||
|
# Use the color table at:
|
||||||
|
# - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A c=(
|
||||||
|
[end]=$'\e[0m'
|
||||||
|
[white]=$'\e[97m'
|
||||||
|
[bold]=$'\e[1m'
|
||||||
|
[dim]=$'\e[2m'
|
||||||
|
[underline]=$'\e[4m'
|
||||||
|
[strike]=$'\e[9m'
|
||||||
|
[blink]=$'\e[5m'
|
||||||
|
[inverted]=$'\e[7m'
|
||||||
|
[hidden]=$'\e[8m'
|
||||||
|
[black]=$'\e[0;30m'
|
||||||
|
[redl]=$'\e[0;91m'
|
||||||
|
[redd]=$'\e[0;31m'
|
||||||
|
[magental]=$'\e[0;95m'
|
||||||
|
[magentad]=$'\e[0;35mm'
|
||||||
|
[bluel]=$'\e[0;94m'
|
||||||
|
[blued]=$'\e[0;34m'
|
||||||
|
[cyanl]=$'\e[0;96m'
|
||||||
|
[cyand]=$'\e[0;36m'
|
||||||
|
[greenl]=$'\e[0;92m'
|
||||||
|
[greend]=$'\e[0;32m'
|
||||||
|
[yellowl]=$'\e[0;93m'
|
||||||
|
[yellowd]=$'\e[0;33m'
|
||||||
|
[greyl]=$'\e[0;37m'
|
||||||
|
[greyd]=$'\e[0;90m'
|
||||||
|
[navy]=$'\e[38;5;62m'
|
||||||
|
[olive]=$'\e[38;5;144m'
|
||||||
|
[peach]=$'\e[38;5;210m'
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# unicode for emojis
|
||||||
|
# https://apps.timwhitlock.info/emoji/tables/unicode
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A icon=(
|
||||||
|
["symbolic link"]=$'\xF0\x9F\x94\x97' # 🔗
|
||||||
|
["regular file"]=$'\xF0\x9F\x93\x84' # 📄
|
||||||
|
["directory"]=$'\xF0\x9F\x93\x81' # 📁
|
||||||
|
["regular empty file"]=$'\xe2\xad\x95' # ⭕
|
||||||
|
["log"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["1"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["2"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["3"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["4"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["5"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["pem"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["pub"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["pfx"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["p12"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["key"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["crt"]=$'\xF0\x9F\xAA\xAA ' # 🪪
|
||||||
|
["gz"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["zip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["gzip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["deb"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["sh"]=$'\xF0\x9F\x97\x94' # 🗔
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# distro info
|
||||||
|
# #
|
||||||
|
|
||||||
|
sys_os_name="Unknown"
|
||||||
|
sys_os_ver="1.0.0"
|
||||||
|
|
||||||
|
if [ -e /etc/alpine-release ]; then
|
||||||
|
sys_os_name="Alpine"
|
||||||
|
sys_os_ver="$(cat /etc/alpine-release)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# get container ips
|
||||||
|
# #
|
||||||
|
|
||||||
IP_GATEWAY=$(/sbin/ip route|awk '/default/ { print $3 }')
|
IP_GATEWAY=$(/sbin/ip route|awk '/default/ { print $3 }')
|
||||||
IP_CONTAINER=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
|
IP_CONTAINER=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
|
||||||
|
|
||||||
|
# #
|
||||||
|
# usermod
|
||||||
|
# -o, --non-unique allow using duplicate (non-unique) UID
|
||||||
|
# -g, --gid GROUP force use GROUP as new primary group
|
||||||
|
# -G, --groups GROUPS new list of supplementary GROUPS
|
||||||
|
# -u, --uid UID new UID for the user account
|
||||||
|
# -U, --unlock unlock the user account
|
||||||
|
#
|
||||||
|
# groupmod
|
||||||
|
# -g, --gid GID change the group ID to GID
|
||||||
|
# -o, --non-unique allow to use a duplicate (non-unique) GID
|
||||||
|
# #
|
||||||
|
|
||||||
if [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
if [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
||||||
groupmod -o -g "$PGID" dockerx
|
groupmod -o -g "$PGID" dockerx
|
||||||
usermod -o -u "$PUID" dockerx
|
usermod -o -u "$PUID" dockerx
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if { [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; } || [[ ! ${TVAPP_FIRST_PARTY} = "true" ]]; then
|
# #
|
||||||
cat /etc/s6-overlay/s6-rc.d/init-adduser/branding
|
# s6 > branding
|
||||||
else
|
# #
|
||||||
cat /run/branding
|
|
||||||
fi
|
printf '%-1s\n' " ${c[greyd]}──────────────────────────────────────────────────────────────────────────────────────────${c[end]}"
|
||||||
|
printf '%-1s\n' " ${c[greyd]} TVApp2 Docker Image${c[end]}"
|
||||||
|
printf '%-1s\n' " ${c[greyd]}──────────────────────────────────────────────────────────────────────────────────────────${c[end]}"
|
||||||
|
|
||||||
|
printf '%-2s\n' " ${c[greyd]}The TvApp2 image allows you to fetch M3U playlist and EPG data for numerous IPTV ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}services online. ${c[end]}"
|
||||||
|
echo -e
|
||||||
|
printf '%-2s\n' " ${c[greyd]}Once the files are fetched by the image, you can visit the self-hosted webpage, copy ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}the links to the M3U and EPG files; and add them to your favorite IPTV app such as ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}Jellyfin, Plex, or Emby. ${c[end]}"
|
||||||
|
echo -e
|
||||||
|
printf '%-2s\n' " ${c[greyd]}For more information about this project; visit the links below. This app is served on ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}multiple repositories as backup. Use any of the repo links below: ${c[end]}"
|
||||||
|
echo -e
|
||||||
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}TVApp2 Repo 1${c[end]}" "${c[end]}https://github.com/TheBinaryNinja/tvapp2 ${c[end]}"
|
||||||
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}TVApp2 Repo 2${c[end]}" "${c[end]}https://git.binaryninja.net/BinaryNinja/tvapp2 ${c[end]}"
|
||||||
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}Base Alpine Image${c[end]}" "${c[end]}https://github.com/Aetherinox/docker-base-alpine ${c[end]}"
|
||||||
|
echo -e
|
||||||
|
|
||||||
|
printf '%-2s\n' " ${c[greyd]}If you are making this container available on a public-facing domain, please consider ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}using Traefik and Authentik to protect this container from outside access. Your M3U ${c[end]}"
|
||||||
|
printf '%-2s\n' " ${c[greyd]}and EPG files will be available for the public to download and use. ${c[end]}"
|
||||||
|
|
||||||
|
# if { [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; } || [[ ! ${TVAPP_FIRST_PARTY} = "true" ]]; then
|
||||||
|
# cat /etc/s6-overlay/s6-rc.d/init-adduser/branding
|
||||||
|
# else
|
||||||
|
# cat /run/branding
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# branding > non-root user
|
||||||
|
# #
|
||||||
|
|
||||||
if [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
if [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
||||||
echo ""
|
echo -e
|
||||||
echo " User:Group $(id -u dockerx):$(id -g dockerx)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}Distro${c[end]}" "${c[end]}${sys_os_name} ${sys_os_ver}${c[end]}"
|
||||||
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}User:Group${c[end]}" "${c[end]}$(id -u dockerx):$(id -g dockerx)${c[end]}"
|
||||||
else
|
else
|
||||||
echo " User:Group $(stat /run -c %u):$(stat /run -c %g)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}User:Group${c[end]}" "${c[end]}$(stat /run -c %u):$(stat /run -c %g)${c[end]}"
|
||||||
fi
|
fi
|
||||||
echo " Port(s) $(echo $WEB_PORT)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}Port(s)${c[end]}" "${c[end]}$(echo $WEB_PORT)${c[end]}"
|
||||||
echo " Gateway $(echo $IP_GATEWAY)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}Gateway${c[end]}" "${c[end]}$(echo $IP_GATEWAY)${c[end]}"
|
||||||
echo " Web Server $(echo $IP_CONTAINER:$WEB_PORT)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}Web Server${c[end]}" "${c[end]}$(echo $IP_CONTAINER:$WEB_PORT)${c[end]}"
|
||||||
echo " App Folder $(echo $DIR_RUN)"
|
printf '%-6s %-35s %-65s\n' "" " ${c[greenl]}App Folder${c[end]}" "${c[end]}$(echo $DIR_RUN)${c[end]}"
|
||||||
echo ""
|
echo -e
|
||||||
echo '──────────────────────────────────────────────────────────────────────────────────────────'
|
printf '%-1s\n' " ${c[greyd]}──────────────────────────────────────────────────────────────────────────────────────────${c[end]}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# set permissions
|
||||||
|
# #
|
||||||
|
|
||||||
if [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
if [[ -z ${TVAPP_READ_ONLY_FS} ]] && [[ -z ${TVAPP_NON_ROOT_USER} ]]; then
|
||||||
aetherxown dockerx:dockerx /app
|
aetherxown dockerx:dockerx /app
|
||||||
|
|||||||
@@ -1,22 +1,88 @@
|
|||||||
#!/usr/bin/with-contenv bash
|
#!/usr/bin/with-contenv bash
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# #
|
||||||
|
# define > colors
|
||||||
|
#
|
||||||
|
# Use the color table at:
|
||||||
|
# - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A c=(
|
||||||
|
[end]=$'\e[0m'
|
||||||
|
[white]=$'\e[97m'
|
||||||
|
[bold]=$'\e[1m'
|
||||||
|
[dim]=$'\e[2m'
|
||||||
|
[underline]=$'\e[4m'
|
||||||
|
[strike]=$'\e[9m'
|
||||||
|
[blink]=$'\e[5m'
|
||||||
|
[inverted]=$'\e[7m'
|
||||||
|
[hidden]=$'\e[8m'
|
||||||
|
[black]=$'\e[0;30m'
|
||||||
|
[redl]=$'\e[0;91m'
|
||||||
|
[redd]=$'\e[0;31m'
|
||||||
|
[magental]=$'\e[0;95m'
|
||||||
|
[magentad]=$'\e[0;35mm'
|
||||||
|
[bluel]=$'\e[0;94m'
|
||||||
|
[blued]=$'\e[0;34m'
|
||||||
|
[cyanl]=$'\e[0;96m'
|
||||||
|
[cyand]=$'\e[0;36m'
|
||||||
|
[greenl]=$'\e[0;92m'
|
||||||
|
[greend]=$'\e[0;32m'
|
||||||
|
[yellowl]=$'\e[0;93m'
|
||||||
|
[yellowd]=$'\e[0;33m'
|
||||||
|
[greyl]=$'\e[0;37m'
|
||||||
|
[greyd]=$'\e[0;90m'
|
||||||
|
[navy]=$'\e[38;5;62m'
|
||||||
|
[olive]=$'\e[38;5;144m'
|
||||||
|
[peach]=$'\e[38;5;210m'
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# unicode for emojis
|
||||||
|
# https://apps.timwhitlock.info/emoji/tables/unicode
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A icon=(
|
||||||
|
["symbolic link"]=$'\xF0\x9F\x94\x97' # 🔗
|
||||||
|
["regular file"]=$'\xF0\x9F\x93\x84' # 📄
|
||||||
|
["directory"]=$'\xF0\x9F\x93\x81' # 📁
|
||||||
|
["regular empty file"]=$'\xe2\xad\x95' # ⭕
|
||||||
|
["log"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["1"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["2"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["3"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["4"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["5"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["pem"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["pub"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["pfx"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["p12"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["key"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["crt"]=$'\xF0\x9F\xAA\xAA ' # 🪪
|
||||||
|
["gz"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["zip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["gzip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["deb"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["sh"]=$'\xF0\x9F\x97\x94' # 🗔
|
||||||
|
)
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
SCRIPTS_DIR="/custom-cont-init.d"
|
SCRIPTS_DIR="/custom-cont-init.d"
|
||||||
|
|
||||||
# Make sure custom init directory exists and has files in it
|
# Make sure custom init directory exists and has files in it
|
||||||
if [[ -e "${SCRIPTS_DIR}" ]] && [[ -n "$(/bin/ls -A ${SCRIPTS_DIR} 2>/dev/null)" ]]; then
|
if [[ -e "${SCRIPTS_DIR}" ]] && [[ -n "$(/bin/ls -A ${SCRIPTS_DIR} 2>/dev/null)" ]]; then
|
||||||
echo -e " Loader : Plugins found, loading them ..."
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}Loading any found plugins${c[end]}"
|
||||||
for SCRIPT in "${SCRIPTS_DIR}"/*; do
|
for SCRIPT in "${SCRIPTS_DIR}"/*; do
|
||||||
NAME="$(basename "${SCRIPT}")"
|
NAME="$(basename "${SCRIPT}")"
|
||||||
if [[ -f "${SCRIPT}" ]]; then
|
if [[ -f "${SCRIPT}" ]]; then
|
||||||
echo -e " Loader : Executing ..."
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}Executing${c[end]}"
|
||||||
/bin/bash "${SCRIPT}"
|
/bin/bash "${SCRIPT}"
|
||||||
echo -e " Loader : ${NAME}: Ran Successfully with code [$?]"
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}Successfully ran with code ${c[bluel]}[$?]${c[end]}"
|
||||||
elif [[ ! -f "${SCRIPT}" ]]; then
|
elif [[ ! -f "${SCRIPT}" ]]; then
|
||||||
echo -e " Loader : ${NAME}: Not a valid file"
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}${c[bluel]}${NAME}${c[end]} is not a valid file${c[end]}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
echo -e " Loader : No Plugins found, skipping..."
|
printf '%-29s %-65s\n' " ${c[bluel]}Loader${c[end]}" "${c[end]}No plugins found; skipping${c[end]}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,10 +1,195 @@
|
|||||||
#!/usr/bin/with-contenv sh
|
#!/usr/bin/with-contenv bash
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# #
|
||||||
|
# defaults
|
||||||
|
# #
|
||||||
|
|
||||||
|
PUID=${PUID:-911}
|
||||||
|
PGID=${PGID:-911}
|
||||||
|
DIR_BUILD=${DIR_BUILD:-/usr/src/app}
|
||||||
|
DIR_RUN=${DIR_RUN:-/usr/bin/app}
|
||||||
|
bHasError=false
|
||||||
|
|
||||||
|
# #
|
||||||
|
# define > colors
|
||||||
|
#
|
||||||
|
# Use the color table at:
|
||||||
|
# - https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A c=(
|
||||||
|
[end]=$'\e[0m'
|
||||||
|
[white]=$'\e[97m'
|
||||||
|
[bold]=$'\e[1m'
|
||||||
|
[dim]=$'\e[2m'
|
||||||
|
[underline]=$'\e[4m'
|
||||||
|
[strike]=$'\e[9m'
|
||||||
|
[blink]=$'\e[5m'
|
||||||
|
[inverted]=$'\e[7m'
|
||||||
|
[hidden]=$'\e[8m'
|
||||||
|
[black]=$'\e[0;30m'
|
||||||
|
[redl]=$'\e[0;91m'
|
||||||
|
[redd]=$'\e[0;31m'
|
||||||
|
[magental]=$'\e[0;95m'
|
||||||
|
[magentad]=$'\e[0;35mm'
|
||||||
|
[bluel]=$'\e[0;94m'
|
||||||
|
[blued]=$'\e[0;34m'
|
||||||
|
[cyanl]=$'\e[0;96m'
|
||||||
|
[cyand]=$'\e[0;36m'
|
||||||
|
[greenl]=$'\e[0;92m'
|
||||||
|
[greend]=$'\e[0;32m'
|
||||||
|
[yellowl]=$'\e[0;93m'
|
||||||
|
[yellowd]=$'\e[0;33m'
|
||||||
|
[greyl]=$'\e[0;37m'
|
||||||
|
[greyd]=$'\e[0;90m'
|
||||||
|
[navy]=$'\e[38;5;62m'
|
||||||
|
[olive]=$'\e[38;5;144m'
|
||||||
|
[peach]=$'\e[38;5;210m'
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# unicode for emojis
|
||||||
|
# https://apps.timwhitlock.info/emoji/tables/unicode
|
||||||
|
# #
|
||||||
|
|
||||||
|
declare -A icon=(
|
||||||
|
["symbolic link"]=$'\xF0\x9F\x94\x97' # 🔗
|
||||||
|
["regular file"]=$'\xF0\x9F\x93\x84' # 📄
|
||||||
|
["directory"]=$'\xF0\x9F\x93\x81' # 📁
|
||||||
|
["regular empty file"]=$'\xe2\xad\x95' # ⭕
|
||||||
|
["log"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["1"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["2"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["3"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["4"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["5"]=$'\xF0\x9F\x93\x9C' # 📜
|
||||||
|
["pem"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["pub"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["pfx"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["p12"]=$'\xF0\x9F\x94\x92' # 🔑
|
||||||
|
["key"]=$'\xF0\x9F\x94\x91' # 🔒
|
||||||
|
["crt"]=$'\xF0\x9F\xAA\xAA ' # 🪪
|
||||||
|
["gz"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["zip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["gzip"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["deb"]=$'\xF0\x9F\x93\xA6' # 📦
|
||||||
|
["sh"]=$'\xF0\x9F\x97\x94' # 🗔
|
||||||
|
)
|
||||||
|
|
||||||
|
# #
|
||||||
|
# distro info
|
||||||
|
# #
|
||||||
|
|
||||||
|
sys_os_name="Unknown"
|
||||||
|
sys_os_ver="1.0.0"
|
||||||
|
|
||||||
|
if [ -e /etc/alpine-release ]; then
|
||||||
|
sys_os_name="Alpine"
|
||||||
|
sys_os_ver="$(cat /etc/alpine-release)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# s6 > store env variables
|
||||||
|
# #
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Fetching docker container and gateway addresses${c[end]}"
|
||||||
|
|
||||||
|
# #
|
||||||
|
# get container ips
|
||||||
|
# #
|
||||||
|
|
||||||
|
ip_gateway=$(/sbin/ip route|awk '/default/ { print $3 }')
|
||||||
|
ip_container=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1')
|
||||||
|
|
||||||
|
if [ -d "/var/run/s6/container_environment/" ]; then
|
||||||
|
printf "$ip_gateway" > /var/run/s6/container_environment/IP_GATEWAY
|
||||||
|
printf "$ip_container" > /var/run/s6/container_environment/IP_CONTAINER
|
||||||
|
else
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot generate s6-overlay env files; folder ${c[redl]}/var/run/s6/container_environment/${c[end]} does not exist${c[end]}"
|
||||||
|
bHasError=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# s6 > export env vars
|
||||||
|
# #
|
||||||
|
|
||||||
|
export IP_GATEWAY=$ip_gateway
|
||||||
|
export IP_GATEWAY=$ip_container
|
||||||
|
|
||||||
# #
|
# #
|
||||||
# install and startup for tvapp2
|
# install and startup for tvapp2
|
||||||
# #
|
# #
|
||||||
|
|
||||||
cp -r ${DIR_BUILD}/* ${DIR_RUN}
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Copying ${c[bluel]}${DIR_BUILD}${c[end]} to ${c[bluel]}${DIR_RUN}${c[end]}"
|
||||||
rm -rf ${DIR_BUILD}/*
|
if [ -z "${DIR_BUILD}" ]; then
|
||||||
cd ${DIR_RUN}
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot copy; env var ${c[redl]}\${DIR_BUILD}${c[end]} missing${c[end]}"
|
||||||
npm start
|
bHasError=true
|
||||||
|
else
|
||||||
|
if [ -d "${DIR_BUILD}/" ]; then
|
||||||
|
cp -r ${DIR_BUILD}/* ${DIR_RUN}
|
||||||
|
else
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot copy folder ${c[redl]}${DIR_BUILD}${c[end]} to ${c[redl]}${DIR_RUN}${c[end]}; build folder ${c[redl]}${DIR_BUILD}${c[end]} does not exist${c[end]}"
|
||||||
|
bHasError=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# remove build directory
|
||||||
|
# #
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Remove ${c[bluel]}${DIR_BUILD}/${c[end]}"
|
||||||
|
if [ -z "${DIR_BUILD}" ]; then
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot remove; env var ${c[redl]}\${DIR_BUILD}${c[end]} missing${c[end]}"
|
||||||
|
else
|
||||||
|
if [ -d "${DIR_BUILD}" ]; then
|
||||||
|
rm -rf "${DIR_BUILD}/"
|
||||||
|
else
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot remove; build folder ${c[redl]}${DIR_BUILD}${c[end]} does not exist. Restart the container to re-initialize build folder.${c[end]}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# cd to BUILD_RUN directory
|
||||||
|
# #
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Changing to run directory ${c[bluel]}${DIR_RUN}/${c[end]}"
|
||||||
|
if [ -z "${DIR_RUN}" ]; then
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot cd; env var ${c[redl]}\${DIR_RUN}${c[end]} missing${c[end]}"
|
||||||
|
bHasError=true
|
||||||
|
else
|
||||||
|
if [ -d "${DIR_RUN}" ]; then
|
||||||
|
cd ${DIR_RUN}
|
||||||
|
else
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot cd; run folder ${c[redl]}${DIR_RUN}${c[end]} does not exist${c[end]}"
|
||||||
|
bHasError=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# install tvapp2 via npm
|
||||||
|
# #
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Running command ${c[bluel]}npm install --omit=dev${c[end]}"
|
||||||
|
if ! command -v npm; then
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Cannot install TVApp2 with npm because package ${c[redl]}npm${c[end]} not installed${c[end]}"
|
||||||
|
bHasError=true
|
||||||
|
else
|
||||||
|
npm install --omit=dev
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[bluel]}STATUS${c[end]}" "${c[end]}Running command ${c[bluel]}npm start${c[end]}"
|
||||||
|
npm start
|
||||||
|
fi
|
||||||
|
|
||||||
|
# #
|
||||||
|
# finished run script
|
||||||
|
# #
|
||||||
|
|
||||||
|
printf '%-29s %-65s\n' " ${c[greenl]}OK${c[end]}" "${c[end]}Finished initializing script${c[end]}"
|
||||||
|
if [ "$bHasError" = true ] ; then
|
||||||
|
printf '%-29s %-65s\n' "" ""
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}ERROR${c[end]}" "${c[end]}Fatal errors were detected${c[end]}"
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}${c[end]}" "${c[end]}The run script detected that certain steps failed. This app may not${c[end]}"
|
||||||
|
printf '%-29s %-65s\n' " ${c[redl]}${c[end]}" "${c[end]}work properly. Try restarting the container.${c[end]}"
|
||||||
|
printf '%-29s %-65s\n' "" ""
|
||||||
|
fi
|
||||||
|
|||||||
169
tvapp2/classes/CLib.js
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
Compress / Uncompress String with base64
|
||||||
|
|
||||||
|
these functions use a unique character table. moving the letters around will cause strings to not
|
||||||
|
be in the correct order once uncompressed.
|
||||||
|
|
||||||
|
@usage new CLib().compress( 'https://daddylive.mp/' )
|
||||||
|
new CLib().uncompress( 'burS7u6FvUHhZfrhkfJoYz8CswTD=' )
|
||||||
|
new CLib().translate( '=', plugin.defTrans, plugin.tvaTrans )
|
||||||
|
|
||||||
|
a custom character set can be specified with two additional parameters. however, anything prior
|
||||||
|
that was encoded will not be decoded by the new character set.
|
||||||
|
|
||||||
|
const strCompress = new CLib().compress( 'test.com' );
|
||||||
|
const strUncompress = new CLib().uncompress( strCompress );
|
||||||
|
|
||||||
|
new CLib().compress( 'test.com', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', 'rXzxP9ZdvehYlstwiTuV1c07j45Abo2Ama6k3gqpyf8n+/NMSEIUHBQRJDLFCGKO' )
|
||||||
|
new CLib().uncompress( 'oZcUozDkAQH=', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', 'rXzxP9ZdvehYlstwiTuV1c07j45Abo2Ama6k3gqpyf8n+/NMSEIUHBQRJDLFCGKO' )
|
||||||
|
*/
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import Log from './Log.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class > CLib
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CLib
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
this.defTrans = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||||
|
this.tvaTrans = 'TVAPp29uqXiv6g5adr1j8nfwZ0bs7Ykm3xl4hczAtoey+/CDKJULSEMBQRFGIHNO';
|
||||||
|
}
|
||||||
|
|
||||||
|
compress( data, defTrans, tvaTrans )
|
||||||
|
{
|
||||||
|
if ( typeof data === 'string' )
|
||||||
|
data = Buffer.from( data, 'utf8' );
|
||||||
|
|
||||||
|
const transDef = defTrans || this.defTrans;
|
||||||
|
const transTva = tvaTrans || this.tvaTrans;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const dataCompress = this.translate( data.toString( 'base64' ), transDef, transTva );
|
||||||
|
|
||||||
|
Log.ok( `clib`, chalk.yellow( `[compress]` ), chalk.white( `⚙️` ),
|
||||||
|
chalk.blueBright( `<msg>` ), chalk.gray( `Compress string` ),
|
||||||
|
chalk.blueBright( `<strRaw>` ), chalk.gray( `${ data }` ),
|
||||||
|
chalk.blueBright( `<strCompress>` ), chalk.gray( `${ dataCompress }` ) );
|
||||||
|
|
||||||
|
return dataCompress;
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
Log.error( `clib`, chalk.redBright( `[compress]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Could not compress string; bad string ${ data }` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err.message }` ),
|
||||||
|
chalk.redBright( `<strCompress>` ), chalk.gray( `${ data }` ) );
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uncompress( data, defTrans, tvaTrans )
|
||||||
|
{
|
||||||
|
if ( Buffer.isBuffer( data ) )
|
||||||
|
data = data.toString();
|
||||||
|
|
||||||
|
const transDef = defTrans || this.defTrans;
|
||||||
|
const transTva = tvaTrans || this.tvaTrans;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const dataTranslated = this.translate( data, transTva, transDef );
|
||||||
|
const dataUncompress = Buffer.from( dataTranslated, 'base64' ).toString( 'utf8' );
|
||||||
|
|
||||||
|
Log.ok( `clib`, chalk.yellow( `[decompss]` ), chalk.white( `⚙️` ),
|
||||||
|
chalk.blueBright( `<msg>` ), chalk.gray( `Uncompress string` ),
|
||||||
|
chalk.blueBright( `<strCompress>` ), chalk.gray( `${ data }` ),
|
||||||
|
chalk.blueBright( `<strRaw>` ), chalk.gray( `${ dataUncompress }` ) );
|
||||||
|
|
||||||
|
return dataUncompress;
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
Log.error( `clib`, chalk.redBright( `[decompss]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Could not uncompress string; bad string ${ data }` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err.message }` ),
|
||||||
|
chalk.redBright( `<strCompress>` ), chalk.gray( `${ data }` ) );
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Translate
|
||||||
|
|
||||||
|
compresses or decompresses encoded strings for the functions:
|
||||||
|
- compress
|
||||||
|
- uncompress
|
||||||
|
*/
|
||||||
|
|
||||||
|
translate( str, fromChars, toChars )
|
||||||
|
{
|
||||||
|
let res = '';
|
||||||
|
for ( let i = 0;i < str.length;i++ )
|
||||||
|
{
|
||||||
|
const char = str[i];
|
||||||
|
const index = fromChars.indexOf( char );
|
||||||
|
if ( index !== -1 )
|
||||||
|
res += toChars[index];
|
||||||
|
else
|
||||||
|
res += char;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Encode: String > Hex > Base64
|
||||||
|
|
||||||
|
encodes a human-readable string into a hex value, and then to base64
|
||||||
|
|
||||||
|
@usage const clib = new CLib()
|
||||||
|
const encoded = clib.encodeToHexBase64('hello'); // Njg2NTZjNmM2Zg==
|
||||||
|
const decoded = clib.decodeFromHexBase64(`${ encoded }`); // hello
|
||||||
|
*/
|
||||||
|
|
||||||
|
encodeToHexBase64( str )
|
||||||
|
{
|
||||||
|
const hex = [...str].map( ( char ) =>
|
||||||
|
{
|
||||||
|
const code = char.charCodeAt( 0 ).toString( 16 );
|
||||||
|
return code.padStart( 2, '0' );
|
||||||
|
}).join( '' );
|
||||||
|
|
||||||
|
const base64 = btoa( hex );
|
||||||
|
return base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Decode: Base64 > Hex > String
|
||||||
|
|
||||||
|
decodes a base64 value to hex, and then back into a human readable string
|
||||||
|
|
||||||
|
@usage const clib = new CLib()
|
||||||
|
const encoded = clib.encodeToHexBase64('hello'); // Njg2NTZjNmM2Zg==
|
||||||
|
const decoded = clib.decodeFromHexBase64(`${ encoded }`); // hello
|
||||||
|
*/
|
||||||
|
|
||||||
|
decodeFromHexBase64( base64Str )
|
||||||
|
{
|
||||||
|
const hex = atob( base64Str );
|
||||||
|
const chars = hex.match( /.{1,2}/g ); // every 2 hex chars = 1 byte
|
||||||
|
|
||||||
|
return chars.map( ( byte ) => String.fromCharCode( parseInt( byte, 16 ) ) ).join( '' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
export class
|
||||||
|
|
||||||
|
@usage import CLib from './classes/CLib.js';
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default CLib;
|
||||||
121
tvapp2/classes/Log.js
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
Define > Logs
|
||||||
|
|
||||||
|
When assigning text colors, terminals and the windows command prompt can display any color; however apps
|
||||||
|
such as Portainer console cannot. If you use 16 million colors and are viewing console in Portainer, colors will
|
||||||
|
not be the same as the rgb value. It's best to just stick to Chalk's default colors.
|
||||||
|
|
||||||
|
Various levels of logs with the following usage:
|
||||||
|
Log.verbose(`This is verbose`)
|
||||||
|
Log.debug(`This is debug`)
|
||||||
|
Log.info(`This is info`)
|
||||||
|
Log.ok(`This is ok`)
|
||||||
|
Log.notice(`This is notice`)
|
||||||
|
Log.warn(`This is warn`)
|
||||||
|
Log.error(
|
||||||
|
`Error fetching sports data with error:`,
|
||||||
|
chalk.white(`→`),
|
||||||
|
chalk.grey(`This is the error message`)
|
||||||
|
);
|
||||||
|
|
||||||
|
Level Type
|
||||||
|
-----------------------------------
|
||||||
|
6 Trace
|
||||||
|
5 Debug
|
||||||
|
4 Info
|
||||||
|
3 Notice
|
||||||
|
2 Warn
|
||||||
|
1 Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
|
/*
|
||||||
|
chalk.level
|
||||||
|
|
||||||
|
@ref https://npmjs.com/package/chalk
|
||||||
|
- 0 All colors disabled
|
||||||
|
- 1 Basic color support (16 colors)
|
||||||
|
- 2 256 color support
|
||||||
|
- 3 Truecolor support (16 million colors)
|
||||||
|
|
||||||
|
When assigning text colors, terminals and the windows command prompt can display any color; however apps
|
||||||
|
such as Portainer console cannot. If you use 16 million colors and are viewing console in Portainer, colors will
|
||||||
|
not be the same as the rgb value. It's best to just stick to Chalk's default colors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
chalk.level = 3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Define
|
||||||
|
*/
|
||||||
|
|
||||||
|
const LOG_LEVEL = process.env.LOG_LEVEL || 4;
|
||||||
|
const { name } = JSON.parse( fs.readFileSync( './package.json' ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class > Log
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
static now()
|
||||||
|
{
|
||||||
|
const now = new Date();
|
||||||
|
return chalk.gray( `[${ now.toLocaleTimeString() }]` );
|
||||||
|
}
|
||||||
|
|
||||||
|
static verbose( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 6 )
|
||||||
|
console.debug( chalk.white.bgBlack.blackBright.bold( ` ${ name } ` ), chalk.white( `⚙️` ), this.now(), chalk.gray( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static debug( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 7 )
|
||||||
|
console.trace( chalk.white.bgMagenta.bold( ` ${ name } ` ), chalk.white( `⚙️` ), this.now(), chalk.magentaBright( msg.join( ' ' ) ) );
|
||||||
|
else if ( LOG_LEVEL >= 5 )
|
||||||
|
console.debug( chalk.white.bgGray.bold( ` ${ name } ` ), chalk.white( `⚙️` ), this.now(), chalk.gray( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static info( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 4 )
|
||||||
|
console.info( chalk.white.bgBlueBright.bold( ` ${ name } ` ), chalk.white( `ℹ️` ), this.now(), chalk.blueBright( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static ok( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 4 )
|
||||||
|
console.log( chalk.white.bgGreen.bold( ` ${ name } ` ), chalk.white( `✅` ), this.now(), chalk.greenBright( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static notice( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 3 )
|
||||||
|
console.log( chalk.white.bgYellow.bold( ` ${ name } ` ), chalk.white( `📌` ), this.now(), chalk.yellowBright( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static warn( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 2 )
|
||||||
|
console.warn( chalk.white.bgYellow.bold( ` ${ name } ` ), chalk.white( `⚠️` ), this.now(), chalk.yellowBright( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static error( ...msg )
|
||||||
|
{
|
||||||
|
if ( LOG_LEVEL >= 1 )
|
||||||
|
console.error( chalk.white.bgRedBright.bold( ` ${ name } ` ), chalk.white( `❌` ), this.now(), chalk.redBright( msg.join( ' ' ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
export class
|
||||||
|
|
||||||
|
@usage import Log from './classes/Log.js';
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default Log;
|
||||||
47
tvapp2/classes/Semaphore.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Semaphore > Declare
|
||||||
|
|
||||||
|
allows multiple threads to work with the same shared resources
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Semaphore
|
||||||
|
{
|
||||||
|
constructor( max )
|
||||||
|
{
|
||||||
|
this.max = max;
|
||||||
|
this.queue = [];
|
||||||
|
this.active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async acquire()
|
||||||
|
{
|
||||||
|
if ( this.active < this.max )
|
||||||
|
{
|
||||||
|
this.active++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise( ( resolve ) => this.queue.push( resolve ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
release()
|
||||||
|
{
|
||||||
|
this.active--;
|
||||||
|
if ( this.queue.length > 0 )
|
||||||
|
{
|
||||||
|
const resolve = this.queue.shift();
|
||||||
|
this.active++;
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
export class
|
||||||
|
|
||||||
|
@usage import Log from './classes/Log.js';
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default Semaphore;
|
||||||
|
|
||||||
520
tvapp2/classes/Storage.js
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
/*
|
||||||
|
Class › Storage
|
||||||
|
|
||||||
|
The storage classes allows you to save specific settings into a json file. These settings are better off being stored in
|
||||||
|
a local file, instead of using up the resources being saved in a database.
|
||||||
|
|
||||||
|
Class supports multiple storage files, but by default, it will save settings in `www/config.json`.
|
||||||
|
|
||||||
|
Settings include Tuner / HDHomeRun device information, etc.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const storage = new Storage( envWebFolder, FILE_CFG );
|
||||||
|
*/
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import path from 'path';
|
||||||
|
import nconf from 'nconf';
|
||||||
|
import fs from 'fs';
|
||||||
|
import Log from './Log.js';
|
||||||
|
import Utils from './Utils.js';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
/*
|
||||||
|
CJS › ESM
|
||||||
|
*/
|
||||||
|
|
||||||
|
const __filename = fileURLToPath( import.meta.url ); // get resolved path to file
|
||||||
|
const __dirname = path.dirname( __filename ); // get name of directory
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class › Storage
|
||||||
|
|
||||||
|
constructor ( str:folder, str:file )
|
||||||
|
Initialize ( bool:bForceNew )
|
||||||
|
Setup ( bool:bForceNew )
|
||||||
|
Get ( str:key )
|
||||||
|
Set ( str:key, any:value )
|
||||||
|
Save ( )
|
||||||
|
GetConfig ( )
|
||||||
|
isJsonString ( json:str )
|
||||||
|
isJsonEmpty ( obj:json )
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Storage
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Constructor › Storage
|
||||||
|
|
||||||
|
Initializes a Storage instance for managing the config.json file.
|
||||||
|
Determines the full path to the config file based on folder and file arguments,
|
||||||
|
or uses the default static fileConfig if none are provided.
|
||||||
|
|
||||||
|
Handles Node.js packaged apps (process.pkg) by adjusting paths accordingly.
|
||||||
|
|
||||||
|
@args
|
||||||
|
folder (str) Optional folder where config.json will be stored. Defaults to 'www'.
|
||||||
|
file (str) Optional config file name. Defaults to static Storage.fileConfig.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const storage = new Storage(envWebFolder, FILE_CFG);
|
||||||
|
*/
|
||||||
|
|
||||||
|
static fileConfig = path.resolve( process.cwd( ), 'www', 'config.json' );
|
||||||
|
|
||||||
|
constructor( folder, file )
|
||||||
|
{
|
||||||
|
this.folderWeb = folder || 'www';
|
||||||
|
this.fileConfig = file ? path.resolve( folder, file ) : Storage.fileConfig;
|
||||||
|
|
||||||
|
if ( process.pkg )
|
||||||
|
this.fileConfig = path.join( path.dirname( process.execPath ), this.folderWeb, this.fileConfig );
|
||||||
|
else
|
||||||
|
this.fileConfig = path.resolve( process.cwd( ), this.folderWeb, this.fileConfig );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize › Activate Config Setup with Logging
|
||||||
|
|
||||||
|
Activates the Storage.Setup( ) function while providing detailed logging.
|
||||||
|
Ensures the user's config.json file exists, is valid, and is initialized
|
||||||
|
with default values if missing or corrupt.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
- Logs the start of initialization.
|
||||||
|
- Calls Setup( ) with optional force flag to recreate config.
|
||||||
|
- Catches and logs any errors during setup.
|
||||||
|
|
||||||
|
@args
|
||||||
|
bForceNew (bool) Optional. If true, forces the config file to be removed
|
||||||
|
and regenerated from defaults.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(Promise) Resolves when initialization completes, or logs an error if setup fails.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const storage = new Storage(envWebFolder, FILE_CFG);
|
||||||
|
await storage.Initialize(false);
|
||||||
|
*/
|
||||||
|
|
||||||
|
async Initialize( bForceNew )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
const bForce = bForceNew || false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.info( `conf`, chalk.yellow( `[initiate]` ), chalk.white( `ℹ️` ),
|
||||||
|
chalk.blueBright( `<msg>` ), chalk.gray( `Initializing config file` ),
|
||||||
|
chalk.blueBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
|
||||||
|
await new Storage( ).Setup( bForce );
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
console.log( 'Error writing Metadata.json:' + err.message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize › Setup User Config File
|
||||||
|
|
||||||
|
Sets up a user's config.json file, ensuring it exists and is valid JSON.
|
||||||
|
If the file is missing, empty, or invalid, it will be created or replaced.
|
||||||
|
Typically, you should call this via Storage( ).Initialize( ) rather than Setup( ) directly.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
- Creates parent directory if it doesn't exist.
|
||||||
|
- Removes existing config if bForceNew is true.
|
||||||
|
- Validates existing JSON; backs up invalid files.
|
||||||
|
- Creates default config if missing.
|
||||||
|
- Wires up nconf with argv, env, file, and default values.
|
||||||
|
|
||||||
|
@args
|
||||||
|
bForceNew (bool) Optional flag to force recreate the config file, wiping all existing data.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(Promise) Resolves true when initialization completes successfully.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const storage = new Storage(envWebFolder, FILE_CFG);
|
||||||
|
await storage.Initialize(false);
|
||||||
|
*/
|
||||||
|
|
||||||
|
async Setup( bForceNew )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
return new Promise( ( resolve, reject ) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.info( `conf`, chalk.yellow( `[generate]` ), chalk.white( `ℹ️` ),
|
||||||
|
chalk.blueBright( `<msg>` ), chalk.gray( `Initializing storage setup` ),
|
||||||
|
chalk.blueBright( `<force>` ), chalk.gray( `${ bForceNew }` ),
|
||||||
|
chalk.blueBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
ensure parent directory exists
|
||||||
|
*/
|
||||||
|
const dirPath = path.dirname( this.fileConfig );
|
||||||
|
|
||||||
|
if ( !fs.existsSync( dirPath ) )
|
||||||
|
{
|
||||||
|
fs.mkdirSync( dirPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if force flag is true, remove existing config file (force)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( bForceNew === true && fs.existsSync( this.fileConfig ) )
|
||||||
|
{
|
||||||
|
Log.ok( `conf`, chalk.yellow( `[generate]` ), chalk.white( `✅` ),
|
||||||
|
chalk.greenBright( `<msg>` ), chalk.gray( `Remove original config; force new` ),
|
||||||
|
chalk.greenBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fs.unlinkSync( this.fileConfig );
|
||||||
|
}
|
||||||
|
catch ( e )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Failed to unlink existing config` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ e.message }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if config exists, validate JSON; if invalid, move to backup and recreate
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( fs.existsSync( this.fileConfig ) )
|
||||||
|
{
|
||||||
|
let raw = null;
|
||||||
|
let parsed = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
raw = fs.readFileSync( this.fileConfig, { encoding: 'utf8' });
|
||||||
|
|
||||||
|
if ( typeof raw !== 'string' || raw.trim( ).length === 0 )
|
||||||
|
{
|
||||||
|
throw new Error( 'Empty config file' );
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed = JSON.parse( raw );
|
||||||
|
}
|
||||||
|
catch ( e )
|
||||||
|
{
|
||||||
|
const backupPath = `${ this.fileConfig }.corrupt.${ Date.now( ) }`;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fs.renameSync( this.fileConfig, backupPath );
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Config file invalid; moved to backup` ),
|
||||||
|
chalk.redBright( `<backup>` ), chalk.gray( `${ backupPath }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
}
|
||||||
|
catch ( renameErr )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Unable to backup invalid config file` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ renameErr.message }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
if ( this.rejected )
|
||||||
|
{
|
||||||
|
reject( renameErr );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if config does not exist (or was just moved because it was corrupt), create it atomically
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( !fs.existsSync( this.fileConfig ) )
|
||||||
|
{
|
||||||
|
const defaults =
|
||||||
|
{
|
||||||
|
deviceId: 'FFFFFFFF'
|
||||||
|
};
|
||||||
|
|
||||||
|
const tempPath = `${ this.fileConfig }.tmp`;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fs.writeFileSync( tempPath, JSON.stringify( defaults, null, 4 ), { encoding: 'utf8' });
|
||||||
|
fs.renameSync( tempPath, this.fileConfig );
|
||||||
|
|
||||||
|
Log.ok( `conf`, chalk.yellow( `[generate]` ), chalk.white( `✅` ),
|
||||||
|
chalk.greenBright( `<msg>` ), chalk.gray( `Created new config file with defaults` ),
|
||||||
|
chalk.greenBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
}
|
||||||
|
catch ( writeErr )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Failed to create config file` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ writeErr.message }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
|
||||||
|
if ( this.rejected )
|
||||||
|
{
|
||||||
|
reject( writeErr );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
now that file exists and is valid JSON, wire up nconf
|
||||||
|
*/
|
||||||
|
|
||||||
|
nconf.argv( ).env({ parseValues: true }).file({ file: this.fileConfig }).defaults(
|
||||||
|
{
|
||||||
|
deviceId: 'FFFFFFFF'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Could not generate and write to new config file` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err.message }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ this.fileConfig }` ) );
|
||||||
|
|
||||||
|
if ( this.rejected )
|
||||||
|
{
|
||||||
|
reject( err );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve( true );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get › Retrieve Configuration Value
|
||||||
|
|
||||||
|
Fetches a stored value from the application's persistent configuration
|
||||||
|
using the provided key via the nconf module.
|
||||||
|
|
||||||
|
This function is static, so it can be called without creating a Storage instance.
|
||||||
|
|
||||||
|
@args
|
||||||
|
key (str) The configuration key to retrieve.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(any) The value associated with the key, or undefined if the key does not exist.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const deviceId = Storage.Get('deviceId');
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Get( key )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
return nconf.get( key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set › Store Configuration Value
|
||||||
|
|
||||||
|
Stores a value in the application's persistent configuration using
|
||||||
|
the provided key via the nconf module. Automatically saves the
|
||||||
|
updated configuration to disk by calling Storage.Save( ).
|
||||||
|
|
||||||
|
This function is static, so it can be called without creating a Storage instance.
|
||||||
|
|
||||||
|
@args
|
||||||
|
key (str) The configuration key to set.
|
||||||
|
value (any) The value to store under the specified key.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(void) No return value.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
Storage.Set('deviceId', '105B35EF');
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Set( key, value )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ),
|
||||||
|
chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
nconf.set( key, value );
|
||||||
|
Storage.Save( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save › Persist Configuration to Disk
|
||||||
|
|
||||||
|
Saves the current configuration stored in nconf to disk.
|
||||||
|
After saving, the method reads back the file to verify it is valid JSON
|
||||||
|
and logs detailed status messages about success or errors.
|
||||||
|
|
||||||
|
@purpose
|
||||||
|
- Calls nconf.save() to write the current configuration.
|
||||||
|
- Reads back the saved file.
|
||||||
|
- Parses the file as JSON to confirm validity.
|
||||||
|
- Logs success or detailed error messages for failures.
|
||||||
|
|
||||||
|
@args
|
||||||
|
none
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(void) Logs success or error; does not return a value.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
Storage.Save();
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Save( )
|
||||||
|
{
|
||||||
|
const filePath = this.fileConfig;
|
||||||
|
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ),
|
||||||
|
chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
nconf.save( ( err ) =>
|
||||||
|
{
|
||||||
|
if ( err )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[snapshot]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Could not save config` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ filePath }` ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readFile( filePath, ( err, data ) =>
|
||||||
|
{
|
||||||
|
if ( err )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[snapshot]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Unable to read config file` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ filePath }` ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const parsed = JSON.parse( data.toString( ) );
|
||||||
|
|
||||||
|
Log.ok( `conf`, chalk.yellow( `[snapshot]` ), chalk.white( `✅` ),
|
||||||
|
chalk.greenBright( `<msg>` ), chalk.gray( `Save to config file successful` ),
|
||||||
|
chalk.greenBright( `<file>` ), chalk.gray( `${ filePath }` ) );
|
||||||
|
|
||||||
|
Log.debug( `conf`, chalk.yellow( `[snapshot]` ), chalk.white( `⚙️` ),
|
||||||
|
chalk.blueBright( `<msg>` ), chalk.gray( `Read values from saved config file` ),
|
||||||
|
chalk.blueBright( `<file>` ), chalk.gray( `${ filePath }` ),
|
||||||
|
chalk.blueBright( `<values>` ), chalk.gray( `${ JSON.stringify( parsed ) }` ) );
|
||||||
|
}
|
||||||
|
catch ( parseErr )
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[snapshot]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Config file is not valid JSON` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ parseErr.message }` ),
|
||||||
|
chalk.redBright( `<file>` ), chalk.gray( `${ filePath }` ) );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetConfig › Return Full Path to Config File
|
||||||
|
|
||||||
|
Returns the full path to the currently used config.json file for this Storage instance.
|
||||||
|
This is useful when you need to know the exact file location without reading its contents.
|
||||||
|
|
||||||
|
@args
|
||||||
|
none
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str) Absolute path to the config.json file.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const storage_config = Storage.GetConfig();
|
||||||
|
*/
|
||||||
|
|
||||||
|
static GetConfig( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
return this.fileConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
isJsonString › Check if Input is Valid JSON
|
||||||
|
|
||||||
|
Determines whether a given string is valid JSON by attempting
|
||||||
|
to parse it. Returns true if parsing succeeds, false if it throws
|
||||||
|
an error.
|
||||||
|
|
||||||
|
@args
|
||||||
|
json (str) The string to test for valid JSON.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(bool) True if input is valid JSON, false otherwise.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const valid = Storage.isJsonString('{"key":"value"}'); // returns true
|
||||||
|
*/
|
||||||
|
|
||||||
|
static isJsonString( json )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JSON.parse( json );
|
||||||
|
}
|
||||||
|
catch ( e )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
helper › json object empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
static isJsonEmpty( json )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
if ( Object.keys( json ).length === 0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if ( JSON.stringify( json ) === '\"{}\"' )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for ( const key in json )
|
||||||
|
{
|
||||||
|
if ( ! Object.prototype.hasOwnProperty.call( json, key ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
export class
|
||||||
|
|
||||||
|
@import
|
||||||
|
import Storage from './classes/Storage.js';
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default Storage;
|
||||||
455
tvapp2/classes/Tuner.js
Normal file
@@ -0,0 +1,455 @@
|
|||||||
|
/*
|
||||||
|
Class › Tuner
|
||||||
|
|
||||||
|
Handles HDHomeRun device management and deviceId lifecycle.
|
||||||
|
|
||||||
|
@purpose
|
||||||
|
- Generate / format HDHomeRun device IDs.
|
||||||
|
- Validate device IDs against HDHomeRun rules (length, hex chars, checksum).
|
||||||
|
- Persist device IDs using Storage class.
|
||||||
|
- Automatically generate new device ID if missing, invalid, or uninitialized (FFFFFFFF).
|
||||||
|
- Initialize tuner instances with validated device IDs.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
await new Tuner( Storage.Get( 'deviceId' ) ).Initialize( );
|
||||||
|
const tuner = new Tuner( );
|
||||||
|
await tuner.Initialize( );
|
||||||
|
const validId = await tuner.VerifyDeviceId( );
|
||||||
|
|
||||||
|
@notes
|
||||||
|
- Device IDs are persisted via the Storage class (config.json).
|
||||||
|
- User's device id must be valid before HDHomeRun will initialize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import Storage from './Storage.js';
|
||||||
|
import Utils from './Utils.js';
|
||||||
|
import Log from './Log.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class › Tuner
|
||||||
|
|
||||||
|
constructor ( str:deviceId )
|
||||||
|
Initialize ( )
|
||||||
|
Start ( )
|
||||||
|
_GenerateDeviceId ( int:len )
|
||||||
|
GenerateDeviceId ( )
|
||||||
|
GetDeviceId ( )
|
||||||
|
FormatDeviceId ( str:deviceid )
|
||||||
|
IsDeviceIdValid ( )
|
||||||
|
VerifyDeviceId ( )
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Tuner
|
||||||
|
{
|
||||||
|
constructor( deviceId )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getConstructorName( ) }` ) );
|
||||||
|
|
||||||
|
this.Name = `HDHomeRun`;
|
||||||
|
this.FriendlyName = `TVApp2`;
|
||||||
|
this.ModelNumber = `HDHR5-4US`;
|
||||||
|
this.FirmwareName = `hdhomerun5_atsc`;
|
||||||
|
this.FirmwareVersion = `0.9.15.00-RC04`;
|
||||||
|
this.SlotsConnected = 0;
|
||||||
|
this.SlotsMax = 10;
|
||||||
|
this.DeviceId = deviceId || Storage.Get( 'deviceId' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize › Setup and Start Tuner
|
||||||
|
|
||||||
|
Initializes the tuner by calling the Start( ) method.
|
||||||
|
Catches and logs any errors encountered during startup.
|
||||||
|
|
||||||
|
@args
|
||||||
|
none
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(void) Logs status; does not return a value.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
await tuner.Initialize( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
async Initialize( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this.Start( );
|
||||||
|
}
|
||||||
|
catch ( err )
|
||||||
|
{
|
||||||
|
Log.error( `hdhr`, chalk.redBright( `[initiate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Failure initializing tuner` ),
|
||||||
|
chalk.redBright( `<error>` ), chalk.gray( `${ err.message }` ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start › Initialize and Verify Device ID
|
||||||
|
|
||||||
|
Starts the tuner by verifying the current deviceId.
|
||||||
|
If the deviceId is missing or invalid, it will be regenerated and validated.
|
||||||
|
Logs the status of the deviceId once verification completes.
|
||||||
|
|
||||||
|
@args
|
||||||
|
none
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(bool) true if deviceId is valid after verification, false otherwise.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
await tuner.Start( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
async Start( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
const verifiedId = await new Tuner( ).VerifyDeviceId( this.DeviceId );
|
||||||
|
|
||||||
|
if ( await this.IsDeviceIdValid( verifiedId ) )
|
||||||
|
{
|
||||||
|
Log.ok( `conf`, chalk.yellow( `[validate]` ), chalk.white( `✅` ),
|
||||||
|
chalk.greenBright( `<msg>` ), chalk.gray( `User has valid deviceId` ),
|
||||||
|
chalk.greenBright( `<deviceId>` ), chalk.gray( `${ verifiedId }` ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
_GenerateDeviceId › Generate Raw Random Hexadecimal String
|
||||||
|
|
||||||
|
Generates a raw random hexadecimal string using Node.js crypto module.
|
||||||
|
This is typically used as the random portion of a deviceId.
|
||||||
|
|
||||||
|
@args
|
||||||
|
len (int) Optional number of bytes to generate. Defaults to 4 bytes.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str) Uppercase hexadecimal string, length = len * 2 characters.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const randomHex = Tuner._GenerateDeviceId( 4 ); // 8-character hex string
|
||||||
|
*/
|
||||||
|
|
||||||
|
static _GenerateDeviceId( len )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
return crypto.randomBytes( len || 4 ).toString( 'hex' ).toUpperCase( );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GenerateDeviceId › Generate New HDHomeRun Device ID
|
||||||
|
|
||||||
|
Generates a new, properly formatted HDHomeRun deviceId.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
- Generates 4 random hexadecimal characters.
|
||||||
|
- Prepends '105' and appends '0' to form base deviceId.
|
||||||
|
- Passes baseId to Tuner.FormatDeviceId( ) to ensure correct checksum and 8-character format.
|
||||||
|
|
||||||
|
@args
|
||||||
|
None
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str) A valid, 8-character HDHomeRun deviceId in uppercase hexadecimal.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const newDeviceId = Tuner.GenerateDeviceId( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
static GenerateDeviceId( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
const chars = '0123456789ABCDEF';
|
||||||
|
let randomHex = '';
|
||||||
|
|
||||||
|
// generate 4 random hexadecimal chars
|
||||||
|
for ( let i = 0;i < 4;i++ )
|
||||||
|
{
|
||||||
|
randomHex += chars[Math.floor( Math.random( ) * chars.length )];
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseId = '105' + randomHex + '0';
|
||||||
|
return this.FormatDeviceId( baseId );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetDeviceId › Retrieve Stored HDHomeRun Device ID
|
||||||
|
|
||||||
|
Fetches the current deviceId from persistent storage (via Storage.Get).
|
||||||
|
|
||||||
|
@args
|
||||||
|
None
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str) The current deviceId stored in configuration.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const deviceId = await tuner.GetDeviceId( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
GetDeviceId( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
return Storage.Get( 'deviceId' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
FormatDeviceId › Validate and Format HDHomeRun Device ID
|
||||||
|
|
||||||
|
Fetches the provided deviceId (or instance default) and ensures it is valid
|
||||||
|
according to HDHomeRun rules, then returns a properly formatted ID.
|
||||||
|
|
||||||
|
Steps:
|
||||||
|
- Input must be exactly 8 hexadecimal characters.
|
||||||
|
- All characters must be 0-9 or A-F/a-f.
|
||||||
|
- Computes checksum using HDHomeRun-specific lookup table.
|
||||||
|
- Generates a new deviceId integer with checksum applied.
|
||||||
|
- Converts back to 8-character uppercase hexadecimal string.
|
||||||
|
|
||||||
|
Logs detailed errors if the input deviceId is invalid.
|
||||||
|
|
||||||
|
@args
|
||||||
|
deviceid (str) Optional deviceId to format. Defaults to instance deviceId.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str|int) Formatted 8-character hex deviceId, or 0 if input invalid.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const formattedId = Tuner.FormatDeviceId( someDeviceId );
|
||||||
|
*/
|
||||||
|
|
||||||
|
static FormatDeviceId( deviceid )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
const deviceId = deviceid || this.DeviceId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Validate input length
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( !deviceId || deviceId.length !== 8 )
|
||||||
|
{
|
||||||
|
Log.error( `hdhr`, chalk.redBright( `[validate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `HDHomeRun deviceId must be 8 hexadecimals` ),
|
||||||
|
chalk.redBright( `<deviceId>` ), chalk.gray( `${ deviceId }` ) );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
All chars should be valid hexadecimal
|
||||||
|
*/
|
||||||
|
|
||||||
|
const hexPattern = /^[0-9A-Fa-f]+$/;
|
||||||
|
if ( !hexPattern.test( deviceId ) )
|
||||||
|
{
|
||||||
|
Log.error( `hdhr`, chalk.redBright( `[validate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `HDHomeRun deviceId must contain all hex (0-9, A-F, a-f)` ),
|
||||||
|
chalk.redBright( `<deviceId>` ), chalk.gray( `${ deviceId }` ) );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Hex string to integer
|
||||||
|
*/
|
||||||
|
|
||||||
|
const deviceIdInt = parseInt( deviceId, 16 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Checksum lookup table
|
||||||
|
*/
|
||||||
|
|
||||||
|
const checksumLookup =
|
||||||
|
[
|
||||||
|
0xA, 0x5, 0xF, 0x6, 0x7, 0xC, 0x1, 0xB, 0x9, 0x2, 0x8, 0xD, 0x4, 0x3, 0xE, 0x0
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calc checksum
|
||||||
|
*/
|
||||||
|
|
||||||
|
let checksum = 0;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >> 28 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >> 24 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >> 20 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >> 16 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >> 12 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >> 8 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >> 4 ) & 0x0F];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calc new device ID
|
||||||
|
*/
|
||||||
|
|
||||||
|
const newDevId = ( deviceIdInt & 0xFFFFFFF0 ) + checksum;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert back to hex string; ensure we get 8 characters with leading zeros; convert to uppercase
|
||||||
|
*/
|
||||||
|
|
||||||
|
return newDevId.toString( 16 ).toUpperCase( ).padStart( 8, '0' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
IsDeviceIdValid › Validate HDHomeRun Device ID
|
||||||
|
|
||||||
|
Checks if the current deviceId on this instance is valid according to HDHomeRun rules.
|
||||||
|
|
||||||
|
Validation steps:
|
||||||
|
- Must be exactly 8 characters long.
|
||||||
|
- All characters must be hexadecimal (0-9, A-F, a-f).
|
||||||
|
- Computes checksum using HDHomeRun-specific lookup table; must equal 0.
|
||||||
|
|
||||||
|
Logs detailed errors if the deviceId fails any validation step.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(bool) true if deviceId is valid, false otherwise.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const isValid = await tuner.IsDeviceIdValid( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
async IsDeviceIdValid( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Define Hexadecimal charset (0-9, A-F, a-f)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const hexDigits = new Set( '0123456789ABCDEFabcdef' );
|
||||||
|
const deviceId = this.DeviceId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if device ID is exactly 8 characters
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( !deviceId || deviceId.length !== 8 )
|
||||||
|
{
|
||||||
|
Log.error( `hdhr`, chalk.redBright( `[validate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `HDHomeRun deviceId must be 8 hexadecimals` ),
|
||||||
|
chalk.redBright( `<deviceId>` ), chalk.gray( `${ deviceId }` ) );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if all characters are hexadecimal
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( !Array.from( deviceId ).every( ( c ) => hexDigits.has( c ) ) )
|
||||||
|
{
|
||||||
|
Log.error( `hdhr`, chalk.redBright( `[validate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `HDHomeRun deviceId must contain all hex (0-A)` ),
|
||||||
|
chalk.redBright( `<deviceId>` ), chalk.gray( `${ deviceId }` ) );
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert hex string to integer (equivalent to int.from_bytes with big endian)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const deviceIdInt = parseInt( deviceId, 16 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Checksum lookup table
|
||||||
|
*/
|
||||||
|
|
||||||
|
const checksumLookup =
|
||||||
|
[
|
||||||
|
0xA, 0x5, 0xF, 0x6, 0x7, 0xC, 0x1, 0xB, 0x9, 0x2, 0x8, 0xD, 0x4, 0x3, 0xE, 0x0
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calc checksum
|
||||||
|
*/
|
||||||
|
|
||||||
|
let checksum = 0;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >>> 28 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >>> 24 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >>> 20 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >>> 16 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >>> 12 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >>> 8 ) & 0x0F;
|
||||||
|
checksum ^= checksumLookup[( deviceIdInt >>> 4 ) & 0x0F];
|
||||||
|
checksum ^= ( deviceIdInt >>> 0 ) & 0x0F;
|
||||||
|
|
||||||
|
return checksum === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
VerifyDeviceId › Validate / Generate Device ID
|
||||||
|
|
||||||
|
Checks if the current deviceId on this instance is valid.
|
||||||
|
|
||||||
|
If missing, uninitialized ('FFFFFFFF'), or fails validation:
|
||||||
|
a new deviceId is generated via the static Tuner.GenerateDeviceId( ) method.
|
||||||
|
|
||||||
|
New deviceId is saved to persistent storage via Storage.Set( ) and
|
||||||
|
updated on the instance.
|
||||||
|
|
||||||
|
Function also recursively verifies until a valid deviceId is established.
|
||||||
|
|
||||||
|
@returns
|
||||||
|
(str) A valid deviceId for this tuner instance.
|
||||||
|
|
||||||
|
@usage
|
||||||
|
const validId = await tuner.VerifyDeviceId( );
|
||||||
|
*/
|
||||||
|
|
||||||
|
async VerifyDeviceId( )
|
||||||
|
{
|
||||||
|
Log.verbose( `func`, chalk.yellow( `[executed]` ), chalk.white( `📣` ), chalk.blueBright( `<name>` ), chalk.gray( `${ Utils.getFuncName( ) }` ) );
|
||||||
|
|
||||||
|
const deviceId = this.DeviceId;
|
||||||
|
|
||||||
|
if ( !deviceId || deviceId === 'FFFFFFFF' || !await this.IsDeviceIdValid( ) )
|
||||||
|
{
|
||||||
|
const deviceIdNew = Tuner.GenerateDeviceId( ); // static generates a properly formatted ID
|
||||||
|
if ( deviceId === 'FFFFFFFF' )
|
||||||
|
{
|
||||||
|
Log.info( `conf`, chalk.yellow( `[generate]` ), chalk.white( `📣` ),
|
||||||
|
chalk.yellow( `<msg>` ), chalk.gray( `Generating HDHomeRun deviceId for the first time` ),
|
||||||
|
chalk.yellow( `<deviceId>` ), chalk.gray( `${ deviceIdNew }` ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.error( `conf`, chalk.redBright( `[generate]` ), chalk.white( `❌` ),
|
||||||
|
chalk.redBright( `<msg>` ), chalk.gray( `Invalid deviceId; generating new` ),
|
||||||
|
chalk.redBright( `<oldDeviceId>` ), chalk.gray( `${ deviceId }` ),
|
||||||
|
chalk.redBright( `<deviceIdNew>` ), chalk.gray( `${ deviceIdNew }` ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage.Set( 'deviceId', deviceIdNew ); // save to JSON via nconf
|
||||||
|
this.DeviceId = deviceIdNew; // update the instance so validation works
|
||||||
|
|
||||||
|
// verify recursively until valid
|
||||||
|
const verifiedId = await this.VerifyDeviceId( );
|
||||||
|
return verifiedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
export class
|
||||||
|
|
||||||
|
@image
|
||||||
|
import Tuner from './classes/Tuner.js';
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default Tuner;
|
||||||
47
tvapp2/classes/Utils.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
class Utils
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Returns the name of the function that this function was called from.
|
||||||
|
used for Log.verbose
|
||||||
|
*/
|
||||||
|
|
||||||
|
static getFuncName()
|
||||||
|
{
|
||||||
|
return ( new Error() ).stack.match( /at (\S+)/g )[1].slice( 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns the name of the constructor that this function was called from.
|
||||||
|
used for Log.verbose
|
||||||
|
*/
|
||||||
|
|
||||||
|
static getConstructorName()
|
||||||
|
{
|
||||||
|
return ( new Error() ).stack.match( /new\s+(\w+)/g )[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
helper > str2bool
|
||||||
|
*/
|
||||||
|
|
||||||
|
static str2bool( str )
|
||||||
|
{
|
||||||
|
if ( typeof str === 'string' )
|
||||||
|
{
|
||||||
|
const lower = str.toLowerCase();
|
||||||
|
if ([
|
||||||
|
'1', 'true', 'yes', 'y', 't'
|
||||||
|
].includes( lower ) )
|
||||||
|
str = true;
|
||||||
|
if ([
|
||||||
|
'0', 'false', 'no', 'n', 'f'
|
||||||
|
].includes( lower ) )
|
||||||
|
str = false;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
else return Boolean( str );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
export default Utils;
|
||||||
273
tvapp2/eslint.config.mjs
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
Eslint 9 Flat Config
|
||||||
|
|
||||||
|
old eslint < 8 .rc files are no longer supported! do not place .eslintrc files in subfolders.
|
||||||
|
eslint developers are currently working on an experimental feature to allow for sub-folder
|
||||||
|
override rules
|
||||||
|
@ref https://github.com/eslint/eslint/discussions/18574#discussioncomment-9729092
|
||||||
|
https://eslint.org/docs/latest/use/configure/configuration-files#experimental-configuration-file-resolution
|
||||||
|
|
||||||
|
eslint config migration docs
|
||||||
|
@ref https://eslint.org/docs/latest/use/configure/migration-guide
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import globals from 'globals';
|
||||||
|
import js from '@eslint/js';
|
||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Plugins
|
||||||
|
*/
|
||||||
|
|
||||||
|
import pluginImport from 'eslint-plugin-import';
|
||||||
|
import pluginNode from 'eslint-plugin-n'
|
||||||
|
import pluginChaiFriendly from 'eslint-plugin-chai-friendly';
|
||||||
|
import pluginStylistic from '@stylistic/eslint-plugin'
|
||||||
|
|
||||||
|
/*
|
||||||
|
Globals
|
||||||
|
*/
|
||||||
|
|
||||||
|
const customGlobals =
|
||||||
|
{
|
||||||
|
guid: 'readable',
|
||||||
|
uuid: 'readable',
|
||||||
|
Buffer: "readonly",
|
||||||
|
BufferEncoding: "readonly"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compatibility
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
const __filename = fileURLToPath(import.meta.url); // get resolved path to file
|
||||||
|
const __dirname = path.dirname(__filename); // get name of directory
|
||||||
|
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname, // optional; default: process.cwd()
|
||||||
|
resolvePluginsRelativeTo: __dirname, // optional
|
||||||
|
recommendedConfig: js.configs.recommended, // optional unless using 'eslint:recommended'
|
||||||
|
allConfig: js.configs.all, // optional unless using 'eslint:all'
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
Eslint > Flat Config
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default
|
||||||
|
[
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
'coverage/**',
|
||||||
|
'node_modules/**',
|
||||||
|
'**/dist/**/*',
|
||||||
|
'**/__tmp__/**/*',
|
||||||
|
'eslint.config.mjs',
|
||||||
|
'eslint.config.cjs',
|
||||||
|
"root.js",
|
||||||
|
"www/**/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...compat.extends('eslint:recommended'),
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
'n': pluginNode,
|
||||||
|
'import': pluginImport,
|
||||||
|
'@stylistic': pluginStylistic,
|
||||||
|
'chai-friendly': pluginChaiFriendly
|
||||||
|
},
|
||||||
|
linterOptions: {
|
||||||
|
reportUnusedDisableDirectives: false
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...customGlobals,
|
||||||
|
...globals.browser,
|
||||||
|
process: true, // Node.js global
|
||||||
|
_: true,
|
||||||
|
$: true
|
||||||
|
},
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
parserOptions: {
|
||||||
|
requireConfigFile: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// eslint/js rules
|
||||||
|
'one-var': 'off',
|
||||||
|
'no-throw-literal': 'off',
|
||||||
|
|
||||||
|
'camelcase': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'properties': 'always'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'no-console': 'off',
|
||||||
|
'no-alert': 'error',
|
||||||
|
'no-debugger': 'error',
|
||||||
|
'prefer-arrow-callback': 'error',
|
||||||
|
'no-useless-escape': 'off',
|
||||||
|
'no-var': 'error',
|
||||||
|
'prefer-const': 'error',
|
||||||
|
'no-unused-expressions': 0,
|
||||||
|
'chai-friendly/no-unused-expressions': 'off',
|
||||||
|
'strict': ['error', 'never'],
|
||||||
|
'prefer-promise-reject-errors': 'off',
|
||||||
|
'no-object-constructor': 'error',
|
||||||
|
'object-shorthand': 'off',
|
||||||
|
'no-array-constructor': 'error',
|
||||||
|
'array-callback-return': 'error',
|
||||||
|
'no-eval': 'error',
|
||||||
|
'no-new-func': 'error',
|
||||||
|
'prefer-rest-params': 'error',
|
||||||
|
'prefer-spread': 'error',
|
||||||
|
'no-useless-constructor': 'error',
|
||||||
|
'no-dupe-class-members': 'error',
|
||||||
|
'no-duplicate-imports': 'error',
|
||||||
|
'eqeqeq': 'error',
|
||||||
|
'no-unneeded-ternary': 'error',
|
||||||
|
'curly': 'off',
|
||||||
|
|
||||||
|
'no-empty': 'off',
|
||||||
|
'no-restricted-syntax': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'selector': 'ExportDefaultDeclaration',
|
||||||
|
'message': 'Prefer named exports'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'import/no-webpack-loader-syntax': 'off',
|
||||||
|
'import/no-relative-parent-imports': 'error',
|
||||||
|
'import/first': 'error',
|
||||||
|
'import/no-default-export': 'off',
|
||||||
|
'node/no-callback-literal': 0,
|
||||||
|
|
||||||
|
/*
|
||||||
|
@plugin eslint-plugin-n
|
||||||
|
*/
|
||||||
|
|
||||||
|
'n/no-callback-literal': 0,
|
||||||
|
'n/no-deprecated-api': 'error',
|
||||||
|
'n/no-exports-assign': 'error',
|
||||||
|
'n/no-extraneous-import': 'error',
|
||||||
|
'n/no-extraneous-require': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'allowModules': ['electron', 'electron-notarize'],
|
||||||
|
'resolvePaths': [],
|
||||||
|
'tryExtensions': []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'n/no-missing-import': 'off',
|
||||||
|
'n/no-missing-require': 'off',
|
||||||
|
'n/no-mixed-requires': 'error',
|
||||||
|
'n/no-new-require': 'error',
|
||||||
|
'n/no-path-concat': 'error',
|
||||||
|
'n/no-process-env': 'off',
|
||||||
|
'n/no-process-exit': 'off',
|
||||||
|
'n/no-restricted-import': 'error',
|
||||||
|
'n/no-restricted-require': 'error',
|
||||||
|
'n/no-sync': 'off',
|
||||||
|
'n/no-unpublished-bin': 'error',
|
||||||
|
'n/no-unpublished-import': 'error',
|
||||||
|
'n/no-unpublished-require': 'error',
|
||||||
|
'n/no-unsupported-features/es-builtins': 'error',
|
||||||
|
'n/no-unsupported-features/es-syntax': 'error',
|
||||||
|
'n/no-unsupported-features/node-builtins': 'off',
|
||||||
|
'n/prefer-global/buffer': 'error',
|
||||||
|
'n/prefer-global/console': 'error',
|
||||||
|
'n/prefer-global/process': 'error',
|
||||||
|
'n/prefer-global/text-decoder': 'error',
|
||||||
|
'n/prefer-global/text-encoder': 'error',
|
||||||
|
'n/prefer-global/url': 'error',
|
||||||
|
'n/prefer-global/url-search-params': 'error',
|
||||||
|
'n/prefer-node-protocol': 'off',
|
||||||
|
'n/prefer-promises/dns': 'off',
|
||||||
|
'n/prefer-promises/fs': 'off',
|
||||||
|
'n/process-exit-as-throw': 'error',
|
||||||
|
'@stylistic/object-property-newline': 'off',
|
||||||
|
'@stylistic/no-multi-spaces': [ 0, { ignoreEOLComments: true } ],
|
||||||
|
'@stylistic/arrow-spacing': [ 'error', { before: true, after: true } ],
|
||||||
|
'@stylistic/semi-spacing': ['error', {
|
||||||
|
before: false,
|
||||||
|
after: false,
|
||||||
|
}],
|
||||||
|
"@stylistic/space-before-function-paren": ["error", {
|
||||||
|
anonymous: "always",
|
||||||
|
asyncArrow: "never",
|
||||||
|
named: "never"
|
||||||
|
}],
|
||||||
|
'@stylistic/padded-blocks': ['error', {
|
||||||
|
blocks: 'never',
|
||||||
|
switches: 'never',
|
||||||
|
classes: 'never',
|
||||||
|
}],
|
||||||
|
'@stylistic/arrow-parens': [ 'error', 'always' ],
|
||||||
|
'@stylistic/block-spacing': [ 'error', 'always' ],
|
||||||
|
'@stylistic/comma-dangle': [ 'error', 'never' ],
|
||||||
|
'@stylistic/comma-spacing': [ 'error', { before: false, after: true }],
|
||||||
|
'@stylistic/computed-property-spacing': ['error', 'never'],
|
||||||
|
'@stylistic/no-mixed-operators': ['off'],
|
||||||
|
'@stylistic/eol-last': ['error', 'always'],
|
||||||
|
'@stylistic/jsx-quotes': ['error', 'prefer-single'],
|
||||||
|
'@stylistic/linebreak-style': ['error', 'unix'],
|
||||||
|
'@stylistic/no-mixed-spaces-and-tabs': ['error'],
|
||||||
|
'@stylistic/no-tabs': ['error'],
|
||||||
|
'@stylistic/no-trailing-spaces': ['error', { skipBlankLines: true, ignoreComments: true }],
|
||||||
|
'@stylistic/no-whitespace-before-property': ['error'],
|
||||||
|
'@stylistic/object-curly-spacing': ['error', 'always'],
|
||||||
|
'@stylistic/quote-props': ['error', 'as-needed'],
|
||||||
|
'@stylistic/quotes': ['error', 'single', { allowTemplateLiterals: 'always' }],
|
||||||
|
'@stylistic/semi': ['error', 'always'],
|
||||||
|
'@stylistic/space-infix-ops': ['error'],
|
||||||
|
'@stylistic/template-curly-spacing': ['error', 'always'],
|
||||||
|
'@stylistic/template-tag-spacing': ['error', 'always'],
|
||||||
|
'@stylistic/space-in-parens': [ 'error', 'always',
|
||||||
|
{
|
||||||
|
exceptions: ["{}", "[]"]
|
||||||
|
}],
|
||||||
|
'@stylistic/spaced-comment': [ 'error', 'always',
|
||||||
|
{
|
||||||
|
markers: ['/']
|
||||||
|
}],
|
||||||
|
'@stylistic/array-bracket-newline': [ 'warn',
|
||||||
|
{
|
||||||
|
multiline: true,
|
||||||
|
minItems: 5,
|
||||||
|
}],
|
||||||
|
'@stylistic/brace-style': [ 'error', 'allman',
|
||||||
|
{
|
||||||
|
allowSingleLine: true,
|
||||||
|
}],
|
||||||
|
'@stylistic/array-bracket-spacing': [ 'error', 'always',
|
||||||
|
{
|
||||||
|
arraysInArrays: false,
|
||||||
|
objectsInArrays: false,
|
||||||
|
singleValue: false,
|
||||||
|
}],
|
||||||
|
'@stylistic/wrap-iife': [2, 'inside', { functionPrototypeMethods: true }],
|
||||||
|
'@stylistic/keyword-spacing': [ 'error',
|
||||||
|
{
|
||||||
|
before: true,
|
||||||
|
after: true,
|
||||||
|
overrides:
|
||||||
|
{
|
||||||
|
return: { before: true, after: true },
|
||||||
|
throw: { before: true, after: true },
|
||||||
|
case: { before: true, after: true },
|
||||||
|
as: { before: true, after: true },
|
||||||
|
if: { before: true, after: true },
|
||||||
|
for: { before: true, after: true },
|
||||||
|
while: { before: true, after: true },
|
||||||
|
static: { before: true, after: true }
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
];
|
||||||
3169
tvapp2/index.js
16
tvapp2/node_modules/.bin/playwright
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../playwright/cli.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../playwright/cli.js" "$@"
|
|
||||||
fi
|
|
||||||
16
tvapp2/node_modules/.bin/playwright-core
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../playwright-core/cli.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../playwright-core/cli.js" "$@"
|
|
||||||
fi
|
|
||||||
17
tvapp2/node_modules/.bin/playwright-core.cmd
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\playwright-core\cli.js" %*
|
|
||||||
28
tvapp2/node_modules/.bin/playwright-core.ps1
generated
vendored
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../playwright-core/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../playwright-core/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../playwright-core/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../playwright-core/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
17
tvapp2/node_modules/.bin/playwright.cmd
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\playwright\cli.js" %*
|
|
||||||
28
tvapp2/node_modules/.bin/playwright.ps1
generated
vendored
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../playwright/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../playwright/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../playwright/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../playwright/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
52
tvapp2/node_modules/.package-lock.json
generated
vendored
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "tvapp2",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"node_modules/lodash.clonedeep": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
|
||||||
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
|
|
||||||
},
|
|
||||||
"node_modules/playwright": {
|
|
||||||
"version": "1.50.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz",
|
|
||||||
"integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"playwright-core": "1.50.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"playwright": "cli.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"fsevents": "2.3.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/playwright-core": {
|
|
||||||
"version": "1.50.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz",
|
|
||||||
"integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"bin": {
|
|
||||||
"playwright-core": "cli.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/user-agents": {
|
|
||||||
"version": "1.1.457",
|
|
||||||
"resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.1.457.tgz",
|
|
||||||
"integrity": "sha512-hQvZvQYUiaeAmq0qP71DRnxTd8lLkyokP/MOgN/klwnQoCECQJjVpXH901fb3JXda9qwLIFfmmPbaO18+3zovg==",
|
|
||||||
"license": "BSD-2-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"lodash.clonedeep": "^4.5.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
47
tvapp2/node_modules/lodash.clonedeep/LICENSE
generated
vendored
@@ -1,47 +0,0 @@
|
|||||||
Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|
||||||
|
|
||||||
Based on Underscore.js, copyright Jeremy Ashkenas,
|
|
||||||
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
|
|
||||||
|
|
||||||
This software consists of voluntary contributions made by many
|
|
||||||
individuals. For exact contribution history, see the revision history
|
|
||||||
available at https://github.com/lodash/lodash
|
|
||||||
|
|
||||||
The following license applies to all parts of this software except as
|
|
||||||
documented below:
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice 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.
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
Copyright and related rights for sample code are waived via CC0. Sample
|
|
||||||
code is defined as all source code displayed within the prose of the
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
CC0: http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
====
|
|
||||||
|
|
||||||
Files located in the node_modules and vendor directories are externally
|
|
||||||
maintained libraries used by this software which have their own
|
|
||||||
licenses; we recommend you read them, as their terms may differ from the
|
|
||||||
terms above.
|
|
||||||
18
tvapp2/node_modules/lodash.clonedeep/README.md
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
# lodash.clonedeep v4.5.0
|
|
||||||
|
|
||||||
The [lodash](https://lodash.com/) method `_.cloneDeep` exported as a [Node.js](https://nodejs.org/) module.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Using npm:
|
|
||||||
```bash
|
|
||||||
$ {sudo -H} npm i -g npm
|
|
||||||
$ npm i --save lodash.clonedeep
|
|
||||||
```
|
|
||||||
|
|
||||||
In Node.js:
|
|
||||||
```js
|
|
||||||
var cloneDeep = require('lodash.clonedeep');
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [documentation](https://lodash.com/docs#cloneDeep) or [package source](https://github.com/lodash/lodash/blob/4.5.0-npm-packages/lodash.clonedeep) for more details.
|
|
||||||
1748
tvapp2/node_modules/lodash.clonedeep/index.js
generated
vendored
17
tvapp2/node_modules/lodash.clonedeep/package.json
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "lodash.clonedeep",
|
|
||||||
"version": "4.5.0",
|
|
||||||
"description": "The lodash method `_.cloneDeep` exported as a module.",
|
|
||||||
"homepage": "https://lodash.com/",
|
|
||||||
"icon": "https://lodash.com/icon.svg",
|
|
||||||
"license": "MIT",
|
|
||||||
"keywords": "lodash-modularized, clonedeep",
|
|
||||||
"author": "John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
|
|
||||||
"contributors": [
|
|
||||||
"John-David Dalton <john.david.dalton@gmail.com> (http://allyoucanleet.com/)",
|
|
||||||
"Blaine Bublitz <blaine.bublitz@gmail.com> (https://github.com/phated)",
|
|
||||||
"Mathias Bynens <mathias@qiwi.be> (https://mathiasbynens.be/)"
|
|
||||||
],
|
|
||||||
"repository": "lodash/lodash",
|
|
||||||
"scripts": { "test": "echo \"See https://travis-ci.org/lodash/lodash-cli for testing details.\"" }
|
|
||||||
}
|
|
||||||
202
tvapp2/node_modules/playwright-core/LICENSE
generated
vendored
@@ -1,202 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Portions Copyright (c) Microsoft Corporation.
|
|
||||||
Portions Copyright 2017 Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
5
tvapp2/node_modules/playwright-core/NOTICE
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
Playwright
|
|
||||||
Copyright (c) Microsoft Corporation
|
|
||||||
|
|
||||||
This software contains code derived from the Puppeteer project (https://github.com/puppeteer/puppeteer),
|
|
||||||
available under the Apache 2.0 license (https://github.com/puppeteer/puppeteer/blob/master/LICENSE).
|
|
||||||
3
tvapp2/node_modules/playwright-core/README.md
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# playwright-core
|
|
||||||
|
|
||||||
This package contains the no-browser flavor of [Playwright](http://github.com/microsoft/playwright).
|
|
||||||
5
tvapp2/node_modules/playwright-core/bin/install_media_pack.ps1
generated
vendored
@@ -1,5 +0,0 @@
|
|||||||
$osInfo = Get-WmiObject -Class Win32_OperatingSystem
|
|
||||||
# check if running on Windows Server
|
|
||||||
if ($osInfo.ProductType -eq 3) {
|
|
||||||
Install-WindowsFeature Server-Media-Foundation
|
|
||||||
}
|
|
||||||
42
tvapp2/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh
generated
vendored
@@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [[ $(arch) == "aarch64" ]]; then
|
|
||||||
echo "ERROR: not supported on Linux Arm64"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$PLAYWRIGHT_HOST_PLATFORM_OVERRIDE" ]; then
|
|
||||||
if [[ ! -f "/etc/os-release" ]]; then
|
|
||||||
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
|
||||||
if [[ "${ID}" != "ubuntu" && "${ID}" != "debian" ]]; then
|
|
||||||
echo "ERROR: cannot install on $ID distribution - only Ubuntu and Debian are supported"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 1. make sure to remove old beta if any.
|
|
||||||
if dpkg --get-selections | grep -q "^google-chrome-beta[[:space:]]*install$" >/dev/null; then
|
|
||||||
apt-get remove -y google-chrome-beta
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Update apt lists (needed to install curl and chrome dependencies)
|
|
||||||
apt-get update
|
|
||||||
|
|
||||||
# 3. Install curl to download chrome
|
|
||||||
if ! command -v curl >/dev/null; then
|
|
||||||
apt-get install -y curl
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. download chrome beta from dl.google.com and install it.
|
|
||||||
cd /tmp
|
|
||||||
curl -O https://dl.google.com/linux/direct/google-chrome-beta_current_amd64.deb
|
|
||||||
apt-get install -y ./google-chrome-beta_current_amd64.deb
|
|
||||||
rm -rf ./google-chrome-beta_current_amd64.deb
|
|
||||||
cd -
|
|
||||||
google-chrome-beta --version
|
|
||||||
13
tvapp2/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
rm -rf "/Applications/Google Chrome Beta.app"
|
|
||||||
cd /tmp
|
|
||||||
curl -o ./googlechromebeta.dmg -k https://dl.google.com/chrome/mac/universal/beta/googlechromebeta.dmg
|
|
||||||
hdiutil attach -nobrowse -quiet -noautofsck -noautoopen -mountpoint /Volumes/googlechromebeta.dmg ./googlechromebeta.dmg
|
|
||||||
cp -pR "/Volumes/googlechromebeta.dmg/Google Chrome Beta.app" /Applications
|
|
||||||
hdiutil detach /Volumes/googlechromebeta.dmg
|
|
||||||
rm -rf /tmp/googlechromebeta.dmg
|
|
||||||
|
|
||||||
/Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta --version
|
|
||||||
24
tvapp2/node_modules/playwright-core/bin/reinstall_chrome_beta_win.ps1
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
$ErrorActionPreference = 'Stop'
|
|
||||||
|
|
||||||
$url = 'https://dl.google.com/tag/s/dl/chrome/install/beta/googlechromebetastandaloneenterprise64.msi'
|
|
||||||
|
|
||||||
Write-Host "Downloading Google Chrome Beta"
|
|
||||||
$wc = New-Object net.webclient
|
|
||||||
$msiInstaller = "$env:temp\google-chrome-beta.msi"
|
|
||||||
$wc.Downloadfile($url, $msiInstaller)
|
|
||||||
|
|
||||||
Write-Host "Installing Google Chrome Beta"
|
|
||||||
$arguments = "/i `"$msiInstaller`" /quiet"
|
|
||||||
Start-Process msiexec.exe -ArgumentList $arguments -Wait
|
|
||||||
Remove-Item $msiInstaller
|
|
||||||
|
|
||||||
$suffix = "\\Google\\Chrome Beta\\Application\\chrome.exe"
|
|
||||||
if (Test-Path "${env:ProgramFiles(x86)}$suffix") {
|
|
||||||
(Get-Item "${env:ProgramFiles(x86)}$suffix").VersionInfo
|
|
||||||
} elseif (Test-Path "${env:ProgramFiles}$suffix") {
|
|
||||||
(Get-Item "${env:ProgramFiles}$suffix").VersionInfo
|
|
||||||
} else {
|
|
||||||
Write-Host "ERROR: Failed to install Google Chrome Beta."
|
|
||||||
Write-Host "ERROR: This could be due to insufficient privileges, in which case re-running as Administrator may help."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
42
tvapp2/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh
generated
vendored
@@ -1,42 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
if [[ $(arch) == "aarch64" ]]; then
|
|
||||||
echo "ERROR: not supported on Linux Arm64"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$PLAYWRIGHT_HOST_PLATFORM_OVERRIDE" ]; then
|
|
||||||
if [[ ! -f "/etc/os-release" ]]; then
|
|
||||||
echo "ERROR: cannot install on unknown linux distribution (/etc/os-release is missing)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ID=$(bash -c 'source /etc/os-release && echo $ID')
|
|
||||||
if [[ "${ID}" != "ubuntu" && "${ID}" != "debian" ]]; then
|
|
||||||
echo "ERROR: cannot install on $ID distribution - only Ubuntu and Debian are supported"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 1. make sure to remove old stable if any.
|
|
||||||
if dpkg --get-selections | grep -q "^google-chrome[[:space:]]*install$" >/dev/null; then
|
|
||||||
apt-get remove -y google-chrome
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 2. Update apt lists (needed to install curl and chrome dependencies)
|
|
||||||
apt-get update
|
|
||||||
|
|
||||||
# 3. Install curl to download chrome
|
|
||||||
if ! command -v curl >/dev/null; then
|
|
||||||
apt-get install -y curl
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. download chrome stable from dl.google.com and install it.
|
|
||||||
cd /tmp
|
|
||||||
curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
|
||||||
apt-get install -y ./google-chrome-stable_current_amd64.deb
|
|
||||||
rm -rf ./google-chrome-stable_current_amd64.deb
|
|
||||||
cd -
|
|
||||||
google-chrome --version
|
|
||||||
12
tvapp2/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh
generated
vendored
@@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -e
|
|
||||||
set -x
|
|
||||||
|
|
||||||
rm -rf "/Applications/Google Chrome.app"
|
|
||||||
cd /tmp
|
|
||||||
curl -o ./googlechrome.dmg -k https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg
|
|
||||||
hdiutil attach -nobrowse -quiet -noautofsck -noautoopen -mountpoint /Volumes/googlechrome.dmg ./googlechrome.dmg
|
|
||||||
cp -pR "/Volumes/googlechrome.dmg/Google Chrome.app" /Applications
|
|
||||||
hdiutil detach /Volumes/googlechrome.dmg
|
|
||||||
rm -rf /tmp/googlechrome.dmg
|
|
||||||
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version
|
|
||||||