Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc78f4be65 | ||
|
|
8769f07539 | ||
|
|
1192d75d15 |
No files matched your search
@@ -1,10 +1,6 @@
|
|||||||
name: ForgeFlow signed release
|
name: ForgeFlow signed release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
paths:
|
|
||||||
- package.json
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
ForgeFlow is a Windows desktop application for teams that use Git, Gitea and self-hosted Docker or Unraid servers. It brings local changes, remote commits and the exact revision running on a server into one workspace, then guides review, commit, push, deployment and verification.
|
ForgeFlow is a Windows desktop application for teams that use Git, Gitea and self-hosted Docker or Unraid servers. It brings local changes, remote commits and the exact revision running on a server into one workspace, then guides review, commit, push, deployment and verification.
|
||||||
|
|
||||||
**Downloads:** Existing signed Windows releases remain at [the legacy ForgeFlow release page](https://gitea.itworx.tech/Jens/ForgeFlow/releases/latest) during the public-repository transition. The [curated public source](https://gitea.itworx.tech/Jens/ForgeFlow-Public) is separate; it will become the release destination only after signing and update compatibility are verified.
|
> **Legacy update compatibility:** This repository remains available for existing installations. Version 0.10.16 is the bridge release that moves the default updater to `Jens/ForgeFlow-Public`.
|
||||||
|
|
||||||
|
**Downloads:** Use [ForgeFlow-Public releases](https://gitea.itworx.tech/Jens/ForgeFlow-Public/releases/latest) for new installations. Older installations can receive the bridge from [this legacy release page](https://gitea.itworx.tech/Jens/ForgeFlow/releases/latest).
|
||||||
|
|
||||||
## See the workflow
|
## See the workflow
|
||||||
|
|
||||||
|
|||||||
+187
-184
@@ -1,14 +1,14 @@
|
|||||||
ForgeFlow 0.10.15 source manifest
|
ForgeFlow 0.10.16 source manifest
|
||||||
SHA-256 BYTES PATH
|
SHA-256 BYTES PATH
|
||||||
(The manifest includes tracked and non-ignored source files, excluding itself.)
|
(The manifest includes tracked and non-ignored source files, excluding itself.)
|
||||||
ec40b1ed8e5152ca4175bbe97be43f0e2e911894112dc6a47c2c348069f79abf 87 .gitattributes
|
ec40b1ed8e5152ca4175bbe97be43f0e2e911894112dc6a47c2c348069f79abf 87 .gitattributes
|
||||||
cc690743121cd3e3a4f12499024456c0b28c4aca4af0f566e57aa9ca87124ef9 883 .gitea/workflows/chatgpt-validation.yml
|
9ae6d151643de45b36312f1345960cc03137b5e79a9025e9c7b9acf4ac08a2ae 886 .gitea/workflows/chatgpt-validation.yml
|
||||||
037209289e7a387d855ee061fec9b385db57c6a31ee71c770e684f70dcae28f8 5157 .gitea/workflows/managed-validation.yml
|
ee3b2cbd2a09a95f3ebd7dfa6af3ac401b13b2ba9496f83cd9f12e15fb975c89 6740 .gitea/workflows/managed-validation.yml
|
||||||
c70a5dd662bc71e91e255b51b1a907939682259af2e27091178ef5ea231cfd77 1896 .gitea/workflows/quality.yml
|
d80f0fe159d2a1604002db4272d1d49cc3ec2097100b3a3bbb3741a855fb1a11 1900 .gitea/workflows/quality.yml
|
||||||
e6b76033c44516b625cd9f40e89824ebc8f74ef2a34666d6d44c042fc602c406 4905 .gitea/workflows/release.yml
|
72166e4caa3d3d09ce52115ac2098975a6c97a95d3f5da2305a1f8b10ae4cd02 4892 .gitea/workflows/release.yml
|
||||||
83fac3efff45f3dc926080b280ae190b6bb40eb8dae7b8cb5d27255759bc9c47 267 .gitignore
|
83fac3efff45f3dc926080b280ae190b6bb40eb8dae7b8cb5d27255759bc9c47 267 .gitignore
|
||||||
f14b4987904bcb5814e4459a057ed4d20f58a633152288a761214dcd28780b56 3 .nvmrc
|
12d3a4efa6646b3ece4782f70033b9785bf0d167b553c43e22579b031cea5c4d 4 .nvmrc
|
||||||
89545860bd6f7566da81edc8328cd2a1ebf33e81a4b0dcf2cec74338c05e8cac 1753 build-windows.ps1
|
89cfdec9f5e47fa1c4ce3f883462ffbd5a95938f1e228535782b2561142afdeb 1754 build-windows.ps1
|
||||||
0970821475a4452aa19e447e9397a95db836791f16890a1a83fd748ac033dc86 8830 build/icon-128.png
|
0970821475a4452aa19e447e9397a95db836791f16890a1a83fd748ac033dc86 8830 build/icon-128.png
|
||||||
09112c1425ca953d8dd8b2bcfd221e5a84b9f81752f7168f360e295030cbc8f2 521 build/icon-16.png
|
09112c1425ca953d8dd8b2bcfd221e5a84b9f81752f7168f360e295030cbc8f2 521 build/icon-16.png
|
||||||
510aa27935a63ad16cc22978ccfde3bdd441cb970ad42d9f05af52c0e5999195 28923 build/icon-256.png
|
510aa27935a63ad16cc22978ccfde3bdd441cb970ad42d9f05af52c0e5999195 28923 build/icon-256.png
|
||||||
@@ -18,73 +18,74 @@ ca32a76e708d565c4af659f0f4d2615fc32114c3f75aec1454862a3ed1e72c41 2263
|
|||||||
4633990a4b055bb3d00fef915ee29e85be5ee8413f809334728ad9688973c183 3364 build/icon-64.png
|
4633990a4b055bb3d00fef915ee29e85be5ee8413f809334728ad9688973c183 3364 build/icon-64.png
|
||||||
25048ed854e8ce8fece115e555c98d25507b002f8019b6ae717b54604c868c50 46223 build/icon.ico
|
25048ed854e8ce8fece115e555c98d25507b002f8019b6ae717b54604c868c50 46223 build/icon.ico
|
||||||
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 build/icon.png
|
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 build/icon.png
|
||||||
164c059453a5737110b4e5e98b6211650c757f0aff710f8f7523ffe0ff1815d7 113 build/update-signing-public.pem
|
5cc93571f6c5648cad5116680ae5218f486407c5026ee37cb0ab2fe93a16a0b4 116 build/update-signing-public.pem
|
||||||
5f4aca19a35cbcaffa1a6993ce96b7d66052ec2b286022f2af74594e8a310568 15712 CHANGELOG.md
|
343ea8dc00a3257801ecc199518a65d4d4adb2644c3acf7b614eb66032ab2afb 15969 CHANGELOG.md
|
||||||
3754dcaa776ead5dc60b4955ed4294fd8580577ecb9ce29cb0d9fbbaf9253313 811 CONTRIBUTING.md
|
3754dcaa776ead5dc60b4955ed4294fd8580577ecb9ce29cb0d9fbbaf9253313 811 CONTRIBUTING.md
|
||||||
c612fcc44ff222db0c9a4cfd11a4076fafe080e4ada31e689a08739a4f14e74f 1650 docs/ACCEPTANCE.md
|
33954dcf8b898885c94fa486a1753a1298dfe6846fe4c5c6dff91d22f64ffe60 1684 docs/ACCEPTANCE.md
|
||||||
3785ad21872e3dc08fde9ef819e26f42161ba6ce6d235f87fcebd7859dfaf148 8293 docs/ARCHITECTURE.md
|
b89ffb60db36a9cca0ed9ca70edd7e8e5d427d51846b93e8383ce6f406309a9d 8514 docs/ARCHITECTURE.md
|
||||||
e05458ee2696e3c57e2475bb42ae1f914f6a36e01768d7a26a3199f1fffed490 1157 docs/COVERAGE_POLICY.md
|
6450bf6b1b5028a6dd9f928f6cbb5a84281a68c24361e2a4216679993e7fb149 1175 docs/COVERAGE_POLICY.md
|
||||||
9eb9eec82518c0bfc7686f5faaf690a93ed63c71d35f1dc5a2c5ec5199da652a 3124 docs/CURRENT_STATE.md
|
af6d5af037687a09a43f14cc19ffe75f959a110765fbddc1ab2803833f735764 3178 docs/CURRENT_STATE.md
|
||||||
8ea655d1912ac2e17f8834e33a566a8b14461b396ec4268c396ca189a1749b94 2205 docs/DEPENDENCY_AUDIT.md
|
1923c673d5cf8b5aa5fbd500eaef648f3b3eaf47527d34e3d0bb34474da8822e 2251 docs/DEPENDENCY_AUDIT.md
|
||||||
3b9c301313a6406c39ec09f5ad7247dafdf47f6c21505ab8970b206cb1734f31 2788 docs/DEPLOYMENT_MIGRATION_EXAMPLE.md
|
4d4b5539024c3805a087f92c85ab48e9aaab366aa68d3e4aa558139a019dc4ba 2851 docs/DEPLOYMENT_MIGRATION_EXAMPLE.md
|
||||||
30a92bcf5daadb019efa2f82cb820ea302490dd1d68fb772674dc3faccd3e594 2045 docs/DEPLOYMENT_SETUP.md
|
e9163fbd6a0532f483e32b4009cedd92f84946e4b949107f8c21cc7c2e4f86d3 2103 docs/DEPLOYMENT_SETUP.md
|
||||||
eb42f979666e05d51c587e4223282914926a2b9b1ade9f3fb75525019ce7f738 4616 docs/DIAGNOSTICS.md
|
8a1be38b097c1cbfaaaee150c64b99f44bbe007817200d675a2b583d8f2198e5 4766 docs/DIAGNOSTICS.md
|
||||||
1d8aa3c688a9d330b9a5303b09e9e3049c50bf04f97807c7ff659607baa34c32 1464 docs/ERROR_CODES.md
|
ff0d8aea8eff6b211493c99fbb8ee7d67bb70eb1d0b4312f3961f651a17c5683 1479 docs/ERROR_CODES.md
|
||||||
648dd6bca6b45668fb86eb3e1f6c5898dd8da0291b990f1bb5105cfd79421343 1301 docs/MUTATION_MODEL.md
|
303d2558da306550e50f2704bfae0fb23e8abee428db436097d9838a9c6956df 1327 docs/MUTATION_MODEL.md
|
||||||
8dc95f69e6f6c8415702c8e79fb6b466c4d60061afded9140450e7e558eaefe5 3704 docs/PRODUCTION_READINESS_1.0.md
|
52fd7c73bcf82ae27ffe12751590d0b05e5fefbafe4a4939e225a6b9258cf0a1 3782 docs/PRODUCTION_READINESS_1.0.md
|
||||||
f79908fb3dad98c38030c6e6be7c79a1999e0478ed9c2496923891954438daa1 4581 docs/RELEASE_AUDIT_0.6.0.md
|
f79908fb3dad98c38030c6e6be7c79a1999e0478ed9c2496923891954438daa1 4581 docs/RELEASE_AUDIT_0.6.0.md
|
||||||
979a0b8e129979be6b265e8571d0a3c1e9ddd4ddb6b0bf55ae748d3478e51854 2296 docs/RELEASE_NOTES_0.10.0.md
|
2b07fd178fe6dd7c2233876c4aa7de5d2371635755e7ac1f2acbbd5b298d491f 2328 docs/RELEASE_NOTES_0.10.0.md
|
||||||
0eb44bda2209a5979a6ac693ac4cd4d235c0015031e54b9e895990f37bf60054 1433 docs/RELEASE_NOTES_0.10.1.md
|
48da50bb0bd0628187ca2f879f1e58d54978f2a7e30cf0c71df9b55a240d7ba6 1454 docs/RELEASE_NOTES_0.10.1.md
|
||||||
5d3240169765e3fb1d3cd391d09547101227e76dd4670ee46be8ca3a21553a03 894 docs/RELEASE_NOTES_0.10.10.md
|
b0202cf6615c149bd79ec8033e99966b54603df3ffad966d91ad0304371b8f97 904 docs/RELEASE_NOTES_0.10.10.md
|
||||||
36edb4f096a248fb8679bd13e5766befb478cf628c6ccfb21e3eda71bbec7633 992 docs/RELEASE_NOTES_0.10.11.md
|
4724c6f2ca9a8d5126552fa1577c4c53d3c6f14946dc29981408e2543f3a76b5 1002 docs/RELEASE_NOTES_0.10.11.md
|
||||||
a355d3f577c2ec85dde5dfd7b6995f4f1615e2f6bac597529f3ff102acd93c35 1292 docs/RELEASE_NOTES_0.10.12.md
|
876c6794ed47ac83d7042b681946c80ba66ac5cc3e24f5ac53f15c4f194850e8 1304 docs/RELEASE_NOTES_0.10.12.md
|
||||||
609c55a1c0b06c307ebe16f2daaf1e48601edd57137586e4f2be1febd6a7060a 1931 docs/RELEASE_NOTES_0.10.13.md
|
7ad75d0a052d9b99b91e78f9b8d3bfe55e3df15e7182d43bd7cfe405a8cfb5fd 1949 docs/RELEASE_NOTES_0.10.13.md
|
||||||
1d5832048dd834a773ee8f34e6599c590373358132203b022b521dd5dde2f179 1571 docs/RELEASE_NOTES_0.10.14.md
|
1d5832048dd834a773ee8f34e6599c590373358132203b022b521dd5dde2f179 1571 docs/RELEASE_NOTES_0.10.14.md
|
||||||
055ad0c73f0854a708eedc3bc4e9dfb991b4e6021348c05484da9a47022e995b 1871 docs/RELEASE_NOTES_0.10.15.md
|
055ad0c73f0854a708eedc3bc4e9dfb991b4e6021348c05484da9a47022e995b 1871 docs/RELEASE_NOTES_0.10.15.md
|
||||||
8d713471a437a8a55b00d7e1dd95290680862107bc4e586cf27d727f6274e46c 577 docs/RELEASE_NOTES_0.10.2.md
|
36d0686bf5760b0d8445cbd1abfc76de71c98d037a1b05d3cbdd4a3e7810bb27 1062 docs/RELEASE_NOTES_0.10.16.md
|
||||||
0942fb2c4a4f972296423b5232687f7389e2c6417a9d48a3244beef9dec907b9 1164 docs/RELEASE_NOTES_0.10.3.md
|
5b10081a98fab0a0394f5216beb3c2e81d9451796d1c325965e984a4edcef44c 586 docs/RELEASE_NOTES_0.10.2.md
|
||||||
8f4a0fe6dc250ae210cc2fc1c57c46091822ae6c2a58caa76e0091f255f9f30d 775 docs/RELEASE_NOTES_0.10.4.md
|
53e4c0d64342715a981ba0f695fa2a20cac22a33839db808816dbfa1a1e0296a 1182 docs/RELEASE_NOTES_0.10.3.md
|
||||||
05ed618f5a74a854363930128ca98939808517eedd28b9a508660a0c46e91d97 884 docs/RELEASE_NOTES_0.10.5.md
|
a26021f356a0b78e4393e14cf5f2dd5752316698ac926c67b7978ebe8859c6b5 783 docs/RELEASE_NOTES_0.10.4.md
|
||||||
94bfb2783c1befad1197e1c5e32fc002222c94a28d70d48360a8d53ecd260d5c 772 docs/RELEASE_NOTES_0.10.6.md
|
cd3f7bd1236013ba9fe0afe0ad8758fbbb9beddaf51872936b2c07323cd65eca 894 docs/RELEASE_NOTES_0.10.5.md
|
||||||
226a3b2d4bc7f54841749a283fcdd71b643cd585ba74d673084bee829fef6ea2 903 docs/RELEASE_NOTES_0.10.7.md
|
f1bbcb3a61c7b3ef255e921ef016d85f11b1eb2a1dcc7ad7bb8a738efe6e213f 781 docs/RELEASE_NOTES_0.10.6.md
|
||||||
4be29ad0cb7ebcf5625172b8d2bd7a67cdc6d64d3a94e2c3f0656cdfd42dcb7a 642 docs/RELEASE_NOTES_0.10.8.md
|
a3b08b9680c5db304c05a0880ac1bb987b02dc20700e4ae61b0e4ebb71d63cfd 913 docs/RELEASE_NOTES_0.10.7.md
|
||||||
fb64517aa64d3ecfe8b51b09e198c2c9fbba96d0cd24a87301c7f6dea3076095 961 docs/RELEASE_NOTES_0.10.9.md
|
3b68776b94c73b72fd069fee7792680bd58523b8a5f34de74216c6255a9fdfdf 651 docs/RELEASE_NOTES_0.10.8.md
|
||||||
a0c00ff76acd1682bb5e0e8dcf6589c9480da436c9c6d30780a1ed58b4dad94f 1770 docs/RELEASE_NOTES_0.2.0.md
|
753e0b0f2c00a6c8ec687294625731d6c4f158509ac76bd08005fff626943bee 971 docs/RELEASE_NOTES_0.10.9.md
|
||||||
5773ead01aa4c522c556295553787482d01b1f5242f053b2c61f120c4de4fa76 5963 docs/RELEASE_NOTES_0.3.0.md
|
532414fab6a23780dd1fdf9905846582905de9ad2f978542a8376915e73bae9b 1802 docs/RELEASE_NOTES_0.2.0.md
|
||||||
d46de73cf6c4cd5c2ba3f455a7a2af2e0d64ee9d94a97fd1a0bfb44e35c1624a 1093 docs/RELEASE_NOTES_0.3.1.md
|
9a79ba9626b852be368afdb687b39e5c12b4674dd716e565c1a3776acd365ef7 6103 docs/RELEASE_NOTES_0.3.0.md
|
||||||
0d697d241a08d2427a6e7f5c2f27bd1830a41836a01e08eeff239c7ad5d89982 2445 docs/RELEASE_NOTES_0.3.2.md
|
cc9eed982cf7c99af2ccbb8e0dd9fd61f0d494603fc2fe7d14a3288aa4ea0d76 1118 docs/RELEASE_NOTES_0.3.1.md
|
||||||
df07794fb3923f3fb6a49dacbfcc5a371227edb592b4e86ecffaae0a8799f187 2154 docs/RELEASE_NOTES_0.4.0.md
|
8498aeb28590640608191add4dcc11f58adcd8d0caafc947cf98019ee557cd42 2527 docs/RELEASE_NOTES_0.3.2.md
|
||||||
343862445061e1a8282a7aa9b2304e7d799e58f9956d50eb5352db18d790efad 1134 docs/RELEASE_NOTES_0.4.1.md
|
48aec5e22fd5392114b8a862f9d2b42c0a891a3af0d935b765706bf21f694b64 2211 docs/RELEASE_NOTES_0.4.0.md
|
||||||
e2d67c816a919f00f9e26bf59cf29e5e8cf894536b743d282075c646c5accc96 1605 docs/RELEASE_NOTES_0.4.2.md
|
e583003bfcf6563e13855ad1c9eb6ff55f6bb1a618982fb0d7336fe6bf8de22a 1160 docs/RELEASE_NOTES_0.4.1.md
|
||||||
1aef74fb109541903c4dbc4d9c48d2bd63507420eaf8cceb31890797a5e4f5fd 670 docs/RELEASE_NOTES_0.4.3.md
|
98c881fe56ca1fea2e4a6cc22926fb5345629677a525c87167f835b4d5184bab 1634 docs/RELEASE_NOTES_0.4.2.md
|
||||||
85fecec65f7687e1382547166eff62777613825a8d81960dfcb4ae16aa15c8be 617 docs/RELEASE_NOTES_0.4.4.md
|
c4891e1c31aeee208855d496053a373ed9cbfd4d8353cb3ef5e4ba28dcd70c95 679 docs/RELEASE_NOTES_0.4.3.md
|
||||||
5cd0cffecdce942fb1024a0410568174e7704af9bacbe42f81891693a1817a19 378 docs/RELEASE_NOTES_0.4.5.md
|
dc6402c30f48b57d000a207779e659f45319d890aceb2ec34b56c79668b10c6f 626 docs/RELEASE_NOTES_0.4.4.md
|
||||||
f9554c10f56d41d916330f06175b07f099c9ed1534f00abc9ea7f94be70f4a97 1097 docs/RELEASE_NOTES_0.5.0.md
|
6b326bff00dada52d678c1d9da893227f27df2c5835349387477ac41151dbf4c 386 docs/RELEASE_NOTES_0.4.5.md
|
||||||
11a932e2c401c53d117175aa312b6d20508918b12192d37c5084bd54a5ea3a72 957 docs/RELEASE_NOTES_0.5.1.md
|
dcf07ac5b9ef7f08ef3c16631a9af7196c4e7589559eeb3512adfc8b354628aa 1111 docs/RELEASE_NOTES_0.5.0.md
|
||||||
d7d007e4c2807698db07b2ebe1cb48c36bd162bf4daad77c9d299096c9654d5a 721 docs/RELEASE_NOTES_0.5.2.md
|
1d89630a53d0d598b4fbf245be46773cef79eff58b3bdca2b79ae9975957464b 973 docs/RELEASE_NOTES_0.5.1.md
|
||||||
3e77df12a7ff4b545069933410bf14fe8891f39915182df25112c722cf4e243d 1030 docs/RELEASE_NOTES_0.5.3.md
|
2a4268b28bb0ae3dea0b647d1ddada6406f7cccab12844e93d2306e5d5a76c81 732 docs/RELEASE_NOTES_0.5.2.md
|
||||||
61f6cbc1c3f263fa96b5c6a70a26baa7cd577d37ac633455eed45d9b63169a35 710 docs/RELEASE_NOTES_0.5.4.md
|
319c39f7499e96513031e419501a0b01a4379b06e2b172d0e7d85876509bda9c 1050 docs/RELEASE_NOTES_0.5.3.md
|
||||||
|
aa00a9f187987419aedefa2c8667f664b4ad0123b3e7e205288d73b5b4f0b4e1 720 docs/RELEASE_NOTES_0.5.4.md
|
||||||
1ecca96cf8a6f01d7ead37d5a6b678549c2561bfd84011b6149f718a25971661 4936 docs/RELEASE_NOTES_0.6.0.md
|
1ecca96cf8a6f01d7ead37d5a6b678549c2561bfd84011b6149f718a25971661 4936 docs/RELEASE_NOTES_0.6.0.md
|
||||||
23150c58e6416d48c2ed6e378fff99179ed810b766ed50b70d4d829c6774b8ef 685 docs/RELEASE_NOTES_0.6.1.md
|
23150c58e6416d48c2ed6e378fff99179ed810b766ed50b70d4d829c6774b8ef 685 docs/RELEASE_NOTES_0.6.1.md
|
||||||
f3d04f2d3419a7a010d5399cdd9351ff85ab2b3fdf8023977e559b0a5f8bcdc3 2571 docs/RELEASE_NOTES_0.7.0.md
|
d4e43b10b64e1c04a0e444ed39bdfcd05869cf5a5d8db5caa8583578ed2c3e9a 2618 docs/RELEASE_NOTES_0.7.0.md
|
||||||
d7bdc61d9b617ad5acf0b2d468eda547fd7509d4af08f33d2661393f25bdcb5a 576 docs/RELEASE_NOTES_0.8.0.md
|
9afcf47ae2feea72e04cabc08e2a5c058891c04e4a99a7f014d6e9b791d52f3d 586 docs/RELEASE_NOTES_0.8.0.md
|
||||||
1e056bfcf2105843402f4b14c63480240cc55456a4a63e229b3fdbaf3156b803 754 docs/RELEASE_NOTES_0.8.1.md
|
674fc8b6c656bd2bfba583388d50e02d0a5c38db4c8396f78d217f4a8b58759c 767 docs/RELEASE_NOTES_0.8.1.md
|
||||||
7f1d7c8bc895d309dad2f8ab444d6d2ba3e68c8daa240fecd2abdd9d8a56ba20 729 docs/RELEASE_NOTES_0.8.2.md
|
65885a64005125a24e9d25b70f01dab6d97cdfc8ce017ea0850e913164a5b07b 740 docs/RELEASE_NOTES_0.8.2.md
|
||||||
c2802fa5dbff392c846b82b55e84a8bfb8e1625546fd1eba39f7129318bece96 654 docs/RELEASE_NOTES_0.8.3.md
|
0f7b3078069a9d7616690fc9aae89fcfa3916eb9b952b24b39ab2ff7bedb6879 667 docs/RELEASE_NOTES_0.8.3.md
|
||||||
8c13279987672314332f648889f52338bcdcb243249f9e1c20fb09d85d7808f5 505 docs/RELEASE_NOTES_0.8.4.md
|
9cb2b202fff4de466cc0bcf1945dcfacbda698a0306e293bd97c1a16ab6b9180 515 docs/RELEASE_NOTES_0.8.4.md
|
||||||
b516db97a0353babc810c24a87a971d30d72a8021d809e6b833ff7ae0458f442 538 docs/RELEASE_NOTES_0.8.5.md
|
82059b894fee48bf9726e9e65c335e221f0c0ccc03a0d27720e918633fbc6421 549 docs/RELEASE_NOTES_0.8.5.md
|
||||||
838d196f3fbbfeee8df375a0502107f56b6df28babca30aa09ef1c7aa5196d09 738 docs/RELEASE_NOTES_0.8.6.md
|
a4997e09ff6b3ce5a1754ece03ab45fb9da8bfaa61e5c3d970be7aa953f13b99 752 docs/RELEASE_NOTES_0.8.6.md
|
||||||
ef049adcfa204908e6dc3a059124b39ba0e2739cc54e38945ce73a57049df0d8 1185 docs/RELEASE_NOTES_0.8.7.md
|
f28b4e027a6417ada385070eff7436bdbc147f80229c65b1306cf8402f622675 1207 docs/RELEASE_NOTES_0.8.7.md
|
||||||
7eedb25e1aae3b06a04bb9b2f4843bd6af614418737e600b4bdc9161edabd76a 632 docs/RELEASE_NOTES_0.8.8.md
|
6b4c9bafcf50917129c64aba13491fb263116ef1a7e9393ed2b951671cecab9c 645 docs/RELEASE_NOTES_0.8.8.md
|
||||||
35dcfda990946480d6d55bd2d2e6360c336260bcd05cdb51d92e07a4e8d76945 1046 docs/RELEASE_NOTES_0.8.9.md
|
3a007e5d2081d33769f217f44de3eb4b5b720b564d646a8655910956bfc16f6a 1066 docs/RELEASE_NOTES_0.8.9.md
|
||||||
29f7b11fef1e4960ef874f643b2206ca73a310b0b75402bcd3764a01e59db2e0 3114 docs/RELEASE_NOTES_0.9.0.md
|
4e650b94caecc137735a7b27f8a17a907dfe3a5b9a3f9c7541dd6912fc1092d1 3144 docs/RELEASE_NOTES_0.9.0.md
|
||||||
ed40e08bac8792f95970bc05e49bce3cc9e288a08d11565a1bd156d787360a3b 720 docs/RELEASE_NOTES_0.9.1.md
|
318e665005a8246e49ed74678c09374f03148c96949f8cdce5dfac773f616959 730 docs/RELEASE_NOTES_0.9.1.md
|
||||||
01bf2cc72593b10010b667ae017b9eb62f4658a9711bbf24c81f5f95d93fe8c8 827 docs/RELEASE_NOTES_0.9.2.md
|
6ec7ddf1290c63bdb1da3dd1f64381f0c92db7d560460f3264ed8f1f23a15f61 837 docs/RELEASE_NOTES_0.9.2.md
|
||||||
25169225d73d22b9d884ab3b5c1625f03fd44e53c7a7a4c4067775e80482c9f8 2182 docs/RELEASE_NOTES_0.9.3.md
|
1b9f884aeaa030388b2a55b50daaa3dcc525b6771ba50b84908cb25a5437c58b 2207 docs/RELEASE_NOTES_0.9.3.md
|
||||||
720506842e0aeb30c9fc635f86a52a5545556f092e678cf37f08436243244c3d 933 docs/RELEASE_NOTES_0.9.4.md
|
bc3fa8731534e0b4f792ee2159bf7cd7d81bbbbe214caf269c5e6fc93f49152c 940 docs/RELEASE_NOTES_0.9.4.md
|
||||||
dd90c81a375f97dfb7fa8f7808db03b19d7e7dafe3818a93537397f57eaae829 2109 docs/RELEASE_NOTES_0.9.5.md
|
9c0256fc09525dc63650c1d1cb3afce8a2742a2e033a471595e5fb734bab40b8 2120 docs/RELEASE_NOTES_0.9.5.md
|
||||||
1bf75f25d704dab0c6bc56c639d259f34523f0fb46718dd5a8419a59911ad2c3 2242 docs/RELEASING.md
|
96272da7be735148e8971717f198eea2819aac915105af1533573156aa9d6b57 2298 docs/RELEASING.md
|
||||||
ac76cb50fabde6a00f28d7e9eccd3ef1129a40665eabdc90d78690a38d424652 4195 docs/ROADMAP.md
|
0e44c88c3a1bbb6899864132f55b02770e5ec53cd380eb4319648e25b774e8e0 4301 docs/ROADMAP.md
|
||||||
1ccde232c060395d7aedce27e89a7647b77afe28ab71de0a5a3efeded57369d3 140415 docs/screenshots/deploy-confirmation.png
|
1ccde232c060395d7aedce27e89a7647b77afe28ab71de0a5a3efeded57369d3 140415 docs/screenshots/deploy-confirmation.png
|
||||||
b39506254ffa2c73c389fb4795b3a745368bbeb7d8514cc47a636316d6d9a6aa 107166 docs/screenshots/deployment-run.png
|
b39506254ffa2c73c389fb4795b3a745368bbeb7d8514cc47a636316d6d9a6aa 107166 docs/screenshots/deployment-run.png
|
||||||
070e6700bdae8c628c907ba181bbf0dde0bbbbb4208f7a875503f933ff1b882e 118819 docs/screenshots/deployment-success.png
|
070e6700bdae8c628c907ba181bbf0dde0bbbbb4208f7a875503f933ff1b882e 118819 docs/screenshots/deployment-success.png
|
||||||
@@ -92,33 +93,33 @@ ed69b8beb948a2cf9a6deb6c82368e2bb44ffe8d8990a900dc878b0938d1084f 95937
|
|||||||
3868ab978de2a7945761c53a9a718aecd54dc791605d07660bcd5cad62a33ea8 103569 docs/screenshots/git-validator.png
|
3868ab978de2a7945761c53a9a718aecd54dc791605d07660bcd5cad62a33ea8 103569 docs/screenshots/git-validator.png
|
||||||
007681714895ac062c980db1dda806ac17d4f01019ce9c46491a108d17c2dbda 85338 docs/screenshots/overview.png
|
007681714895ac062c980db1dda806ac17d4f01019ce9c46491a108d17c2dbda 85338 docs/screenshots/overview.png
|
||||||
1f78414b00ec100af2ec9bf5c9a3e400b6c9bf6dca6fcc317fd951789acc4536 112852 docs/screenshots/repository-workspace.png
|
1f78414b00ec100af2ec9bf5c9a3e400b6c9bf6dca6fcc317fd951789acc4536 112852 docs/screenshots/repository-workspace.png
|
||||||
5cb9ee0e33a06db1796a740f12b0c41b917c68c1ae7cdb0070936a99c61c2c64 6036 docs/SECURITY.md
|
11a7bafaa63c7746a938a247b9315e6f54c083ef219504c88d3658cc1b86e98c 6173 docs/SECURITY.md
|
||||||
32a34ec13a284d3f9ceebbc107b25a844e3db096f8cafa4e43951fc2050c9a03 13552 docs/SETUP_GUIDE.md
|
32a34ec13a284d3f9ceebbc107b25a844e3db096f8cafa4e43951fc2050c9a03 13552 docs/SETUP_GUIDE.md
|
||||||
2fd71e9bcaeb4cb10c3fa2496b7e52fedf70c5b7f871cd587e22dc060c399079 4421 docs/SSH_UNRAID_DEPLOYMENT.md
|
080438fd3e5cb17a46baee6f0aa51fc95ca4ba37c55905bdf60fb7cd44fd1ba5 4494 docs/SSH_UNRAID_DEPLOYMENT.md
|
||||||
b6a178215dab054006aae4944b8ffcbe7f6100691c30f08e221e3a2dbff4cd42 2147 docs/STATUS_ENDPOINT.md
|
b1c3f399bddfc488060a88b58043a3faaa2ced67237ad21391efaf6af66cddb1 2206 docs/STATUS_ENDPOINT.md
|
||||||
0adfeabb98168a7fc0b02bae8d4af436d3c59459012fb05b2216e02265190128 3139 docs/STITCH_REVIEW.md
|
baa7b621b95a9ad6ca44d7b1ec0bc80f400068e93716a525470b5121f380cb19 3238 docs/STITCH_REVIEW.md
|
||||||
4983414a980075e6faae687b0d71c8e57bfe53fcb4cadb8b979b8abca636fe95 6654 docs/TEST_MATRIX.md
|
3610e0981257c5dd2455859902b20e7aa4568c3c93a1dfa6475be6032b564cf2 6703 docs/TEST_MATRIX.md
|
||||||
3c34d42088b18e37d18afc848f91fbe5b74134ca74dd53df1e9eb30753fae750 4433 docs/UPDATING.md
|
85c74adb8c7d4356b6f696013d911ba9041b8d8c4b8900dcb4b491115ba1fbc0 4512 docs/UPDATING.md
|
||||||
73f094a2f0db3de053e515feb2771cd5a4f3aa4178f2c5f37be01ca65ff1c938 2705 eslint.config.js
|
af13cb6d12f31904875cd5bf242a64bd92e15e81fe432fd423802db0f2040394 2772 eslint.config.js
|
||||||
c230b931abf2293d2d44b7a69b94c35f1142c093cc46b88739a0de5cbd6d1896 1532 examples/gitea-actions/deploy.yml
|
a24c5ce4c7147d286ef26258cb64a9f96a54c6d901e7dd5f925e48779df9053d 1583 examples/gitea-actions/deploy.yml
|
||||||
5d2577d4f9f635a12dcc8795879c079b9e66630bb3d96e21510ef7ee13ebef05 3319 examples/gitea-actions/forgeflow-approved-deploy.yml
|
5d2577d4f9f635a12dcc8795879c079b9e66630bb3d96e21510ef7ee13ebef05 3319 examples/gitea-actions/forgeflow-approved-deploy.yml
|
||||||
4c792cc9fd57ed36da291300c252a6ef75b08a249cf6f2561e23c4c22522138a 1477 examples/gitea-actions/rollback.yml
|
aa016403cc795880e29d933b60b52192bc73ad8e1d1eb20a93cbe11b4808b3cf 1527 examples/gitea-actions/rollback.yml
|
||||||
4a84041fcf2d7f36d1807e2c19d6cab816f9635112756a675f32cd24d9757fbb 9661 examples/server/forgeflow-deploy
|
4a84041fcf2d7f36d1807e2c19d6cab816f9635112756a675f32cd24d9757fbb 9661 examples/server/forgeflow-deploy
|
||||||
4fe3eee5c2d8705964c24b8c4dd909883a05e7d6eb85629c84b0d64473e0a92b 258 examples/server/forgeflow-runner.sudoers
|
13f5b67c8896d9ae3437bae0c9542be9084347b28ee84b59ab1a608263828cba 262 examples/server/forgeflow-runner.sudoers
|
||||||
0423fe2cc7f43fe793986a3f62a395668897cdf07348756aa7742a8cd40ac51c 569 examples/server/forgeflow-targets.conf
|
9e3dd8267eccebfc02583519ae2ef56b81e781b386d1b92b497d5cfa061be4a7 578 examples/server/forgeflow-targets.conf
|
||||||
106538d4a14a5a7b13419f9520c582b19809e8fafe2cb8c7dce2bc3e600dd10a 397 examples/server/nginx-forgeflow-status.conf
|
afb0480c781c800bf20834d91e36d60dcce520ab90c91c687745abe96bf87e3a 405 examples/server/nginx-forgeflow-status.conf
|
||||||
a0de3fe4e09b6f246e1513bccc170334e60f63f98c24377192b4335cbf16dff4 593 examples/server/status-example.json
|
a0de3fe4e09b6f246e1513bccc170334e60f63f98c24377192b4335cbf16dff4 593 examples/server/status-example.json
|
||||||
4a561ead5ba7cdfaf4efce91842a4308c5f2a77980205879d83835efb8a579db 1067 LICENSE
|
2033fd1ba7aeb8d2c6377d970516c4b7b82762dfc35efafb4be5a15e298c5e6b 1088 LICENSE
|
||||||
e2daa28bbc01c68c3702add6ea8259dff5920b22f6fdc3c9193ed78a153f2e9e 14708 main.cjs
|
b3d22a6d3222a02144c0ce147a93fa2ebd77c14b1b260503f338284cf9d9d107 15178 main.cjs
|
||||||
91a984a89dd57a084b9a2331763cacdb061582fb590f13df379d92c1a77a2ee1 352 OVERLAY-INSTRUCTIONS.md
|
91a984a89dd57a084b9a2331763cacdb061582fb590f13df379d92c1a77a2ee1 352 OVERLAY-INSTRUCTIONS.md
|
||||||
63d403ada205000a0dfb158ec57cde1a4f58572d790589428ab5b00a99b32cbe 184860 package-lock.json
|
1caed6bb0843d7164abcc7280f97427aea6f9cc2424ff159be03fb02f689ac86 184860 package-lock.json
|
||||||
ae06416348c2039eb4cafbf287c99342e04176bbbbb718646f160ff29b6af42f 6464 package.json
|
93f2bdaf830eebe78e9f6381c201a798ed80cd7c9a78f788c5cf4904d3e53762 6547 package.json
|
||||||
1237df9ddcbb5ac7dc4316f18c34ff4a7030e3e0d56216ade6dd07369e5e2a04 1353 playwright.config.mjs
|
c36f7f245023e31abe058ece7cc1d6899b83a6cd2c8e42c67fa396fb1085fc12 1395 playwright.config.mjs
|
||||||
7b0d173d0cf5a7f8db807580492bade379dba174a271013747f9f28a3793f55e 12409 preload.cjs
|
3020fb7661321b468a2d4532cb43ef50ec6a38cf973db453ec0c662f823c1da6 12571 preload.cjs
|
||||||
abe5dd6fd68f2970cd19ef134094907c67219061d8fe9a1a08324c78de4ad437 484 PUBLISH-AND-ENABLE-UPDATE.cmd
|
fc4a0cd199e4a6b3a8ed745261b770d8202d774bb1234cb9e074997b8a10b072 499 PUBLISH-AND-ENABLE-UPDATE.cmd
|
||||||
6d0858d6654c3c3dc7083ebbd234c88324afcebaecd7b772719440a8afbc2e4e 10736 Publish-ForgeFlow-Release.ps1
|
17d6dd3174c9cbe15073031f82ed760c472bb4543c8fc77cf0bc9f15c136e863 10917 Publish-ForgeFlow-Release.ps1
|
||||||
33f3c4795705ab77c6e6603c88a32c123b3a286bc77e8e472b76970485699338 4386 Publish-Missing-Binary-Release.ps1
|
bf882b8a3ba55c489a76393f65e0f3cc43a74282e8ef04bc31bdf6548495e590 4502 Publish-Missing-Binary-Release.ps1
|
||||||
5d9f13f34c9a9cca77968e472f1829147e51d3795779fa3f766b04cdd54fc698 11437 README.md
|
a3a6296c4ddcbfd22f01bc9f5a6fdd4a7eec66f3057cded8430a81eb28f956f9 5493 README.md
|
||||||
0f1bf0696ca6a3de7c222a935953156cdd1bb0aa27f2215b8000901c4db2be31 17255 reports/architecture-audit.json
|
0f1bf0696ca6a3de7c222a935953156cdd1bb0aa27f2215b8000901c4db2be31 17255 reports/architecture-audit.json
|
||||||
6c50c58f464e2f93fb7255a59d6cbb76354755f63c6f1d4ff14a9a88c8c54574 1758 reports/architecture-audit.md
|
6c50c58f464e2f93fb7255a59d6cbb76354755f63c6f1d4ff14a9a88c8c54574 1758 reports/architecture-audit.md
|
||||||
509c7bcff5280349bd9f45ed6151f70372bad7010a9ea582c13e2ccab91fe0cd 6272 scripts/acceptance.mjs
|
509c7bcff5280349bd9f45ed6151f70372bad7010a9ea582c13e2ccab91fe0cd 6272 scripts/acceptance.mjs
|
||||||
@@ -129,60 +130,60 @@ abe5dd6fd68f2970cd19ef134094907c67219061d8fe9a1a08324c78de4ad437 484
|
|||||||
6d46dd6826069d842f20f9f22a99042257db936cdea0bee8d294d2d7ea290126 3893 scripts/doctor.mjs
|
6d46dd6826069d842f20f9f22a99042257db936cdea0bee8d294d2d7ea290126 3893 scripts/doctor.mjs
|
||||||
7b483476ddd909b085335cb78c9b0ffe71939c50011b5fbfcfdef6a340fa7ce8 2032 scripts/generate-source-manifest.mjs
|
7b483476ddd909b085335cb78c9b0ffe71939c50011b5fbfcfdef6a340fa7ce8 2032 scripts/generate-source-manifest.mjs
|
||||||
842436680521311594e798848b050ae4e488d0595f0de57315f6ec081c049fb9 1266 scripts/prune-dist.mjs
|
842436680521311594e798848b050ae4e488d0595f0de57315f6ec081c049fb9 1266 scripts/prune-dist.mjs
|
||||||
19417a26a5af967b0f057fede45d1811a6d8ad65a0ed49ad4f5865f598457168 9358 scripts/publish-binary-release.cjs
|
bcd934f9c085b073dbccdb6fe55c042dc365d12ae7e48afcad11379d9cd32e3d 9399 scripts/publish-binary-release.cjs
|
||||||
558ff442988f1396c174c7161ff5bd3ef0b2f43cfc31459ec7c3967faa146bc3 1694 scripts/serve-demo.mjs
|
558ff442988f1396c174c7161ff5bd3ef0b2f43cfc31459ec7c3967faa146bc3 1694 scripts/serve-demo.mjs
|
||||||
288c4b93f6006c0b32cdf90555bdc0d1d3b61d24a8763fcc30f1e6425ce1684d 1713 scripts/setup-update-signing-key.mjs
|
288c4b93f6006c0b32cdf90555bdc0d1d3b61d24a8763fcc30f1e6425ce1684d 1713 scripts/setup-update-signing-key.mjs
|
||||||
431d3d7eabf7e2ea2d5cbb96fb0ddc13f26d85afebcb9692f3e30242197cbd8d 2607 scripts/sign-release-manifest.mjs
|
431d3d7eabf7e2ea2d5cbb96fb0ddc13f26d85afebcb9692f3e30242197cbd8d 2607 scripts/sign-release-manifest.mjs
|
||||||
c76507857292c5713e1c699cf02e24b80265da39af2cecd148034bdb874adbb6 5246 scripts/test-authenticode-chain.ps1
|
c76507857292c5713e1c699cf02e24b80265da39af2cecd148034bdb874adbb6 5246 scripts/test-authenticode-chain.ps1
|
||||||
4393f7dc5f417e6d601a68238f4e26791799a3634acec228fe4d79deaee85eb5 3109 scripts/validate-installed-connections.cjs
|
4393f7dc5f417e6d601a68238f4e26791799a3634acec228fe4d79deaee85eb5 3109 scripts/validate-installed-connections.cjs
|
||||||
e6127e1e62f39c70ddb1abf72f4d7e7b8e3f19ff1f219e1a3660353c2e0cdfac 2411 scripts/verify-release-signatures.mjs
|
e6127e1e62f39c70ddb1abf72f4d7e7b8e3f19ff1f219e1a3660353c2e0cdfac 2411 scripts/verify-release-signatures.mjs
|
||||||
2187f4a6e5f162b428f123960c8121f671218e1164327c1b4f21bf45a4477d01 22686 scripts/verify.mjs
|
3e15aadddf71962d938d5331dd32495dc4c3de1f5f235506bec8c2fb42aef5dd 23313 scripts/verify.mjs
|
||||||
c2c9e4ba251d93a530a52b2d0079787680261c314083bb99d2356fc177719613 2434 scripts/write-release-checksums.mjs
|
c2c9e4ba251d93a530a52b2d0079787680261c314083bb99d2356fc177719613 2434 scripts/write-release-checksums.mjs
|
||||||
c8780510ff6e77a16e9c4a88c3c981a0d9d1a4dff8eafd16afdeefbb4b03aac9 1064 SECURITY.md
|
247af21a5d7b42943ac5f6d297366f5e042a15a62c0c616872b9dadc7e47aa0f 1072 SECURITY.md
|
||||||
619515f524cb89960370ffcbd3fafd3c0e178b95f69c5868b1dd44777f23ec1e 2081 setup-windows.ps1
|
2785092555fad70fe679d1d15c8bee735705676c737a1ffcfc022d8d01999902 2128 setup-windows.ps1
|
||||||
dd613d04b366f2cd071a1685a414016a5fb008082ed1b4cb8b24b79c100f640a 2412 src/main/audit-service.cjs
|
fd5c733f9faebd26f5fb14f38bef99b03cc71452bb8ede7d184c8eef0c0bdf78 2469 src/main/audit-service.cjs
|
||||||
e3af59fafa497d032541979bea5fe2b98187b1ced619c567d15ae79ee0904c1f 34629 src/main/config-store.cjs
|
8f5b5f7cb197f7e0619f3ca14f89760222155bdfc9e4eae81b5182354c87c82b 35714 src/main/config-store.cjs
|
||||||
2fb04b1494b39f5d7c0720fa5fd298cd46fa85dc1b696d77657592347fcf1819 2731 src/main/configuration-backup.cjs
|
9223757fcbf46fab6e4dbd60333bed78b771c25f3fe4824cf80850a46ba43b8d 2793 src/main/configuration-backup.cjs
|
||||||
86e9fc2eda66b4b563f6c4bbb87d3e8514340d484fb503b73137e63b6b05c3c9 14597 src/main/deploy-key-lifecycle-service.cjs
|
1c74a88f5ee97063915eccccce854c7d6433f38800ff99fda732a092c649bd16 14788 src/main/deploy-key-lifecycle-service.cjs
|
||||||
7cbfe51973d6607203cb197652ed7f296a3f6b6b644df876957117866a47d802 2159 src/main/deployment-identity.cjs
|
b18f5cddbcd3eb1448ae227bddca7bd2d0866c3e309d852fb0ce45f0815eac3d 2194 src/main/deployment-identity.cjs
|
||||||
ce30ddac403d1adf21176e5df21b0cc3db435305d2628f51f1486eacf20df6f2 23708 src/main/deployment-service.cjs
|
a0284c366693b42d373794e55eec83bf5f6c500b95091b2796a283c1e69fdcdc 24135 src/main/deployment-service.cjs
|
||||||
cc2dad2fdac386d41c37b1a8657ae2b3b4084fd8f35a97f8600c082c8d017552 16475 src/main/diagnostics-service.cjs
|
774a6f4370e75bf086e04e7b4b7961463d97d798c2512525458dbaaa5c008140 16860 src/main/diagnostics-service.cjs
|
||||||
7f452dc2c0e6f3a00eecf6cb1c2be75906ac40445ef3e104341c0c67208aab2e 2397 src/main/external-tools-service.cjs
|
5d70b96d045820891d3a33f2fc5d54b0d4730bdcf82cc0ab32149b4d3328eb64 2448 src/main/external-tools-service.cjs
|
||||||
76fdc5576dcd6fdb88921009d4a923854650bd5efe5b837cd7438eba0dc733c8 48002 src/main/git-service.cjs
|
76fdc5576dcd6fdb88921009d4a923854650bd5efe5b837cd7438eba0dc733c8 48002 src/main/git-service.cjs
|
||||||
e28fc1ca2fd4c0116148f5005d793feddf04c36ef711d2d348560394d209a613 7253 src/main/git-validator-policy.cjs
|
871553beef7613d30493a9af9fdcac4d3305c0d89ae96cff8050f310d4865ff0 7340 src/main/git-validator-policy.cjs
|
||||||
3a101b63ad3761c26350c2ac0793279a0b27672b91a5b1d8dc75bc44d92f0b52 27128 src/main/git-validator-service.cjs
|
e4384b175d2ebff809581861a8b7a950c2bf2780118f3610ca5f9ec673fbb617 27727 src/main/git-validator-service.cjs
|
||||||
3cc53e24e023aa0d8bf36c35ce9672ca98e6c74066512c8b59ab42274e838c22 21307 src/main/gitea-service.cjs
|
0eecfff92532523990bf4a4bf2fdd6f9f1150d9c453706cdadf003954c90a162 21930 src/main/gitea-service.cjs
|
||||||
2ad3b2e647377f687ad987fe248a142ad399ecac98e4b49965aa7efc6093e5fa 6914 src/main/inventory-classifier.cjs
|
2246cd52935cc4b5546a1412f1aa2e33be99da4891be588da95644cc6d1ee8f0 6997 src/main/inventory-classifier.cjs
|
||||||
dafdb09133d2b6ec2161a3f0b09354551e54fc606c8107976fca37405643be91 3404 src/main/inventory-review-service.cjs
|
180f142fcdf41c7c458bbf541a0c2c6e337d99555591593732bc22272b36c43c 3435 src/main/inventory-review-service.cjs
|
||||||
98b332589f86a4874a8adddc38e7844a4ddbe9360d38f9f77b2e95d58d748016 25720 src/main/ipc.cjs
|
d618f9cd1625e291d1f48cad665b38cd5ef322214a1d293ab8c28dd1162d688e 26441 src/main/ipc.cjs
|
||||||
26efebb4c147ed560966e7e60e64a013b3476327b3bbdb4e4439949142fa7846 2250 src/main/ipc/channel.cjs
|
619e89f4489115f60d7cf858e3dac6c6b3e562ca7439e2398e66ca90fadb46d1 2327 src/main/ipc/channel.cjs
|
||||||
748cddf497b4c204e5e6fa1bd049991a086fdfb38afe342e6b3617c85a111478 12467 src/main/ipc/deployment-handlers.cjs
|
a2fb14037189bdad1f2913a713d04f8316d5ee60942dd0982f026cff9aa3ac8c 12751 src/main/ipc/deployment-handlers.cjs
|
||||||
dc9b5971c9fefe8c374aa31916f5513601ce86003fd48b1d0e51330a909ae3a5 3442 src/main/ipc/operations-handlers.cjs
|
c38777b4fe0711a404003765ec4f4032f353d4c01622fa17752b96f5f41ca458 3542 src/main/ipc/operations-handlers.cjs
|
||||||
8072252821b1245d121eac534a18eeb64f0d7d18429e272e21a6e90b010005b9 17272 src/main/ipc/repository-handlers.cjs
|
64c6dffcb232c547976a5ed8c98db4b5225eee10bdb650c8aaaace8eb3b67792 17722 src/main/ipc/repository-handlers.cjs
|
||||||
fc7156aabacb3e85a4f220c490f94e9836e07fa5350a1d9e64f84f835ef51024 4961 src/main/log-redaction.cjs
|
0ae045dab3165a05a518e9a0aca4aba972de3da3be301f219512c7d198e59008 5062 src/main/log-redaction.cjs
|
||||||
958595a99fb242c127f475f3d8622bdba4c07b2d658703f69fe3992227a9107e 12909 src/main/preflight-service.cjs
|
f819385c391b24dfb173d0b9befe82edcc1fdd26492a6fab7b168d03462a4daa 13117 src/main/preflight-service.cjs
|
||||||
720c4a0c554f46386d87c3ab6607d1fbcae66e50b69483c7dbba169d5128c851 680 src/main/process-error-policy.cjs
|
31e449c00daf48639fdf3effddee52e5fc5f8ee4dc27c57cfe9212e6418535f5 706 src/main/process-error-policy.cjs
|
||||||
3096b4181566cb93a27e56e248c92105d4f4df5aee39d73c6c7d8ae8c2231bc0 1570 src/main/process-runner.cjs
|
3096b4181566cb93a27e56e248c92105d4f4df5aee39d73c6c7d8ae8c2231bc0 1570 src/main/process-runner.cjs
|
||||||
e64f7257d478955c675a133b3735b6afe138a69d2ad090898061e56f557c43e5 9926 src/main/production-acceptance-harness.cjs
|
bc9fbb70cc5cc51cbf9115c610fadcb61e83316a69ae3862bbc2f013353c1e4b 10075 src/main/production-acceptance-harness.cjs
|
||||||
27bd6621c731545ec46d8914e9408c89928a8ce563b40eb4bcd8a516662a54d1 8716 src/main/repository-monitor.cjs
|
538ec017ee855b6585f1fb4efb88d828500b75545fccaacf66160a3d76d8a63e 8945 src/main/repository-monitor.cjs
|
||||||
6393583911263575c6e2a19d9baab6e638cce90252c386b0a5144f2fb6f81f15 12154 src/main/repository-service.cjs
|
a17983bf15aa0daa96bdc692e136386b3cae79b878e76694f19eab9e8aea2ace 12457 src/main/repository-service.cjs
|
||||||
52b6d88ed1f5c904a13cdde92e5f96d1e2b5971ceef49862152197353cdc6490 27928 src/main/server-inventory.cjs
|
a80440baafc3655dca2c6b5a5726e80368ac686015c7c184c5cc0353e807376c 28505 src/main/server-inventory.cjs
|
||||||
793003566823e1d5c02283f583888ecc07e44477525620579b3d858f488b3c08 22347 src/main/ssh-service.cjs
|
b344669439fbc6ccadf77277119efb10f200fccf2c7ea417e2aae83456acae4d 22859 src/main/ssh-service.cjs
|
||||||
19538a3c40ea3489bbaee9a23af36a5e99962af6bb3d04259f05ece6588cbeb2 25901 src/main/unraid-access-methods.cjs
|
79e96d402d8e7fddef722ebb9e528ac4a031d0286a994c0a2d3b8f21904ba0d7 26362 src/main/unraid-access-methods.cjs
|
||||||
5621e35323e4f81fb14a05670f81579ec1e66bea3a55fa6457ece0f807421424 9801 src/main/unraid-deploy-key-host.cjs
|
ee87b750d89f8df9ea4d8d7edb852b4681b3f826263bc8360d06a1e1f80f82e6 9880 src/main/unraid-deploy-key-host.cjs
|
||||||
6d9910dace52625f88e066a8485af2663c3735ff15e9ce9031441ce742710a21 30793 src/main/unraid-deployment-methods.cjs
|
518c3f9d017923407b9ceffb5132caf99cae2a3d5a103d21b303207893d38067 31375 src/main/unraid-deployment-methods.cjs
|
||||||
673b1692e7c2b5197545df98750b5d048bddf44206263e25be4f17d9bf900e2c 17208 src/main/unraid-deployment-service.cjs
|
b6cd92952b7fb2cd6f03301f78c9c6bfa962d1f0ddd56cc3931c7688acc538ad 17732 src/main/unraid-deployment-service.cjs
|
||||||
bb4a99c3526fcf4db4fbae88a058e8598fd10a87990e7d502bfdc765328bdaa1 42766 src/main/unraid-inventory-methods.cjs
|
d2d76767c05bbd604e8e557e1ba06ceba12305096fa73c8a9edbe439f2eb8fc2 43475 src/main/unraid-inventory-methods.cjs
|
||||||
2c0cf07921ca7ee5a9085ced44498c2e6798e5cc1e8a5ecf704c3cecabe39a25 27607 src/main/unraid-preflight-methods.cjs
|
aa2b8681d72dc9c232ef9436854da9967ebef35d6a71c66ff6f9a566ad031c06 28229 src/main/unraid-preflight-methods.cjs
|
||||||
d45220176aed72d692f9ae5534f9d40bcc359a2d08e025e74a3b3b505b8b9ed4 16559 src/main/unraid-runtime-methods.cjs
|
78fdb88c0ab376233c114b116559af26c47d83fced47c7a0a0b7248a0ecff8e2 16946 src/main/unraid-runtime-methods.cjs
|
||||||
4c5cf01922e1feb36a31b50af22e973d8aee3fecccd406e449690604111898ac 11608 src/main/unraid-state-methods.cjs
|
a3d3c0327f9120ca956735bf4e63a61e0b48e5b120a2b9fbe7b47d8bcf69b286 11901 src/main/unraid-state-methods.cjs
|
||||||
29b8c5eca83b0e89c7d0716945b5316aac43947b5387e89562d9a024ebc4663c 27204 src/main/update-service.cjs
|
0bac9bb0e30b7ed9b7c37fb4453a7a8d612a66b49caadc9546e0799c09774d98 28795 src/main/update-service.cjs
|
||||||
b5c304531bec358d059189a27cd9db8fa20cefb7f817e5eb0287001f7353f6a7 985 src/renderer/actions/command.js
|
856119ff96dd343f5460eb830a586684c1dda7468ddaec858d38d960614f1a42 1007 src/renderer/actions/command.js
|
||||||
d0bf607dd1de9d55f2947d0adf0997cd3ca5c269d10a5362cc1d8bc4d1a2a8ae 6706 src/renderer/actions/deployment-operation.js
|
6ea98804892017a27450047c6fc5a6193cd98b6f56ded9880eb02c06393683a1 6889 src/renderer/actions/deployment-operation.js
|
||||||
0db283b1a458ae0b31538940b1ddc931ffdb53bd04ceb7fd8903813f9200d071 17978 src/renderer/actions/deployment-profile.js
|
d58d8fed4128d6c512fc1c6cac42dfdf5878380cabab9f068abc371d29036d27 18385 src/renderer/actions/deployment-profile.js
|
||||||
48bed91dd2a85bb51ee7307f7acc3b79c881ce8cf63b22ba79d5d079b265eb4b 7785 src/renderer/actions/inventory.js
|
3efbd97d65ecd74aa30c7ab51c7ddd3da71c3b9f6296597a51e3d921cf7930e1 7970 src/renderer/actions/inventory.js
|
||||||
9e8adf1ba89ffc61a7b595f813c784688bdf50daa259204d74b2cdaa81650895 15493 src/renderer/actions/recovery.js
|
9e8adf1ba89ffc61a7b595f813c784688bdf50daa259204d74b2cdaa81650895 15493 src/renderer/actions/recovery.js
|
||||||
2414a0d29a0380d343b9b0e58ba1909e7a7eeb46357fd45ddbb3ad411d119f78 16280 src/renderer/actions/setup-and-settings.js
|
6c26c3604344230df8ee13129526a271b76db48809d02d4e9ff1e3db08dbe2ee 16720 src/renderer/actions/setup-and-settings.js
|
||||||
058722de35ba33bfcfd29d355a75e1513a2be80c572773472cf9816dd13f894a 20148 src/renderer/actions/shell.js
|
058722de35ba33bfcfd29d355a75e1513a2be80c572773472cf9816dd13f894a 20148 src/renderer/actions/shell.js
|
||||||
0d48993bc26ae28bdab5fbfa8d9be4ef896efdb9a5c34094087721e4274593b4 27566 src/renderer/app.js
|
0d48993bc26ae28bdab5fbfa8d9be4ef896efdb9a5c34094087721e4274593b4 27566 src/renderer/app.js
|
||||||
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 src/renderer/assets/itworx-mark.png
|
16efd2fca83004f781eae40ae0f706a004ce0bddf338dd087b8adf7eb10c1d84 85704 src/renderer/assets/itworx-mark.png
|
||||||
@@ -190,70 +191,72 @@ d0bf607dd1de9d55f2947d0adf0997cd3ca5c269d10a5362cc1d8bc4d1a2a8ae 6706
|
|||||||
094c1b71cc2482a9db250ac175f45f3de68f53277dfbde371a03e61923d00988 75240 src/renderer/assets/itworx-wordmark-light.png
|
094c1b71cc2482a9db250ac175f45f3de68f53277dfbde371a03e61923d00988 75240 src/renderer/assets/itworx-wordmark-light.png
|
||||||
813b8cdeecac43794166f3db9d3c5d2c441e0292f9ab7bd465ba136d6201e95d 82476 src/renderer/assets/itworx-wordmark.png
|
813b8cdeecac43794166f3db9d3c5d2c441e0292f9ab7bd465ba136d6201e95d 82476 src/renderer/assets/itworx-wordmark.png
|
||||||
f826ab1f2f35882c59995497219fcfd500e46a94dac0906ee47fb732e8023fb4 55633 src/renderer/dialogs.js
|
f826ab1f2f35882c59995497219fcfd500e46a94dac0906ee47fb732e8023fb4 55633 src/renderer/dialogs.js
|
||||||
dede1f21a06c73a2c2a462a869d27530d85f99baff202a2eb509c57436ad6aec 2732 src/renderer/diff-view.js
|
196ee9c174de6afaae524d6e1bc7c5fccc8165e653adec44b12627f3be2af42b 2772 src/renderer/diff-view.js
|
||||||
b7698de13b872aa80d27b0a4d977c12ca2303b2246f05e6af4223db9b727e525 7433 src/renderer/events.js
|
b7698de13b872aa80d27b0a4d977c12ca2303b2246f05e6af4223db9b727e525 7433 src/renderer/events.js
|
||||||
c4a71213d412166093f7bd8254b847de4d8beb58c1aaa356a0cdc8d728080326 1524 src/renderer/index.html
|
4eae9d462d04b6c65399a13ed679fccd6fc0469b2da97ff6861b932486319621 1561 src/renderer/index.html
|
||||||
06180d9656dd254edfb6949c397f8e313954fc560ddcb22b3a35fce3c3e35655 21350 src/renderer/mock-bridge.js
|
aee36aa371a9c6ba2b85a1b269a5d43b0a5edb05c1d89aa5b7748b656ee92c2b 21951 src/renderer/mock-bridge.js
|
||||||
870024aff376826a92c9cf7452689cc1ecc5d9034f055bea56734f3f7fcea5e5 28703 src/renderer/mock-deployment-bridge.js
|
9853a4b17e000efa81d76596d7fbdc7277103811302061fae7a0caf6085a8a0d 29408 src/renderer/mock-deployment-bridge.js
|
||||||
ee33d1a77ab7152cb4f3dfbb611011f755a69ba1afb1016a28c997fcfdca97d6 25810 src/renderer/mock-repository-bridge.js
|
4a314d7a0fa00d84c8431ade6d598084ac0fd6ded518f035029f230f6f03a1c1 25815 src/renderer/mock-repository-bridge.js
|
||||||
94fa265c2fe9ca8d644f0ce9b620b6f85d9b25dca5802c4e9195b66dcbe80120 6522 src/renderer/operations.js
|
297dcb573c61f553c82fb5fad9dae82bc6f1fe958b2b026a49f1dee0fc7600c0 6733 src/renderer/operations.js
|
||||||
9299c83e43eef194bac2946c43b2ffda6309ccbdcc5b9ce1775e668ae7f172ef 92319 src/renderer/styles.css
|
9299c83e43eef194bac2946c43b2ffda6309ccbdcc5b9ce1775e668ae7f172ef 92319 src/renderer/styles.css
|
||||||
9ee96e6267d923448a45eb0a02d5352286400f2d7b4a006ba681b6806f2e1424 113808 src/renderer/views.js
|
a4ff14882d0fe3f1f467eb9e263ad1a984b065d1534e14376c42d755a7a0f689 113894 src/renderer/views.js
|
||||||
e9e72c072a5c5d04f59cd6763de0cfbf736c2a5ffa2f722143f3bad2bdbc630b 1411 src/shared/clone-target.cjs
|
e9e72c072a5c5d04f59cd6763de0cfbf736c2a5ffa2f722143f3bad2bdbc630b 1411 src/shared/clone-target.cjs
|
||||||
5d425d5c2f939d0f6beebee7ebb0c77146cb7e318535ba7286ec7081a4dc2269 2497 src/shared/deployment-policy.cjs
|
7d194738a75be91182d558dfdd22fdc66e8ca9713dcc9622605b9c49c59eaa90 2541 src/shared/deployment-policy.cjs
|
||||||
029e600229714d033c28e2dcb77817aa8269847001782ae0012960e83ffd183f 3057 src/shared/git-status.cjs
|
bc13c4d35579e2c64dfd8c0245c48ca4f8bfc8bd1a80210821f4366b799764a9 3150 src/shared/git-status.cjs
|
||||||
2778ebcbdf60fdc1cb0749f15565e0e1bd66f3a0d31eb70ae7942a7511a3de75 1295 src/shared/repository-match.cjs
|
59b4c20d3cfdecdeb8f2126b5e525f2ae99b26a53a3914a2a7a63bbc1cf5643d 1099 src/shared/release-policy.cjs
|
||||||
|
98bf82663ecd159c92eb3d4a9d05996797103e620cd9017f9ccee5c614c35ff7 1334 src/shared/repository-match.cjs
|
||||||
c7e120ea53c5ef3c01b8cce71afe913f34bb461bb73aa3ade24656e09f99f338 1152 src/shared/semver.cjs
|
c7e120ea53c5ef3c01b8cce71afe913f34bb461bb73aa3ade24656e09f99f338 1152 src/shared/semver.cjs
|
||||||
a31b275114a2ac376f3f8c69f4328286219767d22024ddeb01070550ad62109f 3189 src/shared/shell-verification.cjs
|
a31b275114a2ac376f3f8c69f4328286219767d22024ddeb01070550ad62109f 3189 src/shared/shell-verification.cjs
|
||||||
2daa98fd421598bfe5fc9757c9b6f4d82c31d1bfece15829928473581d5d2639 1210 src/shared/tool-invocation.cjs
|
f6acb9c9a3cb9ca771d9cfd133babd8132445322644fc23082313dd1ac1ab2b2 1252 src/shared/tool-invocation.cjs
|
||||||
ee73fdf9c591c029243385cb2d2085c3005c7b08c5b9e1b89102201f0ab30759 5702 src/shared/validation.cjs
|
f2bd787532454b7f52a19d4161458ced05b3496ceb37ef3db4db84a67a99393e 5832 src/shared/validation.cjs
|
||||||
13b731c38863b1007b0312fd9d89562401b7cce875c952f52429bde74f77a8af 3096 src/shared/zip-writer.cjs
|
cfa9298d5ab390f5f1ad8988c73a157e8bee1c2854afc58c4fa0941cfe1da871 3187 src/shared/zip-writer.cjs
|
||||||
f8853dce6fdf360d5df2fbe2b6df3e5687630c807fee5ba8436679b34ec737ea 2436 START_HERE.md
|
39260d5268764844f744278f99a1ce934cc3bf3e2f5eb56687122bb75482255f 2496 START_HERE.md
|
||||||
058aeaa5d9bfe377c7e322f213c7871ecc4151b5d08ef790992f4ee28d857658 743 START-FORGEFLOW-OVERLAY.ps1
|
058aeaa5d9bfe377c7e322f213c7871ecc4151b5d08ef790992f4ee28d857658 743 START-FORGEFLOW-OVERLAY.ps1
|
||||||
f5b0ea887fcdeadec78c1ad49b0ec7979723562f5c0b730703acb77a37281ee0 1009 tests/acceptance.test.mjs
|
1efc658df6e29f5db5aefd3c515115357d33fe7d920e37e1a99a118251babeee 1020 tests/acceptance.test.mjs
|
||||||
2f2b21754dccd8b734d6c7bd4fdd655df79c7739a1de140e562520c8234aa7a2 2854 tests/approved-deployment-evidence.test.mjs
|
2f2b21754dccd8b734d6c7bd4fdd655df79c7739a1de140e562520c8234aa7a2 2854 tests/approved-deployment-evidence.test.mjs
|
||||||
720ff5b549a3dd70854eb1bac3589c77a2019a61148be8e41e112196c8821ee3 1079 tests/approved-deployment-one-shot.test.mjs
|
720ff5b549a3dd70854eb1bac3589c77a2019a61148be8e41e112196c8821ee3 1079 tests/approved-deployment-one-shot.test.mjs
|
||||||
a4e5947204ff6878e601e32477bc85b53cd0153baf95a161c8935b6e5466c257 1155 tests/audit-service.test.mjs
|
17ce23545d113267f414173ccd8cbbcc8e6eaeac4a831c5d53f37d7946775905 1180 tests/audit-service.test.mjs
|
||||||
6e119cda76b2ee36b93623d98f41371798227f9b3f7c20fbef035a7d7a50cc95 19402 tests/browser/forgeflow.spec.mjs
|
6e119cda76b2ee36b93623d98f41371798227f9b3f7c20fbef035a7d7a50cc95 19402 tests/browser/forgeflow.spec.mjs
|
||||||
1728c0a7abd92f4d7d9e68df32e4a6b00730555f23795e9b36416795d9d127af 5978 tests/clone-target.test.mjs
|
1728c0a7abd92f4d7d9e68df32e4a6b00730555f23795e9b36416795d9d127af 5978 tests/clone-target.test.mjs
|
||||||
8aa8789a984769b377f719abca42a428fffc4f89b3997d57184a8073d24121e2 18325 tests/config-store.test.mjs
|
1d85b0bfdd47d3f645904d4db85e1699addd6a0f02ed6c71fa4fe4b568fd21ae 19513 tests/config-store.test.mjs
|
||||||
f1463326aee79842d265687ae628189ce54e92544600f2bd14073780287cfb14 2502 tests/configuration-backup.test.mjs
|
afc181d00bd191f3e8d8074c9fa382d29ddcc1d4bf9186f8f6395b93e3725f14 2547 tests/configuration-backup.test.mjs
|
||||||
144c8e217a334cd69f502938d944e0f2dac61703d5df47e287b9ed542918c779 8129 tests/dependency-wiring.test.mjs
|
a460d1ebb731c89ef0be9a4679604c73d0151e44e24da94788c132c3b298bff5 8294 tests/dependency-wiring.test.mjs
|
||||||
aad5948ea374d1e56e777005c73639654c96a90364dd398c949052cf5ae343a2 11130 tests/deploy-key-host.test.mjs
|
aad5948ea374d1e56e777005c73639654c96a90364dd398c949052cf5ae343a2 11130 tests/deploy-key-host.test.mjs
|
||||||
b7e009fed4171d6dd6b4c3154ba1d3f7198e98f5b79b298687841fc8169447cd 9354 tests/deploy-key-lifecycle.test.mjs
|
636c62293a576e62fbeae3adca3ad6e1345e68da0db555dd3bfde3a532066bc3 9493 tests/deploy-key-lifecycle.test.mjs
|
||||||
49bf9cf9842e7899015013675208f83a95402065a082320927a677ee4bab0766 24875 tests/deployment-operations.test.mjs
|
49bf9cf9842e7899015013675208f83a95402065a082320927a677ee4bab0766 24875 tests/deployment-operations.test.mjs
|
||||||
1dc6477bd07de78be189e6e8195ec339eb9d75820c4dbd5b073b8520ee21f6b5 1938 tests/deployment-policy.test.mjs
|
41589cf470702c7a5af966a096be7ec469c8cfb6133957ec4f4d7ecba395a152 1967 tests/deployment-policy.test.mjs
|
||||||
bf4576901e32662d832687a2761852aa1b2cffe256de5044f18c6637c189463b 9780 tests/deployment-status.test.mjs
|
e8724cf72de796b763acff18aa01ea95a4ff5b2de211246ec89fb8c67d079e54 9823 tests/deployment-status.test.mjs
|
||||||
9a97e79618393d9f9818cb958bd038e0095489331fba0b29de313aaaaa1ce30d 4064 tests/diagnostics.test.mjs
|
34d824c1bee1b1756c279c938ece61a5b7e4b0fd796ba4c0a594d131e2f1ef0e 4142 tests/diagnostics.test.mjs
|
||||||
b63eb5bcd89c34629386c745e80c2f83f0709ebce62459b583e665d0a99654c6 938 tests/external-tools.test.mjs
|
9f862a67d93edf4adc7c8b04040f9ea56394b56445a70cfd658b8def6cd336d1 952 tests/external-tools.test.mjs
|
||||||
26e94450c6ab1dd0d5149d6812e66814a719f80d6f95fcb3a9dee7a3d7f46293 20559 tests/git-integration.test.mjs
|
26e94450c6ab1dd0d5149d6812e66814a719f80d6f95fcb3a9dee7a3d7f46293 20559 tests/git-integration.test.mjs
|
||||||
5ea94c6b241a02060d531fad94e449eecd3772eed2137581d4e2babfb09e56db 1239 tests/git-status.test.mjs
|
cd294dcaf050d639472cb1f9c1a48484fbc74271e527bf9d8153b00e903e2101 1273 tests/git-status.test.mjs
|
||||||
61e0b8cad926acd22b5b17e4044f7edcbe96b6977cbbe2b6fbe123406626fc89 4283 tests/git-validator-policy.test.mjs
|
8ac410d7173bfc3e4b967138d2d6343fb1796b2cbde4fb538b8a38b801377d24 4350 tests/git-validator-policy.test.mjs
|
||||||
2b31459f14a5e36e30cf84c1054f634f4dba8676d29adeb9c2a8e18179f56fa0 6097 tests/git-validator.test.mjs
|
8950162b8ab1b644bca230cf9871f64e530e6d612a9d89a942c3e49b686fce30 6239 tests/git-validator.test.mjs
|
||||||
681ab7bcd02c4dd98d1d8d2092a3521c489d941131e7ffe5903971b940046474 2403 tests/git-workflows.test.mjs
|
eeb7ebc5b2deb882590f8abca3ce76a6e1f9ee26e75d37d3ed1d753790785973 2449 tests/git-workflows.test.mjs
|
||||||
d633c59bd910008223c834c6d7f3e5666c685a0881944263ede2d42cc69d3151 18710 tests/gitea-actions.test.mjs
|
4e9391976989b302d626fb820738d49622e3bc20ad46441685015addc180009f 19052 tests/gitea-actions.test.mjs
|
||||||
fcc9a063882840dd89d74c2785284c8f2f6a9e5acec482b6d89ed8de62efdb85 9635 tests/inventory-classifier.test.mjs
|
f7d9e24146ac87a180fd60e0a2514c971eaaac9001014f7d63336281aae7403e 9759 tests/inventory-classifier.test.mjs
|
||||||
62b90c21c15b841af30d26ccb0b9e88d25674fa7dbff9dc231dd8a1dddc3d657 2025 tests/ipc-contract.test.mjs
|
b73b49e177e0436988d4d38132ea008a35290187ee33deb289b12b621923caa2 2074 tests/ipc-contract.test.mjs
|
||||||
5c66b01ab11585aab6d923a9811ec76eef34e918f1a7f37227edd3f4337c932f 2981 tests/log-redaction.test.mjs
|
c6614369c43ba42531fea6d365187d1a579018374b2fd5c317b4cbc902d1cf61 3067 tests/log-redaction.test.mjs
|
||||||
96432a97d313f331694900bf0a2c21e38c20eac96d59147977aeed9055a9e3ad 2287 tests/partial-staging.test.mjs
|
107d5eb14d1733709f05e817ef303b4c592470b6f9fd057fa804c9a1e2a10a7c 2331 tests/partial-staging.test.mjs
|
||||||
1b6c920e18a248f78acaed6187197c88ec8d911b62d5e2a9f8ad57b91ae80499 11827 tests/preflight.test.mjs
|
d5433897838ea42146cfc15e140e55d1f254e72186a0a5f50d2d43d50490f33c 12004 tests/preflight.test.mjs
|
||||||
7f2751ea2621f76b5427f442e931344d13e97faa7b6ef3151949bbd6a03097cf 1205 tests/process-error-policy.test.mjs
|
070f2857e70d2b36310f2636582ef0eec49f398b3f009bd3742c6c9e676ba508 1231 tests/process-error-policy.test.mjs
|
||||||
0cb884cf62c1cb02cf59a81662be055bcb5339d176de85e2a3eeb8e8573e11b3 6435 tests/production-acceptance.test.mjs
|
0abe5fcea0ab8769188f2131e99301979d4f4983cf9924266291bc716c9e5d33 6564 tests/production-acceptance.test.mjs
|
||||||
|
6f26ae12a39a4711cf699f1a68e8f673e1e53e2cc34f5a6f362a66ae15ba9d1a 1229 tests/release-policy.test.mjs
|
||||||
11fd2029593c0f4e5c36f1ce8572734f8ac9afead5abca7f5b619c5814b40a6c 12602 tests/renderer-workflow.test.mjs
|
11fd2029593c0f4e5c36f1ce8572734f8ac9afead5abca7f5b619c5814b40a6c 12602 tests/renderer-workflow.test.mjs
|
||||||
2b4956fa4df4624a04117737e57ba74020564330ff71303b5746d8ccc881e880 854 tests/repository-matching.test.mjs
|
af43f29c5c1dd78095a3a471b904964c613f1eb567310ffcfc432cbbc9f8f986 872 tests/repository-matching.test.mjs
|
||||||
4defa3c5f21db7fefbd79397c96b6c231a4330df60b54c0fea7e91412e336fd3 6237 tests/repository-monitor.test.mjs
|
4defa3c5f21db7fefbd79397c96b6c231a4330df60b54c0fea7e91412e336fd3 6237 tests/repository-monitor.test.mjs
|
||||||
5476f3ba90bc096d4172900d9b54ada7c12da521f8627913d87794eade3cee23 13494 tests/repository-service.test.mjs
|
d4d2f9e2f6e7c672273a4126966f739c10d584d9e976d8630fe4b988c02dbb47 13784 tests/repository-service.test.mjs
|
||||||
5fea04e668344508fb4e16da9bb6fe8733e2b83d1c227acb3421e51da26b2ffa 3636 tests/security-validation.test.mjs
|
1e4807cbcb19f4dd7787dc1779e3b60a6462989b13bdf482b38a489a756b0b5e 3639 tests/security-validation.test.mjs
|
||||||
bab853feb0e22aa25af17989baaa632c01efa636533ea67407fecfdd973c7024 627 tests/semver.test.mjs
|
bab853feb0e22aa25af17989baaa632c01efa636533ea67407fecfdd973c7024 627 tests/semver.test.mjs
|
||||||
12cb3b240bdd0922566323c0014838ca067ad10d9d4009943165ae2c4e93bc6f 11786 tests/server-inventory-branches.test.mjs
|
76ec40ba206203c89ee41212b75f53159a86ef94af9c64ff3fa204b160cb37eb 11936 tests/server-inventory-branches.test.mjs
|
||||||
5df7f331cc1120a0914f5ddbf39d9a6b83bd5ada70a9953b3f6bd0701ba2485e 4394 tests/shell-verification.test.mjs
|
5df7f331cc1120a0914f5ddbf39d9a6b83bd5ada70a9953b3f6bd0701ba2485e 4394 tests/shell-verification.test.mjs
|
||||||
a39d30f47813dfb98c998811f3d76ebbb1544ecfd017a165d44f9afb80d7daf9 9090 tests/ssh-connection-pool.test.mjs
|
977fc36c38a3af16558fb2c3b2b38a9466aaf08b0e7234d4cab354dee181b4b0 9345 tests/ssh-connection-pool.test.mjs
|
||||||
7ee9166327ed227d2b7c6929692dea5c5d7a41c3e566596fa92d9ec4f42e8677 4085 tests/ssh-connection.test.mjs
|
0149be4165bd5379c8324813cfe536f1620a5c324bead43dd0f463e63bb84d08 4183 tests/ssh-connection.test.mjs
|
||||||
c9354e4bf3720c28cff21c15ff8b9474ba4a23b7f55389de4326f4dffde54d78 9510 tests/ssh-service.test.mjs
|
259f4952baea6e4631f1670c2dfc1cf2e2b4c4ec670a691be922a3784c294491 9667 tests/ssh-service.test.mjs
|
||||||
8a6a8477eb94b85ccef18cddd2640afb0d1eafa679c96bc7de20428d5d69e1be 1794 tests/tool-invocation.test.mjs
|
c61d8ef97ec7f63f3ba0f7bbda11ba1d1bfbe1a5fd85caab2bfec612ad393aa0 1843 tests/tool-invocation.test.mjs
|
||||||
3e4a1a6d6a744df9badcfece2cf8d09f8c34efb3c437cb08a6f2e6c9d428c0d4 59353 tests/unraid-deployment.test.mjs
|
8df71b18f53ac6fe4cb8dc11d526f66c4db374ef9f738a6d85bb5ee2de224515 60887 tests/unraid-deployment.test.mjs
|
||||||
05c0ef13fa2fa977174fdf8bdf76a7d606a049a43ad98901079cf5545d54d18d 31426 tests/update-service.test.mjs
|
c750272ba4616f868b3f5a8b516674342b06b4de7eb85aa4461a107da084b6d0 32655 tests/update-service.test.mjs
|
||||||
9cea5c1d5ba3e0972a0b5c7236cf1f7c5616373e0a39ea4a492ecebf70452e40 948 tests/validation.test.mjs
|
9ecd063698bba4c49f308617399d6ad9ca87946f9ed885412f5a71fb0ee424bd 970 tests/validation.test.mjs
|
||||||
7ef4d4b9f5f3e6979293b29d571ce0e39f83197f3cade2d999a9cea7bacdd84d 1781 tests/zip-writer.test.mjs
|
b9b5ebe3ef0d15f5d6d45d2e8bc49097b59633e7684e72a1f8fad084e6010746 1822 tests/zip-writer.test.mjs
|
||||||
8f36b542736f2933bad8b9464ad7fa37b68196009c81cf702ce3b677cd637dea 767 UPDATE_FROM_0.3.2.md
|
ebafe424ed9dd3d3558949bfcd523352565102da4221769187dcacf4777b4977 786 UPDATE_FROM_0.3.2.md
|
||||||
2ebde94f664d86f42aea9bb3112b70b272c6706f4d364cad2f5c6191d2873e98 1655 update-windows.ps1
|
c2ea145fd3dc55cc82ae2c975d48e3aee1061fd184ca2a688b498a91743a8a2c 1690 update-windows.ps1
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# ForgeFlow 0.10.16
|
||||||
|
|
||||||
|
## Signed releases from the public source repository
|
||||||
|
|
||||||
|
- Packaged updates follow the exact published release commit, so later documentation or source-only changes do not invalidate the signed executable.
|
||||||
|
- New installations check `Jens/ForgeFlow-Public` for Windows updates.
|
||||||
|
- Existing installations that still use the legacy `Jens/ForgeFlow` endpoint move to `ForgeFlow-Public` after installing this bridge release. An intentionally configured alternative update repository is preserved.
|
||||||
|
- A version change in the curated public source now starts the Windows quality, build, signing and release workflow. Source-only updates do not create another binary release.
|
||||||
|
- The publisher refuses to replace an already published version or attach assets built from a different commit. Release manifests continue to bind the executable checksums to the exact public source commit and the existing Ed25519 publisher key.
|
||||||
|
|
||||||
|
The legacy repository remains available for older installations until the bridge update has been verified in the field.
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "forgeflow",
|
"name": "forgeflow",
|
||||||
"version": "0.10.15",
|
"version": "0.10.16",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "forgeflow",
|
"name": "forgeflow",
|
||||||
"version": "0.10.15",
|
"version": "0.10.16",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ssh2": "1.17.0"
|
"ssh2": "1.17.0"
|
||||||
},
|
},
|
||||||
|
|||||||
+4
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "forgeflow",
|
"name": "forgeflow",
|
||||||
"version": "0.10.15",
|
"version": "0.10.16",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Desktop release cockpit for local Git, Gitea Actions and controlled exact-commit deployments.",
|
"description": "Desktop release cockpit for local Git, Gitea Actions and controlled exact-commit deployments.",
|
||||||
"main": "main.cjs",
|
"main": "main.cjs",
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
"dev": "electron . --dev",
|
"dev": "electron . --dev",
|
||||||
"demo": "node scripts/serve-demo.mjs",
|
"demo": "node scripts/serve-demo.mjs",
|
||||||
"test": "node --test tests/*.test.mjs",
|
"test": "node --test --test-concurrency=1 tests/*.test.mjs",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"coverage": "c8 --check-coverage --lines 85 --functions 85 --branches 68 --statements 85 node --test tests/*.test.mjs && npm run coverage:modules",
|
"coverage": "c8 --check-coverage --lines 85 --functions 85 --branches 68 --statements 85 node --test --test-concurrency=1 tests/*.test.mjs && npm run coverage:modules",
|
||||||
"coverage:modules": "c8 report --check-coverage --per-file --include src/** --statements 60 --lines 60 --functions 50 --branches 36 --reporter=text-summary",
|
"coverage:modules": "c8 report --check-coverage --per-file --include src/** --statements 60 --lines 60 --functions 50 --branches 36 --reporter=text-summary",
|
||||||
"verify": "node scripts/verify.mjs",
|
"verify": "node scripts/verify.mjs",
|
||||||
"dist:win": "electron-builder --win nsis portable && node scripts/write-release-checksums.mjs && node scripts/sign-release-manifest.mjs && node scripts/verify-release-signatures.mjs && node scripts/prune-dist.mjs",
|
"dist:win": "electron-builder --win nsis portable && node scripts/write-release-checksums.mjs && node scripts/sign-release-manifest.mjs && node scripts/verify-release-signatures.mjs && node scripts/prune-dist.mjs",
|
||||||
@@ -124,6 +124,7 @@
|
|||||||
"docs/RELEASE_NOTES_0.10.13.md",
|
"docs/RELEASE_NOTES_0.10.13.md",
|
||||||
"docs/RELEASE_NOTES_0.10.14.md",
|
"docs/RELEASE_NOTES_0.10.14.md",
|
||||||
"docs/RELEASE_NOTES_0.10.15.md",
|
"docs/RELEASE_NOTES_0.10.15.md",
|
||||||
|
"docs/RELEASE_NOTES_0.10.16.md",
|
||||||
"docs/CURRENT_STATE.md",
|
"docs/CURRENT_STATE.md",
|
||||||
"docs/MUTATION_MODEL.md",
|
"docs/MUTATION_MODEL.md",
|
||||||
"docs/RELEASING.md",
|
"docs/RELEASING.md",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const path = require("node:path");
|
|||||||
const { execFileSync } = require("node:child_process");
|
const { execFileSync } = require("node:child_process");
|
||||||
const { app, safeStorage } = require("electron");
|
const { app, safeStorage } = require("electron");
|
||||||
const { normalizeBaseUrl } = require("../src/shared/validation.cjs");
|
const { normalizeBaseUrl } = require("../src/shared/validation.cjs");
|
||||||
|
const { existingReleaseState } = require("../src/shared/release-policy.cjs");
|
||||||
|
|
||||||
const root = path.resolve(__dirname, "..");
|
const root = path.resolve(__dirname, "..");
|
||||||
const configuredUserData =
|
const configuredUserData =
|
||||||
@@ -88,7 +89,7 @@ app.whenReady().then(async () => {
|
|||||||
"Release repository owner",
|
"Release repository owner",
|
||||||
);
|
);
|
||||||
const repo = safeRepositoryPart(
|
const repo = safeRepositoryPart(
|
||||||
process.env.FORGEFLOW_RELEASE_REPO || config.updates?.repo || "ForgeFlow",
|
process.env.FORGEFLOW_RELEASE_REPO || config.updates?.repo || "ForgeFlow-Public",
|
||||||
"Release repository name",
|
"Release repository name",
|
||||||
);
|
);
|
||||||
const branch = safeRepositoryPart(
|
const branch = safeRepositoryPart(
|
||||||
@@ -143,17 +144,10 @@ app.whenReady().then(async () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (release.draft !== true) {
|
if (existingReleaseState(release, version, commit) === "published") {
|
||||||
release = await api(
|
console.log(`PASS ForgeFlow ${version} is already published for ${commit.slice(0, 7)}`);
|
||||||
baseUrl,
|
app.exit(0);
|
||||||
token,
|
return;
|
||||||
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/releases/${release.id}`,
|
|
||||||
{
|
|
||||||
method: "PATCH",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ draft: true }),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
const binaries = [
|
const binaries = [
|
||||||
path.join(root, "dist", `ForgeFlow-Setup-${version}-win-x64.exe`),
|
path.join(root, "dist", `ForgeFlow-Setup-${version}-win-x64.exe`),
|
||||||
@@ -172,10 +166,6 @@ app.whenReady().then(async () => {
|
|||||||
const existing = (release.assets || []).find(
|
const existing = (release.assets || []).find(
|
||||||
(asset) => asset.name === name,
|
(asset) => asset.name === name,
|
||||||
);
|
);
|
||||||
if (existing && Number(existing.size) === bytes.length) {
|
|
||||||
console.log(`SKIP ${name} already published`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
await api(
|
await api(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
|||||||
+3
-2
@@ -97,6 +97,7 @@ const required = [
|
|||||||
"docs/RELEASE_NOTES_0.10.13.md",
|
"docs/RELEASE_NOTES_0.10.13.md",
|
||||||
"docs/RELEASE_NOTES_0.10.14.md",
|
"docs/RELEASE_NOTES_0.10.14.md",
|
||||||
"docs/RELEASE_NOTES_0.10.15.md",
|
"docs/RELEASE_NOTES_0.10.15.md",
|
||||||
|
"docs/RELEASE_NOTES_0.10.16.md",
|
||||||
"docs/UPDATING.md",
|
"docs/UPDATING.md",
|
||||||
"docs/DIAGNOSTICS.md",
|
"docs/DIAGNOSTICS.md",
|
||||||
"docs/DEPLOYMENT_SETUP.md",
|
"docs/DEPLOYMENT_SETUP.md",
|
||||||
@@ -136,9 +137,9 @@ for (const file of required) await access(path.join(root, file));
|
|||||||
const packageJson = JSON.parse(
|
const packageJson = JSON.parse(
|
||||||
await readFile(path.join(root, "package.json"), "utf8"),
|
await readFile(path.join(root, "package.json"), "utf8"),
|
||||||
);
|
);
|
||||||
if (packageJson.version !== "0.10.15")
|
if (packageJson.version !== "0.10.16")
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Expected package version 0.10.15, got ${packageJson.version}.`,
|
`Expected package version 0.10.16, got ${packageJson.version}.`,
|
||||||
);
|
);
|
||||||
const sourceManifest = await readFile(
|
const sourceManifest = await readFile(
|
||||||
path.join(root, "SOURCE_MANIFEST.txt"),
|
path.join(root, "SOURCE_MANIFEST.txt"),
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const DEFAULT_CONFIG = {
|
|||||||
favorites: [],
|
favorites: [],
|
||||||
updates: {
|
updates: {
|
||||||
owner: 'Jens',
|
owner: 'Jens',
|
||||||
repo: 'ForgeFlow',
|
repo: 'ForgeFlow-Public',
|
||||||
branch: 'main',
|
branch: 'main',
|
||||||
autoCheck: true,
|
autoCheck: true,
|
||||||
lastCheckedAt: null
|
lastCheckedAt: null
|
||||||
@@ -124,7 +124,15 @@ class ConfigStore {
|
|||||||
: {},
|
: {},
|
||||||
deploymentStates: source.deploymentStates && typeof source.deploymentStates === 'object' ? source.deploymentStates : {},
|
deploymentStates: source.deploymentStates && typeof source.deploymentStates === 'object' ? source.deploymentStates : {},
|
||||||
favorites: [...new Set(uniqueStrings(source.favorites).map((item) => item.toLowerCase()))],
|
favorites: [...new Set(uniqueStrings(source.favorites).map((item) => item.toLowerCase()))],
|
||||||
updates: { ...DEFAULT_CONFIG.updates, ...(source.updates || {}) },
|
updates: {
|
||||||
|
...DEFAULT_CONFIG.updates,
|
||||||
|
...(source.updates || {}),
|
||||||
|
// Move existing installations off the legacy endpoint while preserving
|
||||||
|
// a separately configured update repository.
|
||||||
|
...((source.updates?.owner ?? 'Jens') === 'Jens' && source.updates?.repo === 'ForgeFlow' && (source.updates?.branch ?? 'main') === 'main'
|
||||||
|
? { repo: 'ForgeFlow-Public' }
|
||||||
|
: {})
|
||||||
|
},
|
||||||
servers: Array.isArray(source.servers) ? source.servers.filter((item) => item && typeof item === 'object') : [],
|
servers: Array.isArray(source.servers) ? source.servers.filter((item) => item && typeof item === 'object') : [],
|
||||||
preferences: { ...DEFAULT_CONFIG.preferences, ...(source.preferences || {}) },
|
preferences: { ...DEFAULT_CONFIG.preferences, ...(source.preferences || {}) },
|
||||||
operations: Array.isArray(source.operations) ? source.operations.slice(0, 250).map((operation) => { const { runnerLog, ...safeOperation } = operation || {}; return safeOperation; }) : []
|
operations: Array.isArray(source.operations) ? source.operations.slice(0, 250).map((operation) => { const { runnerLog, ...safeOperation } = operation || {}; return safeOperation; }) : []
|
||||||
@@ -375,7 +383,7 @@ class ConfigStore {
|
|||||||
async setUpdatePreferences(updates) {
|
async setUpdatePreferences(updates) {
|
||||||
const next = { ...this.data.updates, ...(updates || {}) };
|
const next = { ...this.data.updates, ...(updates || {}) };
|
||||||
next.owner = String(next.owner || 'Jens').trim().slice(0, 100);
|
next.owner = String(next.owner || 'Jens').trim().slice(0, 100);
|
||||||
next.repo = String(next.repo || 'ForgeFlow').trim().slice(0, 100);
|
next.repo = String(next.repo || 'ForgeFlow-Public').trim().slice(0, 100);
|
||||||
next.branch = assertBranchName(next.branch || 'main');
|
next.branch = assertBranchName(next.branch || 'main');
|
||||||
next.autoCheck = next.autoCheck !== false;
|
next.autoCheck = next.autoCheck !== false;
|
||||||
this.data.updates = next;
|
this.data.updates = next;
|
||||||
|
|||||||
@@ -265,16 +265,28 @@ class UpdateService {
|
|||||||
"Update repository owner",
|
"Update repository owner",
|
||||||
);
|
);
|
||||||
const repo = safeRepositoryPart(
|
const repo = safeRepositoryPart(
|
||||||
settings.repo || "ForgeFlow",
|
settings.repo || "ForgeFlow-Public",
|
||||||
"Update repository name",
|
"Update repository name",
|
||||||
);
|
);
|
||||||
const branchName = String(settings.branch || "main").trim();
|
const branchName = String(settings.branch || "main").trim();
|
||||||
const branch = await this.gitea.getBranch(owner, repo, branchName);
|
let remoteSha;
|
||||||
const remoteSha =
|
let releaseTag = null;
|
||||||
branch?.commit?.id || branch?.commit?.sha || branch?.commit?.commit?.id;
|
if (this.appInfo.packaged) {
|
||||||
|
const release = await this.gitea.getLatestRelease(owner, repo);
|
||||||
|
if (!release || release.draft || release.prerelease) {
|
||||||
|
const error = new Error("The configured update repository has no published stable Windows release yet.");
|
||||||
|
error.code = "BINARY_RELEASE_NOT_FOUND";
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
remoteSha = release.target_commitish;
|
||||||
|
releaseTag = release.tag_name;
|
||||||
|
} else {
|
||||||
|
const branch = await this.gitea.getBranch(owner, repo, branchName);
|
||||||
|
remoteSha = branch?.commit?.id || branch?.commit?.sha || branch?.commit?.commit?.id;
|
||||||
|
}
|
||||||
if (!/^[0-9a-f]{40}$/i.test(String(remoteSha || "")))
|
if (!/^[0-9a-f]{40}$/i.test(String(remoteSha || "")))
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Gitea did not return a full commit SHA for the update branch.",
|
"Gitea did not return a full commit SHA for the update source.",
|
||||||
);
|
);
|
||||||
|
|
||||||
const file = await this.gitea.getRepositoryFile({
|
const file = await this.gitea.getRepositoryFile({
|
||||||
@@ -294,6 +306,9 @@ class UpdateService {
|
|||||||
"The configured update repository is not a ForgeFlow source repository.",
|
"The configured update repository is not a ForgeFlow source repository.",
|
||||||
);
|
);
|
||||||
const remoteVersion = String(manifest.version || "").trim();
|
const remoteVersion = String(manifest.version || "").trim();
|
||||||
|
if (releaseTag && releaseTag !== `v${remoteVersion}` && releaseTag !== remoteVersion) {
|
||||||
|
throw new Error("The published release tag does not match its source version.");
|
||||||
|
}
|
||||||
const currentVersion = String(this.appInfo.version || "").trim();
|
const currentVersion = String(this.appInfo.version || "").trim();
|
||||||
const available = isNewerVersion(remoteVersion, currentVersion);
|
const available = isNewerVersion(remoteVersion, currentVersion);
|
||||||
const result = {
|
const result = {
|
||||||
@@ -301,6 +316,7 @@ class UpdateService {
|
|||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
branch: branchName,
|
branch: branchName,
|
||||||
|
releaseTag,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
remoteVersion,
|
remoteVersion,
|
||||||
remoteSha,
|
remoteSha,
|
||||||
|
|||||||
@@ -162,7 +162,7 @@
|
|||||||
],
|
],
|
||||||
updates: {
|
updates: {
|
||||||
owner: "Jens",
|
owner: "Jens",
|
||||||
repo: "ForgeFlow",
|
repo: "ForgeFlow-Public",
|
||||||
branch: "main",
|
branch: "main",
|
||||||
autoCheck: true,
|
autoCheck: true,
|
||||||
lastCheckedAt: null,
|
lastCheckedAt: null,
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ function renderSettings() {
|
|||||||
const servers = state.servers || [];
|
const servers = state.servers || [];
|
||||||
return `<div class="settings-layout"><aside class="settings-nav"><button class="nav-button active">${icon("settings")}<span>General</span></button><button class="nav-button" data-action="check-updates">${icon("update")}<span>Updates</span></button><button class="nav-button" data-action="open-add-server">${icon("server")}<span>Servers</span></button><button class="nav-button" data-action="reset-app">${icon("trash")}<span>Reset setup</span></button></aside><div class="settings-content"><div class="page-header"><div><div class="eyebrow">Application</div><h1>Settings</h1><p>Connections, project discovery, secure SSH servers and application updates.</p></div></div>
|
return `<div class="settings-layout"><aside class="settings-nav"><button class="nav-button active">${icon("settings")}<span>General</span></button><button class="nav-button" data-action="check-updates">${icon("update")}<span>Updates</span></button><button class="nav-button" data-action="open-add-server">${icon("server")}<span>Servers</span></button><button class="nav-button" data-action="reset-app">${icon("trash")}<span>Reset setup</span></button></aside><div class="settings-content"><div class="page-header"><div><div class="eyebrow">Application</div><h1>Settings</h1><p>Connections, project discovery, secure SSH servers and application updates.</p></div></div>
|
||||||
<section class="settings-group"><h2>Gitea connection</h2><div class="form-grid"><div class="field full"><label for="settings-gitea-url">Instance URL</label><input id="settings-gitea-url" class="input" value="${attr(state.gitea.baseUrl)}" placeholder="https://gitea.example.com" /></div><div class="field full"><label for="settings-gitea-token">New access token</label><input id="settings-gitea-token" class="input" type="password" placeholder="Leave empty only when keeping the same server" /></div></div><div class="connection-card" style="margin-top:10px"><div><strong>${state.gitea.hasToken ? `Connected as ${escapeHtml(state.gitea.user?.login || "user")}` : "Not connected"}</strong><div class="queue-sub">${escapeHtml(state.gitea.baseUrl || "No Gitea instance configured")}</div></div><button class="button primary" data-action="save-gitea-settings">Validate & save</button></div></section>
|
<section class="settings-group"><h2>Gitea connection</h2><div class="form-grid"><div class="field full"><label for="settings-gitea-url">Instance URL</label><input id="settings-gitea-url" class="input" value="${attr(state.gitea.baseUrl)}" placeholder="https://gitea.example.com" /></div><div class="field full"><label for="settings-gitea-token">New access token</label><input id="settings-gitea-token" class="input" type="password" placeholder="Leave empty only when keeping the same server" /></div></div><div class="connection-card" style="margin-top:10px"><div><strong>${state.gitea.hasToken ? `Connected as ${escapeHtml(state.gitea.user?.login || "user")}` : "Not connected"}</strong><div class="queue-sub">${escapeHtml(state.gitea.baseUrl || "No Gitea instance configured")}</div></div><button class="button primary" data-action="save-gitea-settings">Validate & save</button></div></section>
|
||||||
<section class="settings-group"><div class="section-heading"><div><h2>ForgeFlow updates</h2><span class="meta">Signed packaged updates from ${escapeHtml(state.updates?.owner || "Jens")}/${escapeHtml(state.updates?.repo || "ForgeFlow")}</span></div><button class="button" data-action="check-updates" ${ui.updateChecking ? "disabled" : ""}>${icon("update")}${ui.updateChecking ? "Checking…" : "Check now"}</button></div><div class="form-grid"><div class="field"><label>Repository owner</label><input id="update-owner" class="input" value="${attr(state.updates?.owner || "Jens")}"/></div><div class="field"><label>Repository name</label><input id="update-repo" class="input" value="${attr(state.updates?.repo || "ForgeFlow")}"/></div><div class="field"><label>Release branch</label><input id="update-branch" class="input" value="${attr(state.updates?.branch || "main")}"/></div><div class="field"><label>Automatic startup check</label><select id="update-auto-check" class="select"><option value="true" ${state.updates?.autoCheck !== false ? "selected" : ""}>Enabled</option><option value="false" ${state.updates?.autoCheck === false ? "selected" : ""}>Disabled</option></select></div></div><div class="update-card ${update?.available ? "available" : ""}"><div>${icon(update?.available ? "download" : "check")}<span><strong>${update ? (update.available ? `ForgeFlow ${escapeHtml(update.remoteVersion)} is available${update.packaged ? "" : " in the source repository"}` : `ForgeFlow ${escapeHtml(update.currentVersion)} is up to date`) : `Current version ${escapeHtml(ui.boot.appVersion)}`}</strong><small>${update ? `Branch ${escapeHtml(update.branch)} · commit ${escapeHtml(update.shortSha)} · checked ${formatDate(update.checkedAt)}` : "No update check in this session."}</small></span></div><div class="stack horizontal compact">${update?.available && update.packaged && !update.downloaded ? `<button class="button primary" data-action="download-update">${icon("download")}Download signed update</button>` : ""}${update?.downloaded ? `<button class="button success" data-action="apply-update">${icon("update")}Apply & restart</button>` : ""}<button class="button" data-action="save-update-settings">Save update settings</button></div></div><div class="notice" style="margin-top:10px">${icon("shield")}${update && !update.packaged ? "Source checkouts must be updated with Git after reviewing the exact commit. Integrated source replacement remains disabled until source archives are publisher-signed." : "Packaged updates require an Ed25519 publisher signature that binds the exact commit, artifact name, size and SHA-256 digest."}</div></section>
|
<section class="settings-group"><div class="section-heading"><div><h2>ForgeFlow updates</h2><span class="meta">Signed packaged updates from ${escapeHtml(state.updates?.owner || "Jens")}/${escapeHtml(state.updates?.repo || "ForgeFlow-Public")}</span></div><button class="button" data-action="check-updates" ${ui.updateChecking ? "disabled" : ""}>${icon("update")}${ui.updateChecking ? "Checking…" : "Check now"}</button></div><div class="form-grid"><div class="field"><label>Repository owner</label><input id="update-owner" class="input" value="${attr(state.updates?.owner || "Jens")}"/></div><div class="field"><label>Repository name</label><input id="update-repo" class="input" value="${attr(state.updates?.repo || "ForgeFlow-Public")}"/></div><div class="field"><label>Release branch</label><input id="update-branch" class="input" value="${attr(state.updates?.branch || "main")}"/></div><div class="field"><label>Automatic startup check</label><select id="update-auto-check" class="select"><option value="true" ${state.updates?.autoCheck !== false ? "selected" : ""}>Enabled</option><option value="false" ${state.updates?.autoCheck === false ? "selected" : ""}>Disabled</option></select></div></div><div class="update-card ${update?.available ? "available" : ""}"><div>${icon(update?.available ? "download" : "check")}<span><strong>${update ? (update.available ? `ForgeFlow ${escapeHtml(update.remoteVersion)} is available${update.packaged ? "" : " in the source repository"}` : `ForgeFlow ${escapeHtml(update.currentVersion)} is up to date`) : `Current version ${escapeHtml(ui.boot.appVersion)}`}</strong><small>${update ? `${update.releaseTag ? `Release ${escapeHtml(update.releaseTag)}` : `Branch ${escapeHtml(update.branch)}`} · commit ${escapeHtml(update.shortSha)} · checked ${formatDate(update.checkedAt)}` : "No update check in this session."}</small></span></div><div class="stack horizontal compact">${update?.available && update.packaged && !update.downloaded ? `<button class="button primary" data-action="download-update">${icon("download")}Download signed update</button>` : ""}${update?.downloaded ? `<button class="button success" data-action="apply-update">${icon("update")}Apply & restart</button>` : ""}<button class="button" data-action="save-update-settings">Save update settings</button></div></div><div class="notice" style="margin-top:10px">${icon("shield")}${update && !update.packaged ? "Source checkouts must be updated with Git after reviewing the exact commit. Integrated source replacement remains disabled until source archives are publisher-signed." : "Packaged updates require an Ed25519 publisher signature that binds the exact commit, artifact name, size and SHA-256 digest."}</div></section>
|
||||||
<section class="settings-group"><div class="section-heading"><div><h2>SSH / Unraid servers</h2><span class="meta">Credentials are encrypted locally; a new host fingerprint is shown before authentication.</span></div><button class="button primary" data-action="open-add-server">${icon("plus")}Add server</button></div>${servers.length ? `<div class="server-list">${servers.map((server) => `<article class="server-card"><div class="server-card-main">${icon("server")}<div><strong>${escapeHtml(server.name)}</strong><span>${escapeHtml(server.username)}@${escapeHtml(server.host)}:${escapeHtml(server.port)} · ${escapeHtml(server.basePath)}</span><small>${server.hostFingerprint ? `Trusted ${escapeHtml(server.hostFingerprint)}` : "Host identity not trusted yet"}</small></div></div><div class="stack horizontal compact"><button class="button" data-action="test-server" data-server-id="${attr(server.id)}">${server.hostFingerprint ? "Test connection" : "Preview & trust fingerprint"}</button><button class="button" data-action="edit-server" data-server-id="${attr(server.id)}">Edit</button><button class="icon-button danger" data-action="delete-server" data-server-id="${attr(server.id)}" title="Delete server">${icon("trash")}</button></div></article>`).join("")}</div>` : '<div class="empty-state compact"><p>No SSH server configured. Add your Unraid server before creating an SSH deployment profile.</p></div>'}</section>
|
<section class="settings-group"><div class="section-heading"><div><h2>SSH / Unraid servers</h2><span class="meta">Credentials are encrypted locally; a new host fingerprint is shown before authentication.</span></div><button class="button primary" data-action="open-add-server">${icon("plus")}Add server</button></div>${servers.length ? `<div class="server-list">${servers.map((server) => `<article class="server-card"><div class="server-card-main">${icon("server")}<div><strong>${escapeHtml(server.name)}</strong><span>${escapeHtml(server.username)}@${escapeHtml(server.host)}:${escapeHtml(server.port)} · ${escapeHtml(server.basePath)}</span><small>${server.hostFingerprint ? `Trusted ${escapeHtml(server.hostFingerprint)}` : "Host identity not trusted yet"}</small></div></div><div class="stack horizontal compact"><button class="button" data-action="test-server" data-server-id="${attr(server.id)}">${server.hostFingerprint ? "Test connection" : "Preview & trust fingerprint"}</button><button class="button" data-action="edit-server" data-server-id="${attr(server.id)}">Edit</button><button class="icon-button danger" data-action="delete-server" data-server-id="${attr(server.id)}" title="Delete server">${icon("trash")}</button></div></article>`).join("")}</div>` : '<div class="empty-state compact"><p>No SSH server configured. Add your Unraid server before creating an SSH deployment profile.</p></div>'}</section>
|
||||||
<section class="settings-group"><div class="section-heading"><div><h2>Git remote maintenance</h2><span class="meta">Standardize linked repositories to the current Gitea SSH URLs.</span></div><button class="button" data-action="normalize-origins">${icon("link")}Normalize all origins</button></div><p>This replaces legacy aliases and renamed owners only after an explicit click. Local commits and files are not changed.</p></section>
|
<section class="settings-group"><div class="section-heading"><div><h2>Git remote maintenance</h2><span class="meta">Standardize linked repositories to the current Gitea SSH URLs.</span></div><button class="button" data-action="normalize-origins">${icon("link")}Normalize all origins</button></div><p>This replaces legacy aliases and renamed owners only after an explicit click. Local commits and files are not changed.</p></section>
|
||||||
<section class="settings-group"><h2>Project roots</h2><p>The first folder is the default clone destination. ForgeFlow automatically creates one subfolder per repository.</p><div class="stack">${state.workspaceRoots.map((root, index) => `<div class="root-row">${index === 0 ? '<span class="status-pill success">Default</span>' : ""}<input class="input" data-root-index="${index}" value="${attr(root)}" aria-label="Project root ${index + 1}"/><button class="icon-button" data-action="remove-root" data-index="${index}" title="Remove">${icon("trash")}</button></div>`).join("")}<button class="button" data-action="add-root">${icon("plus")}Add project root</button><button class="button primary" data-action="save-roots">Save folders & rescan</button></div></section>
|
<section class="settings-group"><h2>Project roots</h2><p>The first folder is the default clone destination. ForgeFlow automatically creates one subfolder per repository.</p><div class="stack">${state.workspaceRoots.map((root, index) => `<div class="root-row">${index === 0 ? '<span class="status-pill success">Default</span>' : ""}<input class="input" data-root-index="${index}" value="${attr(root)}" aria-label="Project root ${index + 1}"/><button class="icon-button" data-action="remove-root" data-index="${index}" title="Remove">${icon("trash")}</button></div>`).join("")}<button class="button" data-action="add-root">${icon("plus")}Add project root</button><button class="button primary" data-action="save-roots">Save folders & rescan</button></div></section>
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function windowsReleaseAssetNames(version) {
|
||||||
|
return [
|
||||||
|
...['Setup', 'Portable'].flatMap((kind) => {
|
||||||
|
const name = `ForgeFlow-${kind}-${version}-win-x64.exe`;
|
||||||
|
return [name, `${name}.sha256`];
|
||||||
|
}),
|
||||||
|
`ForgeFlow-${version}-provenance.json`,
|
||||||
|
`ForgeFlow-${version}-sbom.cdx.json`,
|
||||||
|
`ForgeFlow-${version}-release-manifest.json`,
|
||||||
|
`ForgeFlow-${version}-release-manifest.json.sig`
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function existingReleaseState(release, version, commit) {
|
||||||
|
if (release.target_commitish !== commit) {
|
||||||
|
throw new Error(`Release v${version} already targets ${release.target_commitish}; refusing assets from ${commit}. Bump the version for a new source commit.`);
|
||||||
|
}
|
||||||
|
if (release.draft) return 'draft';
|
||||||
|
const names = new Set((release.assets || []).map((asset) => asset.name));
|
||||||
|
const missing = windowsReleaseAssetNames(version).filter((name) => !names.has(name));
|
||||||
|
if (missing.length) throw new Error(`Published release v${version} is missing: ${missing.join(', ')}.`);
|
||||||
|
return 'published';
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { windowsReleaseAssetNames, existingReleaseState };
|
||||||
@@ -48,6 +48,20 @@ test("load creates missing config and recovers malformed JSON", async (t) => {
|
|||||||
assert.ok((await readdir(directory)).some((name) => name.includes(".corrupt-")));
|
assert.ok((await readdir(directory)).some((name) => name.includes(".corrupt-")));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("legacy ForgeFlow update endpoint migrates to the signed public releases", async (t) => {
|
||||||
|
const { directory, store } = await storeFixture(t);
|
||||||
|
assert.equal(store.data.updates.repo, "ForgeFlow-Public");
|
||||||
|
await writeFile(store.filePath, JSON.stringify({
|
||||||
|
updates: { owner: "Jens", repo: "ForgeFlow", branch: "main", autoCheck: true },
|
||||||
|
}), "utf8");
|
||||||
|
await store.load();
|
||||||
|
assert.equal(store.data.updates.repo, "ForgeFlow-Public");
|
||||||
|
assert.equal(JSON.parse(await readFile(store.filePath, "utf8")).updates.repo, "ForgeFlow-Public");
|
||||||
|
assert.equal(store.migrate({ updates: { owner: "Team", repo: "ForgeFlow" } }).updates.repo, "ForgeFlow");
|
||||||
|
assert.equal(store.migrate({ updates: { owner: "Jens", repo: "CustomUpdates" } }).updates.repo, "CustomUpdates");
|
||||||
|
assert.equal(store.migrate({ updates: { owner: "Jens", repo: "ForgeFlow", branch: "custom" } }).updates.repo, "ForgeFlow");
|
||||||
|
});
|
||||||
|
|
||||||
test("server normalization rejects unsafe targets and preserves bounded scan configuration", async (t) => {
|
test("server normalization rejects unsafe targets and preserves bounded scan configuration", async (t) => {
|
||||||
const { store } = await storeFixture(t);
|
const { store } = await storeFixture(t);
|
||||||
assert.throws(() => store.normalizeServer({ host: "bad host", username: "root" }), /hostname/);
|
assert.throws(() => store.normalizeServer({ host: "bad host", username: "root" }), /hostname/);
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import releasePolicy from '../src/shared/release-policy.cjs';
|
||||||
|
|
||||||
|
const { windowsReleaseAssetNames, existingReleaseState } = releasePolicy;
|
||||||
|
const commit = 'a'.repeat(40);
|
||||||
|
const version = '0.10.16';
|
||||||
|
|
||||||
|
test('a draft for another commit cannot receive replacement release assets', () => {
|
||||||
|
assert.throws(() => existingReleaseState({ target_commitish: 'b'.repeat(40), draft: true }, version, commit), /Bump the version/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a matching draft can resume while a complete published release is immutable', () => {
|
||||||
|
assert.equal(existingReleaseState({ target_commitish: commit, draft: true }, version, commit), 'draft');
|
||||||
|
assert.equal(existingReleaseState({ target_commitish: commit, draft: false, assets: windowsReleaseAssetNames(version).map((name) => ({ name })) }, version, commit), 'published');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('a published release missing its signature cannot be treated as complete', () => {
|
||||||
|
const assets = windowsReleaseAssetNames(version).filter((name) => !name.endsWith('.sig')).map((name) => ({ name }));
|
||||||
|
assert.throws(() => existingReleaseState({ target_commitish: commit, draft: false, assets }, version, commit), /release-manifest.json.sig/);
|
||||||
|
});
|
||||||
@@ -118,6 +118,33 @@ test("update repository parts reject path injection", async () => {
|
|||||||
await rm(temp, { recursive: true, force: true });
|
await rm(temp, { recursive: true, force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("packaged updates pin the published release commit despite later source-only changes", async (t) => {
|
||||||
|
const temp = await mkdtemp(path.join(os.tmpdir(), "forgeflow-release-check-"));
|
||||||
|
t.after(() => rm(temp, { recursive: true, force: true }));
|
||||||
|
const releaseCommit = "b".repeat(40);
|
||||||
|
const service = new UpdateService({
|
||||||
|
store: { data: { updates: {} }, save: async () => {} },
|
||||||
|
gitea: {
|
||||||
|
async getLatestRelease(owner, repo) {
|
||||||
|
assert.equal(repo, "ForgeFlow-Public");
|
||||||
|
return { tag_name: "v0.10.16", target_commitish: releaseCommit, draft: false, prerelease: false };
|
||||||
|
},
|
||||||
|
async getBranch() { throw new Error("Packaged updates must not follow mutable main."); },
|
||||||
|
async getRepositoryFile(input) {
|
||||||
|
assert.equal(input.ref, releaseCommit);
|
||||||
|
return { decoded: JSON.stringify({ name: "forgeflow", version: "0.10.16" }) };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
appInfo: { version: "0.10.14", packaged: true },
|
||||||
|
sourcePath: temp,
|
||||||
|
userDataPath: temp,
|
||||||
|
});
|
||||||
|
const result = await service.check();
|
||||||
|
assert.equal(result.available, true);
|
||||||
|
assert.equal(result.remoteSha, releaseCommit);
|
||||||
|
assert.equal(result.releaseTag, "v0.10.16");
|
||||||
|
});
|
||||||
|
|
||||||
test("source updater refuses an unsigned archive before launching a helper", async () => {
|
test("source updater refuses an unsigned archive before launching a helper", async () => {
|
||||||
const temp = await mkdtemp(
|
const temp = await mkdtemp(
|
||||||
path.join(os.tmpdir(), "forgeflow-update-handshake-"),
|
path.join(os.tmpdir(), "forgeflow-update-handshake-"),
|
||||||
|
|||||||
Reference in new issue
Block a user