Added SetupGitHubRelease Task
This commit is contained in:
680
task/SetupGitHubRelease/package-lock.json
generated
Normal file
680
task/SetupGitHubRelease/package-lock.json
generated
Normal file
@@ -0,0 +1,680 @@
|
|||||||
|
{
|
||||||
|
"name": "setup-github-release-task",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "setup-github-release-task",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"azure-pipelines-task-lib": "^5.2.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.11.30",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodelib/fs.stat": "2.0.5",
|
||||||
|
"run-parallel": "^1.1.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nodelib/fs.stat": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nodelib/fs.walk": {
|
||||||
|
"version": "1.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||||
|
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodelib/fs.scandir": "2.1.5",
|
||||||
|
"fastq": "^1.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.19.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz",
|
||||||
|
"integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/adm-zip": {
|
||||||
|
"version": "0.5.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz",
|
||||||
|
"integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/agent-base": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/azure-pipelines-task-lib": {
|
||||||
|
"version": "5.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/azure-pipelines-task-lib/-/azure-pipelines-task-lib-5.2.6.tgz",
|
||||||
|
"integrity": "sha512-YWEJFAY+Imk5nWwPd5ao6h/J8BgW2Dtzt+M5QiUWDV5cB10n4zywQ5Dulj2OcO1B9tGfdV5KDKVnQRKfJ72YmA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"adm-zip": "^0.5.10",
|
||||||
|
"minimatch": "3.0.5",
|
||||||
|
"nodejs-file-downloader": "^4.11.1",
|
||||||
|
"q": "^1.5.1",
|
||||||
|
"semver": "^5.7.2",
|
||||||
|
"shelljs": "^0.10.0",
|
||||||
|
"uuid": "^3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||||
|
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/cross-spawn": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.1.0",
|
||||||
|
"shebang-command": "^2.0.0",
|
||||||
|
"which": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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/execa": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"get-stream": "^6.0.0",
|
||||||
|
"human-signals": "^2.1.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"npm-run-path": "^4.0.1",
|
||||||
|
"onetime": "^5.1.2",
|
||||||
|
"signal-exit": "^3.0.3",
|
||||||
|
"strip-final-newline": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fast-glob": {
|
||||||
|
"version": "3.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||||
|
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nodelib/fs.stat": "^2.0.2",
|
||||||
|
"@nodelib/fs.walk": "^1.2.3",
|
||||||
|
"glob-parent": "^5.1.2",
|
||||||
|
"merge2": "^1.3.0",
|
||||||
|
"micromatch": "^4.0.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fastq": {
|
||||||
|
"version": "1.20.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
||||||
|
"integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"reusify": "^1.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||||
|
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-stream": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/https-proxy-agent": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "6",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/human-signals": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.17.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/isexe": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/merge2": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/micromatch": {
|
||||||
|
"version": "4.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||||
|
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"braces": "^3.0.3",
|
||||||
|
"picomatch": "^2.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"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": "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.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mimic-fn": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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/nodejs-file-downloader": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-nI2fKnmJWWFZF6SgMPe1iBodKhfpztLKJTtCtNYGhm/9QXmWa/Pk9Sv00qHgzEvNLe1x7hjGDRor7gcm/ChaIQ==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"https-proxy-agent": "^5.0.0",
|
||||||
|
"mime-types": "^2.1.27",
|
||||||
|
"sanitize-filename": "^1.6.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/npm-run-path": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"path-key": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/onetime": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mimic-fn": "^2.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-key": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/q": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
|
||||||
|
"deprecated": "You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.\n\n(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6.0",
|
||||||
|
"teleport": ">=0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/queue-microtask": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||||
|
"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/reusify": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"iojs": ">=1.0.0",
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/run-parallel": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||||
|
"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",
|
||||||
|
"dependencies": {
|
||||||
|
"queue-microtask": "^1.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/sanitize-filename": {
|
||||||
|
"version": "1.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
|
||||||
|
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
|
||||||
|
"license": "WTFPL OR ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"truncate-utf8-bytes": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "5.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
|
||||||
|
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||||
|
"license": "ISC",
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-command": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"shebang-regex": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shebang-regex": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/shelljs": {
|
||||||
|
"version": "0.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.10.0.tgz",
|
||||||
|
"integrity": "sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"execa": "^5.1.1",
|
||||||
|
"fast-glob": "^3.3.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/signal-exit": {
|
||||||
|
"version": "3.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||||
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/strip-final-newline": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/truncate-utf8-bytes": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
|
||||||
|
"license": "WTFPL",
|
||||||
|
"dependencies": {
|
||||||
|
"utf8-byte-length": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/utf8-byte-length": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
|
||||||
|
"license": "(WTFPL OR MIT)"
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||||
|
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/which": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"isexe": "^2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"node-which": "bin/node-which"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
task/SetupGitHubRelease/package.json
Normal file
23
task/SetupGitHubRelease/package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "setup-github-release-task",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"author": "Slawomir Koszewski",
|
||||||
|
"license": "MIT",
|
||||||
|
"description": "Azure DevOps task to download and install the latest release asset from GitHub.",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc -p tsconfig.json",
|
||||||
|
"clean": "rm -rf dist"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"azure-pipelines-task-lib": "^5.2.6"
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"minimatch": "3.1.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.11.30",
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
430
task/SetupGitHubRelease/src/index.ts
Normal file
430
task/SetupGitHubRelease/src/index.ts
Normal file
@@ -0,0 +1,430 @@
|
|||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as fsp from 'node:fs/promises';
|
||||||
|
import * as os from 'node:os';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
import { spawnSync } from 'node:child_process';
|
||||||
|
import * as tl from 'azure-pipelines-task-lib/task';
|
||||||
|
|
||||||
|
type ReleaseAsset = {
|
||||||
|
name: string;
|
||||||
|
browser_download_url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ReleaseInfo = {
|
||||||
|
tag_name: string;
|
||||||
|
assets: ReleaseAsset[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type PlatformInfo = {
|
||||||
|
system: string;
|
||||||
|
arch: string;
|
||||||
|
systemPattern: string;
|
||||||
|
archPattern: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type MatchOptions = {
|
||||||
|
fileName?: string;
|
||||||
|
fileType?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const systemPatterns: Record<string, string> = {
|
||||||
|
linux: 'linux',
|
||||||
|
darwin: '(darwin|macos|mac|osx)',
|
||||||
|
win32: '(windows|win)'
|
||||||
|
};
|
||||||
|
|
||||||
|
const archPatterns: Record<string, string> = {
|
||||||
|
x64: '(x86_64|x64|amd64)',
|
||||||
|
arm64: '(aarch64|arm64)'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getPlatformInfo(): PlatformInfo {
|
||||||
|
const system = os.platform();
|
||||||
|
const arch = os.arch();
|
||||||
|
|
||||||
|
return {
|
||||||
|
system,
|
||||||
|
arch,
|
||||||
|
systemPattern: systemPatterns[system] || system,
|
||||||
|
archPattern: archPatterns[arch] || arch
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExtensionPattern(fileType: string): string {
|
||||||
|
if (fileType === 'archive') {
|
||||||
|
return '\\.(zip|tar\\.gz|tar|tgz|7z)';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileType === 'package') {
|
||||||
|
return '\\.(deb|rpm|pkg)';
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMatchingAsset(assets: ReleaseAsset[], platform: PlatformInfo, options: MatchOptions): ReleaseAsset {
|
||||||
|
const fileName = options.fileName;
|
||||||
|
const extPattern = getExtensionPattern(options.fileType || 'archive');
|
||||||
|
|
||||||
|
if (!fileName) {
|
||||||
|
const pattern = `${platform.systemPattern}[_-]${platform.archPattern}.*${extPattern}$`;
|
||||||
|
const regex = new RegExp(pattern, 'i');
|
||||||
|
const matches = assets.filter((asset) => regex.test(asset.name));
|
||||||
|
if (matches.length === 0) {
|
||||||
|
throw new Error(`No assets matched the default criteria: ${pattern}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches.length > 1) {
|
||||||
|
throw new Error(`Multiple assets matched the default criteria: ${matches.map((asset) => asset.name).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileName.startsWith('~')) {
|
||||||
|
let pattern = fileName.substring(1);
|
||||||
|
const hasSystem = pattern.includes('{{SYSTEM}}');
|
||||||
|
const hasArch = pattern.includes('{{ARCH}}');
|
||||||
|
const hasExt = pattern.includes('{{EXT_PATTERN}}');
|
||||||
|
const hasEnd = pattern.endsWith('$');
|
||||||
|
|
||||||
|
if (!hasSystem && !hasArch && !hasExt && !hasEnd) {
|
||||||
|
pattern += '.*{{SYSTEM}}[_-]{{ARCH}}.*{{EXT_PATTERN}}$';
|
||||||
|
} else if (hasSystem && hasArch && !hasExt && !hasEnd) {
|
||||||
|
pattern += '.*{{EXT_PATTERN}}$';
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalPattern = pattern
|
||||||
|
.replace(/{{SYSTEM}}/g, platform.systemPattern)
|
||||||
|
.replace(/{{ARCH}}/g, platform.archPattern)
|
||||||
|
.replace(/{{EXT_PATTERN}}/g, extPattern);
|
||||||
|
|
||||||
|
const regex = new RegExp(finalPattern, 'i');
|
||||||
|
const matches = assets.filter((asset) => regex.test(asset.name));
|
||||||
|
if (matches.length === 0) {
|
||||||
|
throw new Error(`No assets matched the regex: ${finalPattern}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches.length > 1) {
|
||||||
|
throw new Error(`Multiple assets matched the criteria: ${matches.map((asset) => asset.name).join(', ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const exact = assets.find((asset) => asset.name === fileName);
|
||||||
|
if (!exact) {
|
||||||
|
throw new Error(`No asset found matching the exact name: ${fileName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchLatestRelease(repository: string, token?: string): Promise<ReleaseInfo> {
|
||||||
|
const url = `https://api.github.com/repos/${repository}/releases/latest`;
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
Accept: 'application/vnd.github.v3+json',
|
||||||
|
'User-Agent': 'setup-github-release-ado-task'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
headers.Authorization = `token ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(url, { headers });
|
||||||
|
if (!response.ok) {
|
||||||
|
const body = await response.text();
|
||||||
|
throw new Error(`Failed to fetch latest release for ${repository}: ${response.status} ${response.statusText}. ${body}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (await response.json()) as ReleaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadAsset(url: string, destinationPath: string, token?: string): Promise<void> {
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
'User-Agent': 'setup-github-release-ado-task'
|
||||||
|
};
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
headers.Authorization = `token ${token}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(url, { headers });
|
||||||
|
if (!response.ok) {
|
||||||
|
const body = await response.text();
|
||||||
|
throw new Error(`Failed to download asset from ${url}: ${response.status} ${response.statusText}. ${body}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
await fsp.writeFile(destinationPath, Buffer.from(arrayBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function extractAsset(filePath: string, destinationDirectory: string): Promise<void> {
|
||||||
|
const lowerName = path.basename(filePath).toLowerCase();
|
||||||
|
|
||||||
|
await fsp.mkdir(destinationDirectory, { recursive: true });
|
||||||
|
|
||||||
|
if (lowerName.endsWith('.tar.gz') || lowerName.endsWith('.tgz') || lowerName.endsWith('.tar')) {
|
||||||
|
const result = spawnSync('tar', ['-xf', filePath, '-C', destinationDirectory]);
|
||||||
|
if (result.status !== 0) {
|
||||||
|
throw new Error(`tar failed with status ${result.status}: ${result.stderr.toString()}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowerName.endsWith('.zip')) {
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
const tarResult = spawnSync('tar', ['-xf', filePath, '-C', destinationDirectory]);
|
||||||
|
if (tarResult.status === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const escapedFilePath = filePath.replace(/'/g, "''");
|
||||||
|
const escapedDestinationDirectory = destinationDirectory.replace(/'/g, "''");
|
||||||
|
const command = `Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFilePath}', '${escapedDestinationDirectory}')`;
|
||||||
|
|
||||||
|
for (const shell of ['pwsh', 'powershell']) {
|
||||||
|
const result = spawnSync(shell, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', command]);
|
||||||
|
if (result.status === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('ZIP extraction failed on Windows.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const unzipResult = spawnSync('unzip', ['-q', filePath, '-d', destinationDirectory]);
|
||||||
|
if (unzipResult.status !== 0) {
|
||||||
|
throw new Error(`unzip failed with status ${unzipResult.status}: ${unzipResult.stderr.toString()}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowerName.endsWith('.7z')) {
|
||||||
|
const sevenZipResult = spawnSync('7z', ['x', filePath, `-o${destinationDirectory}`, '-y']);
|
||||||
|
if (sevenZipResult.status !== 0) {
|
||||||
|
throw new Error(`7z failed with status ${sevenZipResult.status}: ${sevenZipResult.stderr.toString()}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowerName.endsWith('.pkg') || lowerName.endsWith('.xar')) {
|
||||||
|
const xarResult = spawnSync('xar', ['-xf', filePath], { cwd: destinationDirectory });
|
||||||
|
if (xarResult.status !== 0) {
|
||||||
|
throw new Error(`xar failed with status ${xarResult.status}: ${xarResult.stderr.toString()}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const destinationPath = path.join(destinationDirectory, path.basename(filePath));
|
||||||
|
await fsp.copyFile(filePath, destinationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findBinary(directory: string, pattern: string | RegExp, debug: boolean): string | undefined {
|
||||||
|
const items = fs.readdirSync(directory);
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
tl.debug(`Searching for binary in ${directory}`);
|
||||||
|
for (const item of items) {
|
||||||
|
tl.debug(`- ${item}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
const fullPath = path.join(directory, item);
|
||||||
|
const stat = fs.statSync(fullPath);
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
const nested = findBinary(fullPath, pattern, debug);
|
||||||
|
if (nested) {
|
||||||
|
return nested;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let match = false;
|
||||||
|
if (pattern instanceof RegExp) {
|
||||||
|
match = pattern.test(item);
|
||||||
|
} else {
|
||||||
|
match = item === pattern;
|
||||||
|
if (!match && process.platform === 'win32' && !pattern.toLowerCase().endsWith('.exe')) {
|
||||||
|
match = item.toLowerCase() === `${pattern.toLowerCase()}.exe`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyDirectory(sourceDirectory: string, destinationDirectory: string): Promise<void> {
|
||||||
|
await fsp.mkdir(destinationDirectory, { recursive: true });
|
||||||
|
const entries = await fsp.readdir(sourceDirectory, { withFileTypes: true });
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const sourcePath = path.join(sourceDirectory, entry.name);
|
||||||
|
const destinationPath = path.join(destinationDirectory, entry.name);
|
||||||
|
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
await copyDirectory(sourcePath, destinationPath);
|
||||||
|
} else if (entry.isSymbolicLink()) {
|
||||||
|
const linkTarget = await fsp.readlink(sourcePath);
|
||||||
|
await fsp.symlink(linkTarget, destinationPath);
|
||||||
|
} else {
|
||||||
|
await fsp.copyFile(sourcePath, destinationPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getToolsRoot(): string {
|
||||||
|
const toolsDirectory = tl.getVariable('Agent.ToolsDirectory');
|
||||||
|
if (toolsDirectory !== undefined) {
|
||||||
|
return toolsDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.join(os.homedir(), '.ado-sk-tools');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findAnyCachedVersion(toolName: string, arch: string): Promise<{ version: string; toolDirectory: string } | undefined> {
|
||||||
|
const archRoot = path.join(getToolsRoot(), toolName);
|
||||||
|
if (!fs.existsSync(archRoot)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const entries = await fsp.readdir(archRoot, { withFileTypes: true });
|
||||||
|
const versions = entries
|
||||||
|
.filter((entry) => entry.isDirectory())
|
||||||
|
.map((entry) => entry.name)
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
for (let index = versions.length - 1; index >= 0; index -= 1) {
|
||||||
|
const version = versions[index];
|
||||||
|
const candidate = path.join(archRoot, version, arch);
|
||||||
|
if (fs.existsSync(candidate)) {
|
||||||
|
return {
|
||||||
|
version,
|
||||||
|
toolDirectory: candidate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSpecificCacheDirectory(toolName: string, version: string, arch: string): string {
|
||||||
|
return path.join(getToolsRoot(), toolName, version, arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cacheTool(sourceDirectory: string, toolName: string, version: string, arch: string): Promise<string> {
|
||||||
|
const destinationDirectory = getSpecificCacheDirectory(toolName, version, arch);
|
||||||
|
await fsp.rm(destinationDirectory, { recursive: true, force: true });
|
||||||
|
await copyDirectory(sourceDirectory, destinationDirectory);
|
||||||
|
return destinationDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setExecutable(filePath: string): void {
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
fs.chmodSync(filePath, 0o755);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const repository = tl.getInputRequired('repository');
|
||||||
|
const fileNameInput = tl.getInput('fileName', false) || '';
|
||||||
|
const binaryInput = tl.getInput('binaryName', false) || '';
|
||||||
|
const fileType = tl.getInput('fileType', false) || 'archive';
|
||||||
|
const updateCache = (tl.getInput('updateCache', false) || 'false').toLowerCase();
|
||||||
|
const debug = tl.getBoolInput('debug', false);
|
||||||
|
const token = tl.getInput('token', false) || process.env.GITHUB_TOKEN;
|
||||||
|
|
||||||
|
if (!/^[^/\s]+\/[^/\s]+$/.test(repository)) {
|
||||||
|
throw new Error('Input repository must be in owner/repo format.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!['false', 'true', 'always'].includes(updateCache)) {
|
||||||
|
throw new Error('Input updateCache must be one of: false, true, always.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const platformInfo = getPlatformInfo();
|
||||||
|
const toolName = repository.split('/').pop() || repository;
|
||||||
|
|
||||||
|
if (updateCache === 'false') {
|
||||||
|
const cached = await findAnyCachedVersion(toolName, platformInfo.arch);
|
||||||
|
if (cached) {
|
||||||
|
tl.debug(`Using cached ${toolName} version ${cached.version}`);
|
||||||
|
tl.prependPath(cached.toolDirectory);
|
||||||
|
tl.setResult(tl.TaskResult.Succeeded, `Using cached ${toolName} version ${cached.version}.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tl.debug(`Fetching latest release for ${repository}`);
|
||||||
|
const release = await fetchLatestRelease(repository, token);
|
||||||
|
const asset = getMatchingAsset(release.assets, platformInfo, {
|
||||||
|
fileName: fileNameInput,
|
||||||
|
fileType
|
||||||
|
});
|
||||||
|
|
||||||
|
const version = release.tag_name.replace(/^v/, '');
|
||||||
|
const binaryName = binaryInput || toolName;
|
||||||
|
|
||||||
|
if (updateCache !== 'always') {
|
||||||
|
const cachedDirectory = getSpecificCacheDirectory(toolName, version, platformInfo.arch);
|
||||||
|
if (fs.existsSync(cachedDirectory)) {
|
||||||
|
tl.debug(`Using cached ${toolName} version ${version}`);
|
||||||
|
tl.prependPath(cachedDirectory);
|
||||||
|
tl.setResult(tl.TaskResult.Succeeded, `Using cached ${toolName} version ${version}.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'setup-github-release-'));
|
||||||
|
const downloadPath = path.join(tempRoot, asset.name);
|
||||||
|
|
||||||
|
tl.debug(`Downloading asset ${asset.name}`);
|
||||||
|
await downloadAsset(asset.browser_download_url, downloadPath, token);
|
||||||
|
|
||||||
|
let extractionRoot = path.join(tempRoot, 'extract');
|
||||||
|
const lowerName = asset.name.toLowerCase();
|
||||||
|
|
||||||
|
if (
|
||||||
|
/\.(tar\.gz|tar|tgz)$/i.test(lowerName) ||
|
||||||
|
/\.zip$/i.test(lowerName) ||
|
||||||
|
/\.7z$/i.test(lowerName) ||
|
||||||
|
/\.(xar|pkg)$/i.test(lowerName)
|
||||||
|
) {
|
||||||
|
await extractAsset(downloadPath, extractionRoot);
|
||||||
|
} else {
|
||||||
|
extractionRoot = path.join(tempRoot, 'bin');
|
||||||
|
await fsp.mkdir(extractionRoot, { recursive: true });
|
||||||
|
const destinationPath = path.join(extractionRoot, asset.name);
|
||||||
|
await fsp.rename(downloadPath, destinationPath);
|
||||||
|
setExecutable(destinationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const binaryPattern = binaryName.startsWith('~')
|
||||||
|
? new RegExp(binaryName.substring(1), 'i')
|
||||||
|
: binaryName;
|
||||||
|
|
||||||
|
const binaryPath = findBinary(extractionRoot, binaryPattern, debug);
|
||||||
|
if (!binaryPath) {
|
||||||
|
throw new Error(`Could not find binary ${binaryName} in extracted asset.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
setExecutable(binaryPath);
|
||||||
|
|
||||||
|
const binaryDirectory = path.dirname(binaryPath);
|
||||||
|
const cachedDirectory = await cacheTool(binaryDirectory, toolName, version, platformInfo.arch);
|
||||||
|
|
||||||
|
tl.prependPath(cachedDirectory);
|
||||||
|
tl.setResult(tl.TaskResult.Succeeded, `Installed ${toolName} ${version} from ${repository}.`);
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
|
tl.setResult(tl.TaskResult.Failed, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run();
|
||||||
85
task/SetupGitHubRelease/task.json
Normal file
85
task/SetupGitHubRelease/task.json
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json",
|
||||||
|
"id": "950311ab-f037-4f4f-a875-8a4251e2dbd5",
|
||||||
|
"name": "SetupGitHubRelease",
|
||||||
|
"friendlyName": "Setup GitHub Release",
|
||||||
|
"description": "Downloads and installs a binary from the latest GitHub release and adds it to PATH.",
|
||||||
|
"helpMarkDown": "Matches release assets by platform and architecture, downloads, extracts, locates the binary, caches it, and prepends its directory to PATH.",
|
||||||
|
"category": "Utility",
|
||||||
|
"author": "Slawomir Koszewski",
|
||||||
|
"version": {
|
||||||
|
"Major": 1,
|
||||||
|
"Minor": 0,
|
||||||
|
"Patch": 0
|
||||||
|
},
|
||||||
|
"instanceNameFormat": "Setup GitHub release from $(repository)",
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "repository",
|
||||||
|
"type": "string",
|
||||||
|
"label": "Repository",
|
||||||
|
"defaultValue": "",
|
||||||
|
"required": true,
|
||||||
|
"helpMarkDown": "GitHub repository in owner/repo format."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fileName",
|
||||||
|
"type": "string",
|
||||||
|
"label": "File Name",
|
||||||
|
"defaultValue": "",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "Asset name or regex prefixed with ~."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "binaryName",
|
||||||
|
"type": "string",
|
||||||
|
"label": "Binary Name",
|
||||||
|
"defaultValue": "",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "Binary name or regex prefixed with ~. Defaults to repository name."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fileType",
|
||||||
|
"type": "string",
|
||||||
|
"label": "File Type",
|
||||||
|
"defaultValue": "archive",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "archive, package, or custom regex pattern for file extension matching."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "updateCache",
|
||||||
|
"type": "pickList",
|
||||||
|
"label": "Update Cache",
|
||||||
|
"defaultValue": "false",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "false: use any cached version. true: use current latest release and cache if needed. always: always download latest and refresh cache.",
|
||||||
|
"options": {
|
||||||
|
"false": "false",
|
||||||
|
"true": "true",
|
||||||
|
"always": "always"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"type": "boolean",
|
||||||
|
"label": "Debug",
|
||||||
|
"defaultValue": "false",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "Logs discovered files while searching for the binary."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "token",
|
||||||
|
"type": "string",
|
||||||
|
"label": "GitHub Token",
|
||||||
|
"defaultValue": "",
|
||||||
|
"required": false,
|
||||||
|
"helpMarkDown": "Optional GitHub token for private repos or higher API limits. If empty, uses GITHUB_TOKEN if available."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"execution": {
|
||||||
|
"Node20_1": {
|
||||||
|
"target": "dist/SetupGitHubRelease/src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimumAgentVersion": "3.225.0"
|
||||||
|
}
|
||||||
14
task/SetupGitHubRelease/tsconfig.json
Normal file
14
task/SetupGitHubRelease/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "CommonJS",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": ".."
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user