From fd63ff858de2cb5219039cf3a767c4606894597d Mon Sep 17 00:00:00 2001 From: scott45 Date: Wed, 15 Oct 2025 17:46:55 +0300 Subject: [PATCH 01/27] feat: initialize TODO API with Express --- package-lock.json | 865 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 13 + src/app.js | 20 ++ 3 files changed, 898 insertions(+) create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/app.js diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ee4f885 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,865 @@ +{ + "name": "github-devops-javascript", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "github-devops-javascript", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "cors": "^2.8.5", + "express": "^5.1.0" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", + "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.7.0", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e1393e2 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "github-devops-todo", + "version": "1.0.0", + "main": "src/app.js", + "scripts": { + "start": "node src/app.js", + "test": "echo 'Add tests later' && exit 0" + }, + "dependencies": { + "express": "^4.18.2", + "cors": "^2.8.5" + } +} diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..3c65555 --- /dev/null +++ b/src/app.js @@ -0,0 +1,20 @@ +const express = require('express'); + const cors = require('cors'); + const app = express(); + app.use(cors()); + app.use(express.json()); + + let todos = []; // In-memory for demo + + app.get('/todos', (req, res) => res.json(todos)); + app.post('/todos', (req, res) => { + const id = todos.length + 1; + todos.push({ id, ...req.body }); + res.json({ id }); + }); + app.delete('/todos/:id', (req, res) => { + todos = todos.filter(t => t.id != req.params.id); + res.json({ success: true }); + }); + + app.listen(3000, () => console.log('TODO API on port 3000')); From fceaf172e189fb61f2097c6a0a9e74b62f3ba3a0 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:04:09 +0300 Subject: [PATCH 02/27] chore: use secrets for project automation IDs --- .github/workflows/automate-docs.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/automate-docs.yml diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml new file mode 100644 index 0000000..c612b9c --- /dev/null +++ b/.github/workflows/automate-docs.yml @@ -0,0 +1,27 @@ +name: Auto-Update Wiki & Project + on: [issues, pull_request] + jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install GH CLI + run: | + sudo apt update && sudo apt install curl -y + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list + sudo apt update && sudo apt install gh -y + gh auth login --with-token <<< ${{ secrets.GITHUB_TOKEN }} + - name: Auto-Update Wiki + run: | + ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"') + echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md + git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp + cp wiki/Home.md wiki-temp/ + cd wiki-temp && git add . && git commit -m "docs: auto-update wiki" && git push + - name: Auto-Update Project + if: github.event.pull_request.merged == true + run: | + ISSUE_NUMBER=${{ github.event.pull_request.number }} + ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') + gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" From 9cb7c6cd0e60f42cb14e9a7ab95885c597e573bf Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:07:13 +0300 Subject: [PATCH 03/27] chore: add other files in the .github folder and the DOCKERFILE --- .github/CODEOWNERS | 1 + .github/ISSUE_TEMPLATE/bug-report.md | 14 ++++++++++++ .github/ISSUE_TEMPLATE/development-item.md | 21 ++++++++++++++++++ .github/ISSUE_TEMPLATE/failing-tests.md | 25 ++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature-request.md | 20 +++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 10 +++++++++ .github/dependabot.yml | 10 +++++++++ .github/workflows/cd.yml | 21 ++++++++++++++++++ .github/workflows/ci.yml | 13 +++++++++++ Dockerfile | 7 ++++++ 10 files changed, 142 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/development-item.md create mode 100644 .github/ISSUE_TEMPLATE/failing-tests.md create mode 100644 .github/ISSUE_TEMPLATE/feature-request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/cd.yml create mode 100644 .github/workflows/ci.yml create mode 100644 Dockerfile diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..b575b58 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +@scott45 diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..d0c0293 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,14 @@ +name: Bug Report + description: File a bug + body: + - type: textarea + id: description + attributes: + label: Describe the bug + placeholder: What went wrong? + - type: dropdown + id: labels + attributes: + label: Type + options: [bug, enhancement] + \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/development-item.md b/.github/ISSUE_TEMPLATE/development-item.md new file mode 100644 index 0000000..9769810 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/development-item.md @@ -0,0 +1,21 @@ +name: Development Item + description: Propose a general development task or chore + body: + - type: textarea + id: description + attributes: + label: Task Description + placeholder: What needs to be done? (e.g., refactor code, update docs) + validations: + required: true + - type: dropdown + id: priority + attributes: + label: Priority + options: [Low, Medium, High] + default: Medium + - type: dropdown + id: labels + attributes: + label: Labels + options: [chore, devops, documentation] diff --git a/.github/ISSUE_TEMPLATE/failing-tests.md b/.github/ISSUE_TEMPLATE/failing-tests.md new file mode 100644 index 0000000..5a7ba80 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/failing-tests.md @@ -0,0 +1,25 @@ +name: Failing Test + description: Report a failing automated test in the CI pipeline + body: + - type: textarea + id: test-description + attributes: + label: Test Description + placeholder: Which test is failing? (e.g., test name, file, or CI job) + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Steps to Reproduce + placeholder: How can the failure be reproduced locally or in CI? + - type: input + id: ci-link + attributes: + label: CI Run Link + placeholder: URL to the failing GitHub Actions run (if applicable) + - type: dropdown + id: labels + attributes: + label: Labels + options: [bug, test-failure] diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000..cefb69b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,20 @@ +name: Feature Request + description: Suggest a new feature for the project + body: + - type: textarea + id: feature-description + attributes: + label: Feature Description + placeholder: What feature would you like to see? (e.g., new API endpoint) + validations: + required: true + - type: textarea + id: use-case + attributes: + label: Use Case + placeholder: How would this feature be used? Who benefits? + - type: dropdown + id: labels + attributes: + label: Labels + options: [enhancement, feature] diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..14e5e8b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +## What did we change? + +## Why are we doing this? + +## How was it tested? +- [ ] Locally +- [ ] Development Environment +- [ ] Not needed, changes very basic +- [ ] Husky successfully run +- [ ] Unit tests passing and Documentation done diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..547cf7e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +# Set update schedule for GitHub Actions + +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'daily' diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..39089e9 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,21 @@ +name: Deploy to GHCR + on: + push: + tags: ['v*'] + jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - name: Publish to GH Packages (Docker) + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.DEMO_GITHUB_TOKEN }} + - run: | + docker build -t ghcr.io/${{ github.repository }}:latest . + docker push ghcr.io/${{ github.repository }}:latest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c10709e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,13 @@ +name: CI Pipeline + on: [pull_request, push] + jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - run: npm test + - name: Check Conventional Commits + uses: amannn/action-semantic-commit@v1 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7125318 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM node:20 +WORKDIR /app +COPY package*.json ./ +RUN npm ci +COPY src/ ./src/ +EXPOSE 3000 +CMD ["npm", "start"] From 9ed98dc655839b0df3c79a24c055a6cc54b3b44d Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:23:55 +0300 Subject: [PATCH 04/27] chore: minor improvements in the workflows --- .github/workflows/automate-docs.yml | 2 +- .github/workflows/cd-dev.yml | 24 ++++++++++++++++++++++++ .github/workflows/cd-main.yml | 23 +++++++++++++++++++++++ .github/workflows/cd.yml | 21 --------------------- .github/workflows/ci.yml | 24 ++++++++++++------------ 5 files changed, 60 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/cd-dev.yml create mode 100644 .github/workflows/cd-main.yml delete mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index c612b9c..39aeabe 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -11,7 +11,7 @@ name: Auto-Update Wiki & Project curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list sudo apt update && sudo apt install gh -y - gh auth login --with-token <<< ${{ secrets.GITHUB_TOKEN }} + gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} - name: Auto-Update Wiki run: | ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"') diff --git a/.github/workflows/cd-dev.yml b/.github/workflows/cd-dev.yml new file mode 100644 index 0000000..071d08f --- /dev/null +++ b/.github/workflows/cd-dev.yml @@ -0,0 +1,24 @@ +name: Deploy to GHCR +on: + push: + branches: + - dev + # tags: ['v*'] + workflow_dispatch: +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - name: Publish to GH Packages (Docker) + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.DEMO_GITHUB_TOKEN }} + - run: | + docker build -t ghcr.io/${{ github.repository }}:rc . + docker push ghcr.io/${{ github.repository }}:rc diff --git a/.github/workflows/cd-main.yml b/.github/workflows/cd-main.yml new file mode 100644 index 0000000..befb9a8 --- /dev/null +++ b/.github/workflows/cd-main.yml @@ -0,0 +1,23 @@ +name: Deploy to GHCR +on: + push: + branches: + - main + # tags: ['v*'] +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - name: Publish to GH Packages (Docker) + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.DEMO_GITHUB_TOKEN }} + - run: | + docker build -t ghcr.io/${{ github.repository }}:latest . + docker push ghcr.io/${{ github.repository }}:latest diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml deleted file mode 100644 index 39089e9..0000000 --- a/.github/workflows/cd.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Deploy to GHCR - on: - push: - tags: ['v*'] - jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: { node-version: '20' } - - run: npm ci - - name: Publish to GH Packages (Docker) - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.DEMO_GITHUB_TOKEN }} - - run: | - docker build -t ghcr.io/${{ github.repository }}:latest . - docker push ghcr.io/${{ github.repository }}:latest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c10709e..f573c44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,13 @@ name: CI Pipeline - on: [pull_request, push] - jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: { node-version: '20' } - - run: npm ci - - run: npm test - - name: Check Conventional Commits - uses: amannn/action-semantic-commit@v1 + on: [pull_request, push] + jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - run: npm test + - name: Check Conventional Commits + uses: amannn/action-semantic-commit@v1 From 05aeb3290906013fe805ac14757239c85a624161 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:26:12 +0300 Subject: [PATCH 05/27] chore: fix syntax errors in workflow files --- .github/workflows/automate-docs.yml | 52 ++++++++++++++--------------- .github/workflows/ci.yml | 24 ++++++------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 39aeabe..2bd7803 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,27 +1,27 @@ name: Auto-Update Wiki & Project - on: [issues, pull_request] - jobs: - update: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Install GH CLI - run: | - sudo apt update && sudo apt install curl -y - curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list - sudo apt update && sudo apt install gh -y - gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} - - name: Auto-Update Wiki - run: | - ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"') - echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md - git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp - cp wiki/Home.md wiki-temp/ - cd wiki-temp && git add . && git commit -m "docs: auto-update wiki" && git push - - name: Auto-Update Project - if: github.event.pull_request.merged == true - run: | - ISSUE_NUMBER=${{ github.event.pull_request.number }} - ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') - gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" +on: [issues, pull_request] +jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install GH CLI + run: | + sudo apt update && sudo apt install curl -y + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list + sudo apt update && sudo apt install gh -y + gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} + - name: Auto-Update Wiki + run: | + ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"') + echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md + git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp + cp wiki/Home.md wiki-temp/ + cd wiki-temp && git add . && git commit -m "docs: auto-update wiki" && git push + - name: Auto-Update Project + if: github.event.pull_request.merged == true + run: | + ISSUE_NUMBER=${{ github.event.pull_request.number }} + ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') + gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f573c44..4717e93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,13 +1,13 @@ name: CI Pipeline - on: [pull_request, push] - jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: { node-version: '20' } - - run: npm ci - - run: npm test - - name: Check Conventional Commits - uses: amannn/action-semantic-commit@v1 +on: [pull_request, push] +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: '20' } + - run: npm ci + - run: npm test + - name: Check Conventional Commits + uses: amannn/action-semantic-commit@v1 From 0fb5c03905e652a49e0c4f1b2ee3fdf0f313593e Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:33:30 +0300 Subject: [PATCH 06/27] fix: add wiki dir creation and robust wiki push and update to correct semantic commit action --- .github/workflows/automate-docs.yml | 12 ++++++++---- .github/workflows/ci.yml | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 2bd7803..537e36b 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -14,14 +14,18 @@ jobs: gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} - name: Auto-Update Wiki run: | - ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"') + mkdir -p wiki + ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md - git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp + git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp || (git init wiki-temp && cd wiki-temp && git remote add origin https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git && git checkout -b main) cp wiki/Home.md wiki-temp/ - cd wiki-temp && git add . && git commit -m "docs: auto-update wiki" && git push + cd wiki-temp + git add . + git commit -m "docs: auto-update wiki" || echo "No changes to commit" + git push origin main - name: Auto-Update Project if: github.event.pull_request.merged == true run: | ISSUE_NUMBER=${{ github.event.pull_request.number }} ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') - gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" + gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4717e93..0487d6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,4 +10,6 @@ jobs: - run: npm ci - run: npm test - name: Check Conventional Commits - uses: amannn/action-semantic-commit@v1 + uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} \ No newline at end of file From 253a7fe606fdbc1fc9b48f900998b1b90c10da6f Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:35:11 +0300 Subject: [PATCH 07/27] fix: run npm install --- package-lock.json | 456 +++++++++++++++++++++++----------------------- 1 file changed, 223 insertions(+), 233 deletions(-) diff --git a/package-lock.json b/package-lock.json index ee4f885..0c155bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,49 +1,58 @@ { - "name": "github-devops-javascript", + "name": "github-devops-todo", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "github-devops-javascript", + "name": "github-devops-todo", "version": "1.0.0", - "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^5.1.0" + "express": "^4.18.2" } }, "node_modules/accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, "node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.0", - "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">=18" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/bytes": { @@ -85,9 +94,9 @@ } }, "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -106,22 +115,19 @@ } }, "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "license": "MIT", - "engines": { - "node": ">=6.6.0" - } + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, "node_modules/cors": { "version": "2.8.5", @@ -137,20 +143,12 @@ } }, "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "ms": "2.0.0" } }, "node_modules/depd": { @@ -162,6 +160,16 @@ "node": ">= 0.8" } }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -237,41 +245,45 @@ } }, "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", - "license": "MIT", - "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.0", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "engines": { - "node": ">= 18" + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" }, "funding": { "type": "opencollective", @@ -279,17 +291,18 @@ } }, "node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" @@ -305,12 +318,12 @@ } }, "node_modules/fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/function-bind": { @@ -411,22 +424,13 @@ "node": ">= 0.8" } }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" @@ -447,12 +451,6 @@ "node": ">= 0.10" } }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "license": "MIT" - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -463,57 +461,75 @@ } }, "node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", - "engines": { - "node": ">=18" - }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { - "mime-db": "^1.54.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -552,15 +568,6 @@ "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -571,14 +578,10 @@ } }, "node_modules/path-to-regexp": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", - "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -594,12 +597,12 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -618,50 +621,18 @@ } }, "node_modules/raw-body": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", - "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", - "iconv-lite": "0.7.0", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.10" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "engines": { - "node": ">= 18" + "node": ">= 0.8" } }, "node_modules/safe-buffer": { @@ -691,40 +662,57 @@ "license": "MIT" }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { - "debug": "^4.3.5", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { - "node": ">= 18" + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" }, "engines": { - "node": ">= 18" + "node": ">= 0.8.0" } }, "node_modules/setprototypeof": { @@ -806,9 +794,9 @@ } }, "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -824,14 +812,13 @@ } }, "node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "license": "MIT", "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, "engines": { "node": ">= 0.6" @@ -846,6 +833,15 @@ "node": ">= 0.8" } }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -854,12 +850,6 @@ "engines": { "node": ">= 0.8" } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" } } } From 4c6100c2206412c88dadc558a8e57d0baddba5e1 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:37:01 +0300 Subject: [PATCH 08/27] fix: conventional commit --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0487d6f..a4afbce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,5 @@ jobs: with: { node-version: '20' } - run: npm ci - run: npm test - - name: Check Conventional Commits - uses: amannn/action-semantic-pull-request@v5 env: GITHUB_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} \ No newline at end of file From 5055496b6d2f68630f8b7c78ca0455191bf2e8a6 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:48:46 +0300 Subject: [PATCH 09/27] fix: correct wiki URL and git identity issues --- .github/workflows/automate-docs.yml | 17 ++++++++++++++++- .github/workflows/ci.yml | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 537e36b..d2036a1 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -17,9 +17,24 @@ jobs: mkdir -p wiki ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md - git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp || (git init wiki-temp && cd wiki-temp && git remote add origin https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git && git checkout -b main) + git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp || ( + echo "Wiki repo not found, initializing..." + mkdir wiki-temp + cd wiki-temp + git init + git config user.name "GitHub Actions" + git config user.email "actions@github.com" + git remote add origin https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git + touch Home.md + git add Home.md + git commit -m "chore: initialize wiki repo" + git branch -M main + git push -u origin main + ) cp wiki/Home.md wiki-temp/ cd wiki-temp + git config user.name "GitHub Actions" + git config user.email "actions@github.com" git add . git commit -m "docs: auto-update wiki" || echo "No changes to commit" git push origin main diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4afbce..5d65417 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,5 @@ name: CI Pipeline -on: [pull_request, push] +on: [pull_request] jobs: test: runs-on: ubuntu-latest @@ -10,4 +10,4 @@ jobs: - run: npm ci - run: npm test env: - GITHUB_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} From 05186346368f6843c5258cb5fa703e0aa3667972 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 13:55:35 +0300 Subject: [PATCH 10/27] fix: correct wiki repo URL and remove invalid init logic --- .github/workflows/automate-docs.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index d2036a1..01301a2 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -17,19 +17,9 @@ jobs: mkdir -p wiki ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md - git clone https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git wiki-temp || ( - echo "Wiki repo not found, initializing..." - mkdir wiki-temp - cd wiki-temp - git init - git config user.name "GitHub Actions" - git config user.email "actions@github.com" - git remote add origin https://github.com/${{ github.repository_owner }}/${{ github.repository }}.wiki.git - touch Home.md - git add Home.md - git commit -m "chore: initialize wiki repo" - git branch -M main - git push -u origin main + git clone https://github.com/${{ github.repository_owner }}/${{ github.repository_name }}.wiki.git wiki-temp || ( + echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository_owner }}/${{ github.repository_name }}/wiki" + exit 1 ) cp wiki/Home.md wiki-temp/ cd wiki-temp @@ -43,4 +33,4 @@ jobs: run: | ISSUE_NUMBER=${{ github.event.pull_request.number }} ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') - gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" \ No newline at end of file + gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" From fbb7442febb9fe6ad7ff5c1f2119ab3935af2815 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 14:07:18 +0300 Subject: [PATCH 11/27] fix: use github.repository for wiki URL and add auth for git --- .github/workflows/automate-docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 01301a2..c7dce1a 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -17,8 +17,8 @@ jobs: mkdir -p wiki ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md - git clone https://github.com/${{ github.repository_owner }}/${{ github.repository_name }}.wiki.git wiki-temp || ( - echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository_owner }}/${{ github.repository_name }}/wiki" + git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( + echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 ) cp wiki/Home.md wiki-temp/ @@ -27,7 +27,7 @@ jobs: git config user.email "actions@github.com" git add . git commit -m "docs: auto-update wiki" || echo "No changes to commit" - git push origin main + git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git main - name: Auto-Update Project if: github.event.pull_request.merged == true run: | From 90ae4db1acfdde07c66a39c58dfcf467ae6623ef Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 14:19:20 +0300 Subject: [PATCH 12/27] fix: use master for wiki push and trigger on dev PRs --- .github/workflows/automate-docs.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index c7dce1a..7ed36bd 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,5 +1,8 @@ name: Auto-Update Wiki & Project -on: [issues, pull_request] +on: + issues: + pull_request: + branches: [dev] # Trigger on PRs targeting dev jobs: update: runs-on: ubuntu-latest @@ -25,11 +28,12 @@ jobs: cd wiki-temp git config user.name "GitHub Actions" git config user.email "actions@github.com" + git checkout dev || git checkout -b dev git add . git commit -m "docs: auto-update wiki" || echo "No changes to commit" - git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git main + git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git dev - name: Auto-Update Project - if: github.event.pull_request.merged == true + if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' run: | ISSUE_NUMBER=${{ github.event.pull_request.number }} ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') From e91065c4aa3bdd2d89c6a5bc6b6aa15c3512a10c Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 15:26:34 +0300 Subject: [PATCH 13/27] feat: second iteration of workflows improvements --- .github/ISSUE_TEMPLATE/bug-report.md | 27 ++++++------ .github/ISSUE_TEMPLATE/bug_report_md.md | 11 +++++ .github/ISSUE_TEMPLATE/development-item.md | 42 +++++++++--------- .github/ISSUE_TEMPLATE/failing-tests.md | 50 +++++++++++----------- .github/ISSUE_TEMPLATE/feature-request.md | 40 ++++++++--------- .github/PULL_REQUEST_TEMPLATE.md | 5 ++- .github/workflows/automate-docs.yml | 15 +++++-- .github/workflows/cd-dev.yml | 1 + .github/workflows/cd-main.yml | 1 + .github/workflows/ci.yml | 1 + Dockerfile | 2 + 11 files changed, 111 insertions(+), 84 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report_md.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index d0c0293..f7d5672 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,14 +1,15 @@ name: Bug Report - description: File a bug - body: - - type: textarea - id: description - attributes: - label: Describe the bug - placeholder: What went wrong? - - type: dropdown - id: labels - attributes: - label: Type - options: [bug, enhancement] - \ No newline at end of file +description: File a bug +body: + - type: textarea + id: description + attributes: + label: Describe the bug + placeholder: What went wrong? + validations: + required: true + - type: dropdown + id: labels + attributes: + label: Type + options: [bug, enhancement] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report_md.md b/.github/ISSUE_TEMPLATE/bug_report_md.md new file mode 100644 index 0000000..6a3c073 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report_md.md @@ -0,0 +1,11 @@ +--- +name: Bug Report +about: File a bug +--- +## Bug Report +**Describe the bug**: +What went wrong? + +**Type**: +- [ ] Bug +- [ ] Enhancement diff --git a/.github/ISSUE_TEMPLATE/development-item.md b/.github/ISSUE_TEMPLATE/development-item.md index 9769810..e71b074 100644 --- a/.github/ISSUE_TEMPLATE/development-item.md +++ b/.github/ISSUE_TEMPLATE/development-item.md @@ -1,21 +1,21 @@ -name: Development Item - description: Propose a general development task or chore - body: - - type: textarea - id: description - attributes: - label: Task Description - placeholder: What needs to be done? (e.g., refactor code, update docs) - validations: - required: true - - type: dropdown - id: priority - attributes: - label: Priority - options: [Low, Medium, High] - default: Medium - - type: dropdown - id: labels - attributes: - label: Labels - options: [chore, devops, documentation] +name: Development Item +description: Propose a general development task or chore +body: + - type: textarea + id: description + attributes: + label: Task Description + placeholder: What needs to be done? (e.g., refactor code, update docs) + validations: + required: true + - type: dropdown + id: priority + attributes: + label: Priority + options: [Low, Medium, High] + default: 1 + - type: dropdown + id: labels + attributes: + label: Labels + options: [chore, devops, documentation] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/failing-tests.md b/.github/ISSUE_TEMPLATE/failing-tests.md index 5a7ba80..ce78707 100644 --- a/.github/ISSUE_TEMPLATE/failing-tests.md +++ b/.github/ISSUE_TEMPLATE/failing-tests.md @@ -1,25 +1,25 @@ -name: Failing Test - description: Report a failing automated test in the CI pipeline - body: - - type: textarea - id: test-description - attributes: - label: Test Description - placeholder: Which test is failing? (e.g., test name, file, or CI job) - validations: - required: true - - type: textarea - id: reproduction - attributes: - label: Steps to Reproduce - placeholder: How can the failure be reproduced locally or in CI? - - type: input - id: ci-link - attributes: - label: CI Run Link - placeholder: URL to the failing GitHub Actions run (if applicable) - - type: dropdown - id: labels - attributes: - label: Labels - options: [bug, test-failure] +name: Failing Test +description: Report a failing automated test in the CI pipeline +body: + - type: textarea + id: test-description + attributes: + label: Test Description + placeholder: Which test is failing? (e.g., test name, file, or CI job) + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Steps to Reproduce + placeholder: How can the failure be reproduced locally or in CI? + - type: input + id: ci-link + attributes: + label: CI Run Link + placeholder: URL to the failing GitHub Actions run (if applicable) + - type: dropdown + id: labels + attributes: + label: Labels + options: [bug, test-failure] \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index cefb69b..e130c4c 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,20 +1,20 @@ -name: Feature Request - description: Suggest a new feature for the project - body: - - type: textarea - id: feature-description - attributes: - label: Feature Description - placeholder: What feature would you like to see? (e.g., new API endpoint) - validations: - required: true - - type: textarea - id: use-case - attributes: - label: Use Case - placeholder: How would this feature be used? Who benefits? - - type: dropdown - id: labels - attributes: - label: Labels - options: [enhancement, feature] +name: Feature Request +description: Suggest a new feature for the project +body: + - type: textarea + id: feature-description + attributes: + label: Feature Description + placeholder: What feature would you like to see? (e.g., new API endpoint) + validations: + required: true + - type: textarea + id: use-case + attributes: + label: Use Case + placeholder: How would this feature be used? Who benefits? + - type: dropdown + id: labels + attributes: + label: Labels + options: [enhancement, feature] \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 14e5e8b..e72c3a0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,6 @@ +## What Issue is being closed by this PR. Replace X below with the issue number +Closes #X + ## What did we change? ## Why are we doing this? @@ -6,5 +9,5 @@ - [ ] Locally - [ ] Development Environment - [ ] Not needed, changes very basic -- [ ] Husky successfully run +- [ ] npm i successfully run - [ ] Unit tests passing and Documentation done diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 7ed36bd..e1b0598 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -5,6 +5,7 @@ on: branches: [dev] # Trigger on PRs targeting dev jobs: update: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -28,13 +29,19 @@ jobs: cd wiki-temp git config user.name "GitHub Actions" git config user.email "actions@github.com" - git checkout dev || git checkout -b dev + git checkout master || git checkout -b master git add . git commit -m "docs: auto-update wiki" || echo "No changes to commit" - git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git dev + git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' run: | ISSUE_NUMBER=${{ github.event.pull_request.number }} - ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $ISSUE_NUMBER) { id } } }" --jq '.data.repository.issue.id') - gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" + PR_BODY=$(gh pr view $ISSUE_NUMBER --json body --jq '.body') + LINKED_ISSUE_NUM=$(echo "$PR_BODY" | grep -oE 'Closes #([0-9]+)' | sed 's/Closes #//g' | head -n1) + if [ -n "$LINKED_ISSUE_NUM" ]; then + ISSUE_ID=$(gh api graphql -f query="query { repository(owner: \"${{ github.repository_owner }}\", name: \"${{ github.repository_name }}\") { issue(number: $LINKED_ISSUE_NUM) { id } } }" --jq '.data.repository.issue.id') + gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" + else + echo "No linked issue found in PR body (e.g., 'Closes #X'). Skipping project update." + fi diff --git a/.github/workflows/cd-dev.yml b/.github/workflows/cd-dev.yml index 071d08f..4884a49 100644 --- a/.github/workflows/cd-dev.yml +++ b/.github/workflows/cd-dev.yml @@ -7,6 +7,7 @@ on: workflow_dispatch: jobs: deploy: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/cd-main.yml b/.github/workflows/cd-main.yml index befb9a8..f75ae6e 100644 --- a/.github/workflows/cd-main.yml +++ b/.github/workflows/cd-main.yml @@ -6,6 +6,7 @@ on: # tags: ['v*'] jobs: deploy: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d65417..becc460 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI Pipeline on: [pull_request] jobs: test: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index 7125318..e843f42 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,3 +5,5 @@ RUN npm ci COPY src/ ./src/ EXPOSE 3000 CMD ["npm", "start"] +# Add these labels for auto-linking +LABEL org.opencontainers.image.source="https://github.com/scott45/github-devops-javascript" From 310bf64b8870092eca86e84e5b633e919b9b9bc5 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 15:40:35 +0300 Subject: [PATCH 14/27] fix: correct wiki formatting with echo -e and overwrite --- .github/workflows/automate-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index e1b0598..121fe62 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -20,7 +20,7 @@ jobs: run: | mkdir -p wiki ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") - echo "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md + echo -e "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 From 9372b072cb14a8db8e6837f3aa89bbfb8bd321b0 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 16:28:43 +0300 Subject: [PATCH 15/27] enhance: subdivide wiki issues into To-Do and Done --- .../ISSUE_TEMPLATE/{bug-report.md => bug-report.yml} | 0 .../{development-item.md => development-item.yml} | 0 .../{failing-tests.md => failing-tests.yml} | 0 .../{feature-request.md => feature-request.yml} | 0 .github/workflows/automate-docs.yml | 10 +++++++--- 5 files changed, 7 insertions(+), 3 deletions(-) rename .github/ISSUE_TEMPLATE/{bug-report.md => bug-report.yml} (100%) rename .github/ISSUE_TEMPLATE/{development-item.md => development-item.yml} (100%) rename .github/ISSUE_TEMPLATE/{failing-tests.md => failing-tests.yml} (100%) rename .github/ISSUE_TEMPLATE/{feature-request.md => feature-request.yml} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/bug-report.md rename to .github/ISSUE_TEMPLATE/bug-report.yml diff --git a/.github/ISSUE_TEMPLATE/development-item.md b/.github/ISSUE_TEMPLATE/development-item.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/development-item.md rename to .github/ISSUE_TEMPLATE/development-item.yml diff --git a/.github/ISSUE_TEMPLATE/failing-tests.md b/.github/ISSUE_TEMPLATE/failing-tests.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/failing-tests.md rename to .github/ISSUE_TEMPLATE/failing-tests.yml diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.yml similarity index 100% rename from .github/ISSUE_TEMPLATE/feature-request.md rename to .github/ISSUE_TEMPLATE/feature-request.yml diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 121fe62..67dbc29 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -19,8 +19,12 @@ jobs: - name: Auto-Update Wiki run: | mkdir -p wiki - ISSUES=$(gh issue list --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No issues found") - echo -e "# Project Updates\n\n## Recent Issues\n$ISSUES" > wiki/Home.md + # Get open issues + ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open issues") + # Get closed issues + ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") + # Generate Markdown with subsections + echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n\n## Done\n$ISSUES_CLOSED" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 @@ -31,7 +35,7 @@ jobs: git config user.email "actions@github.com" git checkout master || git checkout -b master git add . - git commit -m "docs: auto-update wiki" || echo "No changes to commit" + git commit -m "docs: auto-update wiki" || git commit -m "docs: force update wiki" git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' From fb97a5f3a19d7f0b6c1c971bbe102323a7be6349 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 17:03:51 +0300 Subject: [PATCH 16/27] enhance: dynamic tag with PR number and commit hash for dev and fix bug templates --- .github/ISSUE_TEMPLATE/bug-report.yml | 4 ++-- .github/ISSUE_TEMPLATE/bug_report_md.md | 4 ++-- .github/workflows/cd-dev.yml | 14 ++++++++++---- .github/workflows/cd-main.yml | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index f7d5672..926c7a7 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,5 +1,5 @@ -name: Bug Report -description: File a bug +name: Bug Report yml +description: File a bug with yml body: - type: textarea id: description diff --git a/.github/ISSUE_TEMPLATE/bug_report_md.md b/.github/ISSUE_TEMPLATE/bug_report_md.md index 6a3c073..4591293 100644 --- a/.github/ISSUE_TEMPLATE/bug_report_md.md +++ b/.github/ISSUE_TEMPLATE/bug_report_md.md @@ -1,6 +1,6 @@ --- -name: Bug Report -about: File a bug +name: Bug Report with traditional mkdwn format +about: File a bug in mkdwn --- ## Bug Report **Describe the bug**: diff --git a/.github/workflows/cd-dev.yml b/.github/workflows/cd-dev.yml index 4884a49..765549c 100644 --- a/.github/workflows/cd-dev.yml +++ b/.github/workflows/cd-dev.yml @@ -1,9 +1,8 @@ -name: Deploy to GHCR +name: Deploy to GHCR (Dev) on: push: branches: - dev - # tags: ['v*'] workflow_dispatch: jobs: deploy: @@ -21,5 +20,12 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.DEMO_GITHUB_TOKEN }} - run: | - docker build -t ghcr.io/${{ github.repository }}:rc . - docker push ghcr.io/${{ github.repository }}:rc + # Extract PR number from merge commit message (e.g., "Merge pull request #5...") + PR_NUMBER=$(git log -1 --pretty=%B | grep -oE 'Merge pull request #([0-9]+)' | sed 's/Merge pull request #//g' || echo "unknown") + # Use short commit hash (first 7 chars) + COMMIT_HASH=$(git rev-parse --short=7 HEAD) + # Construct tag (e.g., pr5-a1b2c3d) + TAG="pr${PR_NUMBER}-${COMMIT_HASH}" + # Build and push with dynamic tag + docker build -t ghcr.io/${{ github.repository }}:$TAG . + docker push ghcr.io/${{ github.repository }}:$TAG diff --git a/.github/workflows/cd-main.yml b/.github/workflows/cd-main.yml index f75ae6e..919ca93 100644 --- a/.github/workflows/cd-main.yml +++ b/.github/workflows/cd-main.yml @@ -1,4 +1,4 @@ -name: Deploy to GHCR +name: Deploy to GHCR (Main) on: push: branches: From c228a0d4ac20144fc1ab39e12d1cda6b2de98727 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 18:10:55 +0300 Subject: [PATCH 17/27] fix: stabilize wiki workflow with forced commits --- .github/workflows/automate-docs.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 67dbc29..886bc71 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,8 +1,7 @@ name: Auto-Update Wiki & Project on: - issues: - pull_request: - branches: [dev] # Trigger on PRs targeting dev + push: + branches: [ "dev", "main" ] # Trigger on PRs targeting dev jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -19,11 +18,8 @@ jobs: - name: Auto-Update Wiki run: | mkdir -p wiki - # Get open issues ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open issues") - # Get closed issues ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") - # Generate Markdown with subsections echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n\n## Done\n$ISSUES_CLOSED" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" @@ -34,8 +30,10 @@ jobs: git config user.name "GitHub Actions" git config user.email "actions@github.com" git checkout master || git checkout -b master + git reset --hard # Ensure clean state git add . - git commit -m "docs: auto-update wiki" || git commit -m "docs: force update wiki" + TIMESTAMP=$(date -u +"%Y%m%d%H%M%S") + git commit -m "docs: auto-update wiki [run $TIMESTAMP]" || echo "No changes detected, but workflow continues" git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' From c56fb9e5fa5e8ab8df94f9300dece9700484fc98 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 18:15:34 +0300 Subject: [PATCH 18/27] fix: stabilize wiki workflow by running only on opened issues --- .github/workflows/automate-docs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 886bc71..4df4bc7 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -2,6 +2,8 @@ name: Auto-Update Wiki & Project on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev + issues: + types: [opened] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' From cbb6b85d8c89f6f450a73fe9cc128ca34d98c194 Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 18:25:00 +0300 Subject: [PATCH 19/27] fix: stabilize wiki workflow by running only on pr merges --- .github/workflows/automate-docs.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 4df4bc7..886bc71 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -2,8 +2,6 @@ name: Auto-Update Wiki & Project on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev - issues: - types: [opened] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' From b828157f34bd0f5752b46f3bb4384299e0dec2ee Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 18:44:44 +0300 Subject: [PATCH 20/27] fix: stabilize wiki workflow by running also on pr merges --- .github/workflows/automate-docs.yml | 71 ++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 886bc71..de362c9 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -2,6 +2,8 @@ name: Auto-Update Wiki & Project on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev + pull_request: + types: [opened, edited, reopened, closed] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -15,26 +17,71 @@ jobs: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list sudo apt update && sudo apt install gh -y gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} - - name: Auto-Update Wiki + - name: Auto-Update Wiki (Issues + PRs) + env: + GH_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} run: | + set -euo pipefail + mkdir -p wiki - ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open issues") - ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") - echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n\n## Done\n$ISSUES_CLOSED" > wiki/Home.md - git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( - echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" + + # Open / Closed Issues + ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || true) + ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || true) + + # Open / Merged PRs + PRS_OPEN=$(gh pr list --state open --json title,createdAt --jq '.[] | "- \(.title) (Opened: \(.createdAt))"' || true) + PRS_MERGED=$(gh pr list --state merged --json title,mergedAt --jq '.[] | "- \(.title) (Merged: \(.mergedAt))"' || true) + + # Fallback text if lists are empty + [ -n "$ISSUES_OPEN" ] || ISSUES_OPEN="(none)" + [ -n "$ISSUES_CLOSED"] || ISSUES_CLOSED="(none)" + [ -n "$PRS_OPEN" ] || PRS_OPEN="(none)" + [ -n "$PRS_MERGED" ] || PRS_MERGED="(none)" + + cat > wiki/Home.md <<'EOF' + # Project Updates + + ## To-Do + ### Issues + __ISSUES_OPEN__ + ### Pull Requests + __PRS_OPEN__ + + ## Done + ### Issues (Closed) + __ISSUES_CLOSED__ + ### Pull Requests (Merged) + __PRS_MERGED__ + EOF + + # Inject the dynamic lists + sed -i 's|__ISSUES_OPEN__|'"$(printf '%s\n' "$ISSUES_OPEN" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md + sed -i 's|__ISSUES_CLOSED__|'"$(printf '%s\n' "$ISSUES_CLOSED"| sed 's/[&/\]/\\&/g')"|g' wiki/Home.md + sed -i 's|__PRS_OPEN__|'"$(printf '%s\n' "$PRS_OPEN" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md + sed -i 's|__PRS_MERGED__|'"$(printf '%s\n' "$PRS_MERGED" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md + + # Clone wiki repo + git clone "https://${{ github.actor }}:${GH_TOKEN}@github.com/${{ github.repository }}.wiki.git" wiki-temp || { + echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI (Wiki tab)." exit 1 - ) + } + cp wiki/Home.md wiki-temp/ cd wiki-temp + git config user.name "GitHub Actions" git config user.email "actions@github.com" - git checkout master || git checkout -b master - git reset --hard # Ensure clean state + + # Detect wiki default branch (master/main) + DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}') + git checkout "$DEFAULT_BRANCH" || git checkout -b "$DEFAULT_BRANCH" + git add . - TIMESTAMP=$(date -u +"%Y%m%d%H%M%S") - git commit -m "docs: auto-update wiki [run $TIMESTAMP]" || echo "No changes detected, but workflow continues" - git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master + TS=$(date -u +"%Y%m%d%H%M%S") + git commit -m "docs: auto-update wiki [run $TS]" || { echo "No changes to commit"; exit 0; } + git push "https://${{ github.actor }}:${GH_TOKEN}@github.com/${{ github.repository }}.wiki.git" "$DEFAULT_BRANCH" + - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' run: | From 99aeeb691bcdba56e3667101b46c6fe49db67c2e Mon Sep 17 00:00:00 2001 From: scott45 Date: Thu, 16 Oct 2025 18:45:38 +0300 Subject: [PATCH 21/27] fix: stabilize wiki workflow by running also on pr merges --- .github/workflows/automate-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index de362c9..705af12 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -3,7 +3,7 @@ on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev pull_request: - types: [opened, edited, reopened, closed] + types: [opened, reopened, closed] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' From 04a87b6b3827333c64c041542da389fe76b265ae Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 10:02:46 +0300 Subject: [PATCH 22/27] feat: list issues and pr merges in wiki --- .github/workflows/automate-docs.yml | 76 +++++++---------------------- 1 file changed, 18 insertions(+), 58 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 705af12..0446716 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -3,7 +3,7 @@ on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev pull_request: - types: [opened, reopened, closed] + types: [opened, edited, reopened, closed] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -17,71 +17,31 @@ jobs: echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list sudo apt update && sudo apt install gh -y gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} - - name: Auto-Update Wiki (Issues + PRs) - env: - GH_TOKEN: ${{ secrets.DEMO_GITHUB_TOKEN }} + - name: Auto-Update Wiki run: | - set -euo pipefail - mkdir -p wiki - - # Open / Closed Issues - ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || true) - ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || true) - - # Open / Merged PRs - PRS_OPEN=$(gh pr list --state open --json title,createdAt --jq '.[] | "- \(.title) (Opened: \(.createdAt))"' || true) - PRS_MERGED=$(gh pr list --state merged --json title,mergedAt --jq '.[] | "- \(.title) (Merged: \(.mergedAt))"' || true) - - # Fallback text if lists are empty - [ -n "$ISSUES_OPEN" ] || ISSUES_OPEN="(none)" - [ -n "$ISSUES_CLOSED"] || ISSUES_CLOSED="(none)" - [ -n "$PRS_OPEN" ] || PRS_OPEN="(none)" - [ -n "$PRS_MERGED" ] || PRS_MERGED="(none)" - - cat > wiki/Home.md <<'EOF' - # Project Updates - - ## To-Do - ### Issues - __ISSUES_OPEN__ - ### Pull Requests - __PRS_OPEN__ - - ## Done - ### Issues (Closed) - __ISSUES_CLOSED__ - ### Pull Requests (Merged) - __PRS_MERGED__ - EOF - - # Inject the dynamic lists - sed -i 's|__ISSUES_OPEN__|'"$(printf '%s\n' "$ISSUES_OPEN" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md - sed -i 's|__ISSUES_CLOSED__|'"$(printf '%s\n' "$ISSUES_CLOSED"| sed 's/[&/\]/\\&/g')"|g' wiki/Home.md - sed -i 's|__PRS_OPEN__|'"$(printf '%s\n' "$PRS_OPEN" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md - sed -i 's|__PRS_MERGED__|'"$(printf '%s\n' "$PRS_MERGED" | sed 's/[&/\]/\\&/g')"|g' wiki/Home.md - - # Clone wiki repo - git clone "https://${{ github.actor }}:${GH_TOKEN}@github.com/${{ github.repository }}.wiki.git" wiki-temp || { - echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI (Wiki tab)." + # Get open issues and PRs for To-Do + ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open issues") + PRS_OPEN=$(gh pr list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open PRs") + # Get closed issues and merged PRs for Done + ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") + PRS_MERGED=$(gh pr list --state merged --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No merged PRs") + # Generate Markdown with subsections + echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n$PRS_OPEN\n\n## Done\n$ISSUES_CLOSED\n$PRS_MERGED" > wiki/Home.md + git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( + echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 - } - + ) cp wiki/Home.md wiki-temp/ cd wiki-temp - git config user.name "GitHub Actions" git config user.email "actions@github.com" - - # Detect wiki default branch (master/main) - DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}') - git checkout "$DEFAULT_BRANCH" || git checkout -b "$DEFAULT_BRANCH" - + git checkout master || git checkout -b master + git reset --hard # Ensure clean state git add . - TS=$(date -u +"%Y%m%d%H%M%S") - git commit -m "docs: auto-update wiki [run $TS]" || { echo "No changes to commit"; exit 0; } - git push "https://${{ github.actor }}:${GH_TOKEN}@github.com/${{ github.repository }}.wiki.git" "$DEFAULT_BRANCH" - + TIMESTAMP=$(date -u +"%Y%m%d%H%M%S") + git commit -m "docs: auto-update wiki [run $TIMESTAMP]" || echo "No changes detected, but workflow continues" + git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' run: | From 2d2f3ed9ed6e6be0fa29ec9352901b909eb4eddf Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 10:13:15 +0300 Subject: [PATCH 23/27] enhance: add subheadings for PRs in wiki --- .github/workflows/automate-docs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 0446716..446f85d 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -2,8 +2,8 @@ name: Auto-Update Wiki & Project on: push: branches: [ "dev", "main" ] # Trigger on PRs targeting dev - pull_request: - types: [opened, edited, reopened, closed] + # pull_request: + # types: [opened, edited, reopened, closed] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -26,8 +26,8 @@ jobs: # Get closed issues and merged PRs for Done ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") PRS_MERGED=$(gh pr list --state merged --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No merged PRs") - # Generate Markdown with subsections - echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n$PRS_OPEN\n\n## Done\n$ISSUES_CLOSED\n$PRS_MERGED" > wiki/Home.md + # Generate Markdown with subheadings for issues and PRs + echo -e "# Project Updates\n\n## To-Do\n### Open Issues\n$ISSUES_OPEN\n### Open PRs\n$PRS_OPEN\n\n## Done\n### Closed Issues\n$ISSUES_CLOSED\n### Merged PRs\n$PRS_MERGED" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 From 15791f6417284e74e7c2bd0b632c8b1f20308277 Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 10:27:02 +0300 Subject: [PATCH 24/27] fix: add issues trigger and confirm subheadings --- .github/workflows/automate-docs.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 446f85d..9a042d9 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,9 +1,11 @@ name: Auto-Update Wiki & Project on: + issues: + types: [opened, edited, closed, reopened] push: - branches: [ "dev", "main" ] # Trigger on PRs targeting dev - # pull_request: - # types: [opened, edited, reopened, closed] + branches: [ "dev", "main" ] + pull_request: + types: [opened, edited, reopened, closed] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -26,7 +28,7 @@ jobs: # Get closed issues and merged PRs for Done ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") PRS_MERGED=$(gh pr list --state merged --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No merged PRs") - # Generate Markdown with subheadings for issues and PRs + # Generate Markdown with subsections echo -e "# Project Updates\n\n## To-Do\n### Open Issues\n$ISSUES_OPEN\n### Open PRs\n$PRS_OPEN\n\n## Done\n### Closed Issues\n$ISSUES_CLOSED\n### Merged PRs\n$PRS_MERGED" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" From 56f22cf433934cd8a3ce4fb3a5e73e9b0ec8f35a Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 10:38:38 +0300 Subject: [PATCH 25/27] fix: revert to last working version --- .github/workflows/automate-docs.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 9a042d9..93e4d5c 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,11 +1,8 @@ name: Auto-Update Wiki & Project on: issues: - types: [opened, edited, closed, reopened] - push: - branches: [ "dev", "main" ] pull_request: - types: [opened, edited, reopened, closed] + branches: [dev] # Trigger on PRs targeting dev jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' @@ -22,14 +19,12 @@ jobs: - name: Auto-Update Wiki run: | mkdir -p wiki - # Get open issues and PRs for To-Do + # Get open issues ISSUES_OPEN=$(gh issue list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open issues") - PRS_OPEN=$(gh pr list --state open --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No open PRs") - # Get closed issues and merged PRs for Done + # Get closed issues ISSUES_CLOSED=$(gh issue list --state closed --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No closed issues") - PRS_MERGED=$(gh pr list --state merged --json title,createdAt --jq '.[] | "- \(.title) (Created: \(.createdAt))"' || echo "No merged PRs") # Generate Markdown with subsections - echo -e "# Project Updates\n\n## To-Do\n### Open Issues\n$ISSUES_OPEN\n### Open PRs\n$PRS_OPEN\n\n## Done\n### Closed Issues\n$ISSUES_CLOSED\n### Merged PRs\n$PRS_MERGED" > wiki/Home.md + echo -e "# Project Updates\n\n## To-Do\n$ISSUES_OPEN\n\n## Done\n$ISSUES_CLOSED" > wiki/Home.md git clone https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git wiki-temp || ( echo "Error: Wiki repo not found. Please initialize the wiki in the GitHub UI at https://github.com/${{ github.repository }}/wiki" exit 1 @@ -39,10 +34,8 @@ jobs: git config user.name "GitHub Actions" git config user.email "actions@github.com" git checkout master || git checkout -b master - git reset --hard # Ensure clean state git add . - TIMESTAMP=$(date -u +"%Y%m%d%H%M%S") - git commit -m "docs: auto-update wiki [run $TIMESTAMP]" || echo "No changes detected, but workflow continues" + git commit -m "docs: auto-update wiki" || git commit -m "docs: force update wiki" git push https://${{ github.actor }}:${{ secrets.DEMO_GITHUB_TOKEN }}@github.com/${{ github.repository }}.wiki.git master - name: Auto-Update Project if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'dev' @@ -55,4 +48,4 @@ jobs: gh api graphql -f query="mutation { updateProjectV2ItemFieldValue(input: { projectId: \"${{ secrets.PROJECT_ID }}\", itemId: \"$ISSUE_ID\", fieldId: \"${{ secrets.STATUS_FIELD_ID }}\", value: { singleSelectOptionId: \"${{ secrets.DONE_OPTION_ID }}\" } }) { projectV2Item { id } } }" else echo "No linked issue found in PR body (e.g., 'Closes #X'). Skipping project update." - fi + fi \ No newline at end of file From 5e2a230af3423dc4ee9b1554848c93206ee69bde Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 10:54:02 +0300 Subject: [PATCH 26/27] fix: only trigger workflow on issues --- .github/workflows/automate-docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 93e4d5c..44f3b0a 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,8 +1,7 @@ name: Auto-Update Wiki & Project on: issues: - pull_request: - branches: [dev] # Trigger on PRs targeting dev + types: [opened, edited, closed, reopened] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' From 7423973f4d48d283b7b597e9b15f96ff8b24fe8e Mon Sep 17 00:00:00 2001 From: scott45 Date: Fri, 17 Oct 2025 12:30:37 +0300 Subject: [PATCH 27/27] fix: only trigger workflow on issues --- .github/workflows/automate-docs.yml | 2 +- .github/workflows/release.yml | 45 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/automate-docs.yml b/.github/workflows/automate-docs.yml index 44f3b0a..1e4f231 100644 --- a/.github/workflows/automate-docs.yml +++ b/.github/workflows/automate-docs.yml @@ -1,7 +1,7 @@ name: Auto-Update Wiki & Project on: issues: - types: [opened, edited, closed, reopened] + types: [opened, closed] # [opened, edited, closed, reopened] jobs: update: if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5f9ca21 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,45 @@ +name: Prepare Release +on: + push: + branches: + - main +jobs: + release: + if: github.actor != 'dependabot[bot]' && github.actor != 'dependabot-preview[bot]' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for last tag and notes + - name: Install GH CLI + run: | + sudo apt update && sudo apt install curl -y + curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list + sudo apt update && sudo apt install gh -y + gh auth login --with-token <<< ${{ secrets.DEMO_GITHUB_TOKEN }} + - name: Generate Release Notes and Tag + run: | + # Get last tag or default to v1.0.0 + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v1.0.0") + # Extract PR title from merge commit message (e.g., "Merge pull request #X from ... feat!: release v1.0.0") + PR_TITLE=$(git log -1 --merges --pretty=%s | sed 's/Merge pull request #[0-9]\+ from .*//;s/ .*//') + # Determine version bump based on PR title prefix + MAJOR=$(echo "$PR_TITLE" | grep -q "^feat!:" && echo 1 || echo 0) + MINOR=$(echo "$PR_TITLE" | grep -q "^\(feat:\|fix:\|refactor:\)" && echo 1 || echo 0) + PATCH=$(echo "$PR_TITLE" | grep -q "^\(chore:\|docs:\|test:\)" && echo 1 || echo 0) + # Parse current version + CURRENT_MAJOR=$(echo $LAST_TAG | sed 's/v\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/\1/') + CURRENT_MINOR=$(echo $LAST_TAG | sed 's/v\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/\2/') + CURRENT_PATCH=$(echo $LAST_TAG | sed 's/v\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/\3/') + # Calculate new version (only one level bumps) + NEW_MAJOR=$((CURRENT_MAJOR + MAJOR)) + NEW_MINOR=$((CURRENT_MINOR + MINOR * (1 - MAJOR))) + NEW_PATCH=$((CURRENT_PATCH + PATCH * (1 - MAJOR) * (1 - MINOR))) + TAG="v${NEW_MAJOR}.${NEW_MINOR}.${NEW_PATCH}" + # Extract notes from commits since last tag + NOTES=$(git log $LAST_TAG..HEAD --pretty=format:"- %s" | grep -E "^(feat|fix|chore|docs|test|refactor):" || echo "Initial release") + # Create tag and draft release + git tag $TAG + git push origin $TAG + gh release create $TAG --title "Release ${NEW_MAJOR}.${NEW_MINOR}.${NEW_PATCH}" --notes "$NOTES" --draft