mirror of
				https://github.com/trympet/nextcloud-artifacts-action.git
				synced 2025-10-30 01:36:41 +01:00 
			
		
		
		
	add nextcloud support
This commit is contained in:
		
							
								
								
									
										449
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										449
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -9,11 +9,460 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.3.0.tgz", |       "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.3.0.tgz", | ||||||
|       "integrity": "sha512-xxtX0Cwdhb8LcgatfJkokqT8KzPvcIbwL9xpLU09nOwBzaStbfm0dNncsP0M4us+EpoPdWy7vbzU5vSOH7K6pg==" |       "integrity": "sha512-xxtX0Cwdhb8LcgatfJkokqT8KzPvcIbwL9xpLU09nOwBzaStbfm0dNncsP0M4us+EpoPdWy7vbzU5vSOH7K6pg==" | ||||||
|     }, |     }, | ||||||
|  |     "@actions/glob": { | ||||||
|  |       "version": "0.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.1.2.tgz", | ||||||
|  |       "integrity": "sha512-SclLR7Ia5sEqjkJTPs7Sd86maMDw43p769YxBOxvPvEWuPEhpAnBsQfENOpXjFYMmhCqd127bmf+YdvJqVqR4A==", | ||||||
|  |       "requires": { | ||||||
|  |         "@actions/core": "^1.2.6", | ||||||
|  |         "minimatch": "^3.0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@types/archiver": { | ||||||
|  |       "version": "5.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-5.1.0.tgz", | ||||||
|  |       "integrity": "sha512-baFOhanb/hxmcOd1Uey2TfFg43kTSmM6py1Eo7Rjbv/ivcl7PXLhY0QgXGf50Hx/eskGCFqPfhs/7IZLb15C5g==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "@types/glob": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@types/glob": { | ||||||
|  |       "version": "7.1.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", | ||||||
|  |       "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "@types/minimatch": "*", | ||||||
|  |         "@types/node": "*" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "@types/minimatch": { | ||||||
|  |       "version": "3.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", | ||||||
|  |       "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "@types/node": { | ||||||
|  |       "version": "15.6.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.2.tgz", | ||||||
|  |       "integrity": "sha512-dxcOx8801kMo3KlU+C+/ctWrzREAH7YvoF3aoVpRdqgs+Kf7flp+PJDN/EX5bME3suDUZHsxes9hpvBmzYlWbA==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "@types/node-fetch": { | ||||||
|  |       "version": "2.5.10", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz", | ||||||
|  |       "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "@types/node": "*", | ||||||
|  |         "form-data": "^3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "archiver": { | ||||||
|  |       "version": "5.3.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", | ||||||
|  |       "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", | ||||||
|  |       "requires": { | ||||||
|  |         "archiver-utils": "^2.1.0", | ||||||
|  |         "async": "^3.2.0", | ||||||
|  |         "buffer-crc32": "^0.2.1", | ||||||
|  |         "readable-stream": "^3.6.0", | ||||||
|  |         "readdir-glob": "^1.0.0", | ||||||
|  |         "tar-stream": "^2.2.0", | ||||||
|  |         "zip-stream": "^4.1.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "archiver-utils": { | ||||||
|  |       "version": "2.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", | ||||||
|  |       "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", | ||||||
|  |       "requires": { | ||||||
|  |         "glob": "^7.1.4", | ||||||
|  |         "graceful-fs": "^4.2.0", | ||||||
|  |         "lazystream": "^1.0.0", | ||||||
|  |         "lodash.defaults": "^4.2.0", | ||||||
|  |         "lodash.difference": "^4.5.0", | ||||||
|  |         "lodash.flatten": "^4.4.0", | ||||||
|  |         "lodash.isplainobject": "^4.0.6", | ||||||
|  |         "lodash.union": "^4.6.0", | ||||||
|  |         "normalize-path": "^3.0.0", | ||||||
|  |         "readable-stream": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "readable-stream": { | ||||||
|  |           "version": "2.3.7", | ||||||
|  |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", | ||||||
|  |           "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", | ||||||
|  |           "requires": { | ||||||
|  |             "core-util-is": "~1.0.0", | ||||||
|  |             "inherits": "~2.0.3", | ||||||
|  |             "isarray": "~1.0.0", | ||||||
|  |             "process-nextick-args": "~2.0.0", | ||||||
|  |             "safe-buffer": "~5.1.1", | ||||||
|  |             "string_decoder": "~1.1.1", | ||||||
|  |             "util-deprecate": "~1.0.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "async": { | ||||||
|  |       "version": "3.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", | ||||||
|  |       "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" | ||||||
|  |     }, | ||||||
|  |     "asynckit": { | ||||||
|  |       "version": "0.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", | ||||||
|  |       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "balanced-match": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||||||
|  |       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" | ||||||
|  |     }, | ||||||
|  |     "base64-js": { | ||||||
|  |       "version": "1.5.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", | ||||||
|  |       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" | ||||||
|  |     }, | ||||||
|  |     "bl": { | ||||||
|  |       "version": "4.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", | ||||||
|  |       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", | ||||||
|  |       "requires": { | ||||||
|  |         "buffer": "^5.5.0", | ||||||
|  |         "inherits": "^2.0.4", | ||||||
|  |         "readable-stream": "^3.4.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "brace-expansion": { | ||||||
|  |       "version": "1.1.11", | ||||||
|  |       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", | ||||||
|  |       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", | ||||||
|  |       "requires": { | ||||||
|  |         "balanced-match": "^1.0.0", | ||||||
|  |         "concat-map": "0.0.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "buffer": { | ||||||
|  |       "version": "5.7.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", | ||||||
|  |       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "base64-js": "^1.3.1", | ||||||
|  |         "ieee754": "^1.1.13" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "buffer-crc32": { | ||||||
|  |       "version": "0.2.13", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", | ||||||
|  |       "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" | ||||||
|  |     }, | ||||||
|  |     "combined-stream": { | ||||||
|  |       "version": "1.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", | ||||||
|  |       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "delayed-stream": "~1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "compress-commons": { | ||||||
|  |       "version": "4.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", | ||||||
|  |       "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "buffer-crc32": "^0.2.13", | ||||||
|  |         "crc32-stream": "^4.0.2", | ||||||
|  |         "normalize-path": "^3.0.0", | ||||||
|  |         "readable-stream": "^3.6.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "concat-map": { | ||||||
|  |       "version": "0.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
|  |       "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||||||
|  |     }, | ||||||
|  |     "core-util-is": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", | ||||||
|  |       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" | ||||||
|  |     }, | ||||||
|  |     "crc-32": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", | ||||||
|  |       "requires": { | ||||||
|  |         "exit-on-epipe": "~1.0.1", | ||||||
|  |         "printj": "~1.1.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "crc32-stream": { | ||||||
|  |       "version": "4.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", | ||||||
|  |       "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", | ||||||
|  |       "requires": { | ||||||
|  |         "crc-32": "^1.2.0", | ||||||
|  |         "readable-stream": "^3.4.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "delayed-stream": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "end-of-stream": { | ||||||
|  |       "version": "1.4.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", | ||||||
|  |       "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", | ||||||
|  |       "requires": { | ||||||
|  |         "once": "^1.4.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "exit-on-epipe": { | ||||||
|  |       "version": "1.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", | ||||||
|  |       "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" | ||||||
|  |     }, | ||||||
|  |     "form-data": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "asynckit": "^0.4.0", | ||||||
|  |         "combined-stream": "^1.0.8", | ||||||
|  |         "mime-types": "^2.1.12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "fs-constants": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", | ||||||
|  |       "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" | ||||||
|  |     }, | ||||||
|  |     "fs.realpath": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" | ||||||
|  |     }, | ||||||
|  |     "glob": { | ||||||
|  |       "version": "7.1.7", | ||||||
|  |       "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", | ||||||
|  |       "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "fs.realpath": "^1.0.0", | ||||||
|  |         "inflight": "^1.0.4", | ||||||
|  |         "inherits": "2", | ||||||
|  |         "minimatch": "^3.0.4", | ||||||
|  |         "once": "^1.3.0", | ||||||
|  |         "path-is-absolute": "^1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "graceful-fs": { | ||||||
|  |       "version": "4.2.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", | ||||||
|  |       "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" | ||||||
|  |     }, | ||||||
|  |     "ieee754": { | ||||||
|  |       "version": "1.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", | ||||||
|  |       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" | ||||||
|  |     }, | ||||||
|  |     "inflight": { | ||||||
|  |       "version": "1.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", | ||||||
|  |       "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", | ||||||
|  |       "requires": { | ||||||
|  |         "once": "^1.3.0", | ||||||
|  |         "wrappy": "1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "inherits": { | ||||||
|  |       "version": "2.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", | ||||||
|  |       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" | ||||||
|  |     }, | ||||||
|  |     "isarray": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | ||||||
|  |     }, | ||||||
|  |     "lazystream": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", | ||||||
|  |       "requires": { | ||||||
|  |         "readable-stream": "^2.0.5" | ||||||
|  |       }, | ||||||
|  |       "dependencies": { | ||||||
|  |         "readable-stream": { | ||||||
|  |           "version": "2.3.7", | ||||||
|  |           "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", | ||||||
|  |           "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", | ||||||
|  |           "requires": { | ||||||
|  |             "core-util-is": "~1.0.0", | ||||||
|  |             "inherits": "~2.0.3", | ||||||
|  |             "isarray": "~1.0.0", | ||||||
|  |             "process-nextick-args": "~2.0.0", | ||||||
|  |             "safe-buffer": "~5.1.1", | ||||||
|  |             "string_decoder": "~1.1.1", | ||||||
|  |             "util-deprecate": "~1.0.1" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "lodash.defaults": { | ||||||
|  |       "version": "4.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", | ||||||
|  |       "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" | ||||||
|  |     }, | ||||||
|  |     "lodash.difference": { | ||||||
|  |       "version": "4.5.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", | ||||||
|  |       "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" | ||||||
|  |     }, | ||||||
|  |     "lodash.flatten": { | ||||||
|  |       "version": "4.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", | ||||||
|  |       "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" | ||||||
|  |     }, | ||||||
|  |     "lodash.isplainobject": { | ||||||
|  |       "version": "4.0.6", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", | ||||||
|  |       "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" | ||||||
|  |     }, | ||||||
|  |     "lodash.union": { | ||||||
|  |       "version": "4.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", | ||||||
|  |       "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" | ||||||
|  |     }, | ||||||
|  |     "mime-db": { | ||||||
|  |       "version": "1.48.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", | ||||||
|  |       "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "mime-types": { | ||||||
|  |       "version": "2.1.31", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", | ||||||
|  |       "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "mime-db": "1.48.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "minimatch": { | ||||||
|  |       "version": "3.0.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||||||
|  |       "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", | ||||||
|  |       "requires": { | ||||||
|  |         "brace-expansion": "^1.1.7" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node-fetch": { | ||||||
|  |       "version": "2.6.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", | ||||||
|  |       "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" | ||||||
|  |     }, | ||||||
|  |     "normalize-path": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" | ||||||
|  |     }, | ||||||
|  |     "once": { | ||||||
|  |       "version": "1.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", | ||||||
|  |       "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", | ||||||
|  |       "requires": { | ||||||
|  |         "wrappy": "1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "path-is-absolute": { | ||||||
|  |       "version": "1.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", | ||||||
|  |       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" | ||||||
|  |     }, | ||||||
|  |     "printj": { | ||||||
|  |       "version": "1.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", | ||||||
|  |       "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" | ||||||
|  |     }, | ||||||
|  |     "process-nextick-args": { | ||||||
|  |       "version": "2.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", | ||||||
|  |       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" | ||||||
|  |     }, | ||||||
|  |     "readable-stream": { | ||||||
|  |       "version": "3.6.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", | ||||||
|  |       "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", | ||||||
|  |       "requires": { | ||||||
|  |         "inherits": "^2.0.3", | ||||||
|  |         "string_decoder": "^1.1.1", | ||||||
|  |         "util-deprecate": "^1.0.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "readdir-glob": { | ||||||
|  |       "version": "1.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", | ||||||
|  |       "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", | ||||||
|  |       "requires": { | ||||||
|  |         "minimatch": "^3.0.4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "safe-buffer": { | ||||||
|  |       "version": "5.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", | ||||||
|  |       "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" | ||||||
|  |     }, | ||||||
|  |     "string_decoder": { | ||||||
|  |       "version": "1.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", | ||||||
|  |       "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", | ||||||
|  |       "requires": { | ||||||
|  |         "safe-buffer": "~5.1.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "tar-stream": { | ||||||
|  |       "version": "2.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", | ||||||
|  |       "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "bl": "^4.0.3", | ||||||
|  |         "end-of-stream": "^1.4.1", | ||||||
|  |         "fs-constants": "^1.0.0", | ||||||
|  |         "inherits": "^2.0.3", | ||||||
|  |         "readable-stream": "^3.1.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "typescript": { |     "typescript": { | ||||||
|       "version": "4.3.2", |       "version": "4.3.2", | ||||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", |       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", | ||||||
|       "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", |       "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", | ||||||
|       "dev": true |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "util-deprecate": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", | ||||||
|  |       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" | ||||||
|  |     }, | ||||||
|  |     "wrappy": { | ||||||
|  |       "version": "1.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", | ||||||
|  |       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" | ||||||
|  |     }, | ||||||
|  |     "zip-stream": { | ||||||
|  |       "version": "4.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", | ||||||
|  |       "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", | ||||||
|  |       "requires": { | ||||||
|  |         "archiver-utils": "^2.1.0", | ||||||
|  |         "compress-commons": "^4.1.0", | ||||||
|  |         "readable-stream": "^3.6.0" | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,9 +18,15 @@ | |||||||
|   }, |   }, | ||||||
|   "homepage": "https://github.com/trympet/nextcloud-artifacts-action#readme", |   "homepage": "https://github.com/trympet/nextcloud-artifacts-action#readme", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@actions/core": "^1.3.0" |     "@actions/core": "^1.3.0", | ||||||
|  |     "@actions/glob": "^0.1.2", | ||||||
|  |     "archiver": "^5.3.0", | ||||||
|  |     "node-fetch": "^2.6.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@types/archiver": "^5.1.0", | ||||||
|  |     "@types/node": "^15.6.2", | ||||||
|  |     "@types/node-fetch": "^2.5.10", | ||||||
|     "typescript": "^4.3.2" |     "typescript": "^4.3.2" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										146
									
								
								src/FileFinder.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								src/FileFinder.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | |||||||
|  | import * as glob from '@actions/glob' | ||||||
|  | import {stat} from 'fs' | ||||||
|  | import {debug, info} from '@actions/core' | ||||||
|  | import * as path from 'path' | ||||||
|  | import {promisify} from 'util' | ||||||
|  | const stats = promisify(stat) | ||||||
|  |  | ||||||
|  | export class FileFinder { | ||||||
|  |     private static DefaultGlobOptions: glob.GlobOptions = { | ||||||
|  |         followSymbolicLinks: true, | ||||||
|  |         implicitDescendants: true, | ||||||
|  |         omitBrokenSymbolicLinks: true | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private globOptions: glob.GlobOptions | ||||||
|  |  | ||||||
|  |     public constructor(private searchPath: string, globOptions?: glob.GlobOptions) { | ||||||
|  |         this.globOptions = globOptions || FileFinder.DefaultGlobOptions; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async findFiles() { | ||||||
|  |         const searchResults: string[] = [] | ||||||
|  |         const globber = await glob.create( | ||||||
|  |             this.searchPath, | ||||||
|  |             this.globOptions | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         const rawSearchResults: string[] = await globber.glob() | ||||||
|  |  | ||||||
|  |         /* | ||||||
|  |           Files are saved with case insensitivity. Uploading both a.txt and A.txt will files to be overwritten | ||||||
|  |           Detect any files that could be overwritten for user awareness | ||||||
|  |         */ | ||||||
|  |         const set = new Set<string>() | ||||||
|  |  | ||||||
|  |         /* | ||||||
|  |           Directories will be rejected if attempted to be uploaded. This includes just empty | ||||||
|  |           directories so filter any directories out from the raw search results | ||||||
|  |         */ | ||||||
|  |         for (const searchResult of rawSearchResults) { | ||||||
|  |             const fileStats = await stats(searchResult) | ||||||
|  |             // isDirectory() returns false for symlinks if using fs.lstat(), make sure to use fs.stat() instead | ||||||
|  |             if (!fileStats.isDirectory()) { | ||||||
|  |                 debug(`File:${searchResult} was found using the provided searchPath`) | ||||||
|  |                 searchResults.push(searchResult) | ||||||
|  |  | ||||||
|  |                 // detect any files that would be overwritten because of case insensitivity | ||||||
|  |                 if (set.has(searchResult.toLowerCase())) { | ||||||
|  |                     info( | ||||||
|  |                         `Uploads are case insensitive: ${searchResult} was detected that it will be overwritten by another file with the same path` | ||||||
|  |                     ) | ||||||
|  |                 } else { | ||||||
|  |                     set.add(searchResult.toLowerCase()) | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 debug( | ||||||
|  |                     `Removing ${searchResult} from rawSearchResults because it is a directory` | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Calculate the root directory for the artifact using the search paths that were utilized | ||||||
|  |         const searchPaths: string[] = globber.getSearchPaths() | ||||||
|  |  | ||||||
|  |         if (searchPaths.length > 1) { | ||||||
|  |             info( | ||||||
|  |                 `Multiple search paths detected. Calculating the least common ancestor of all paths` | ||||||
|  |             ) | ||||||
|  |             const lcaSearchPath = this.getMultiPathLCA(searchPaths) | ||||||
|  |             info( | ||||||
|  |                 `The least common ancestor is ${lcaSearchPath}. This will be the root directory of the artifact` | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |             return { | ||||||
|  |                 filesToUpload: searchResults, | ||||||
|  |                 rootDirectory: lcaSearchPath | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /* | ||||||
|  |           Special case for a single file artifact that is uploaded without a directory or wildcard pattern. The directory structure is | ||||||
|  |           not preserved and the root directory will be the single files parent directory | ||||||
|  |         */ | ||||||
|  |         if (searchResults.length === 1 && searchPaths[0] === searchResults[0]) { | ||||||
|  |             return { | ||||||
|  |                 filesToUpload: searchResults, | ||||||
|  |                 rootDirectory: path.dirname(searchResults[0]) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return { | ||||||
|  |             filesToUpload: searchResults, | ||||||
|  |             rootDirectory: searchPaths[0] | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private getMultiPathLCA(searchPaths: string[]): string { | ||||||
|  |         if (searchPaths.length < 2) { | ||||||
|  |           throw new Error('At least two search paths must be provided') | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |         const commonPaths = new Array<string>() | ||||||
|  |         const splitPaths = new Array<string[]>() | ||||||
|  |         let smallestPathLength = Number.MAX_SAFE_INTEGER | ||||||
|  |        | ||||||
|  |         // split each of the search paths using the platform specific separator | ||||||
|  |         for (const searchPath of searchPaths) { | ||||||
|  |           debug(`Using search path ${searchPath}`) | ||||||
|  |        | ||||||
|  |           const splitSearchPath = path.normalize(searchPath).split(path.sep) | ||||||
|  |        | ||||||
|  |           // keep track of the smallest path length so that we don't accidentally later go out of bounds | ||||||
|  |           smallestPathLength = Math.min(smallestPathLength, splitSearchPath.length) | ||||||
|  |           splitPaths.push(splitSearchPath) | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |         // on Unix-like file systems, the file separator exists at the beginning of the file path, make sure to preserve it | ||||||
|  |         if (searchPaths[0].startsWith(path.sep)) { | ||||||
|  |           commonPaths.push(path.sep) | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |         let splitIndex = 0 | ||||||
|  |         // function to check if the paths are the same at a specific index | ||||||
|  |         function isPathTheSame(): boolean { | ||||||
|  |           const compare = splitPaths[0][splitIndex] | ||||||
|  |           for (let i = 1; i < splitPaths.length; i++) { | ||||||
|  |             if (compare !== splitPaths[i][splitIndex]) { | ||||||
|  |               // a non-common index has been reached | ||||||
|  |               return false | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |           return true | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |         // loop over all the search paths until there is a non-common ancestor or we go out of bounds | ||||||
|  |         while (splitIndex < smallestPathLength) { | ||||||
|  |           if (!isPathTheSame()) { | ||||||
|  |             break | ||||||
|  |           } | ||||||
|  |           // if all are the same, add to the end result & increment the index | ||||||
|  |           commonPaths.push(splitPaths[0][splitIndex]) | ||||||
|  |           splitIndex++ | ||||||
|  |         } | ||||||
|  |         return path.join(...commonPaths) | ||||||
|  |       } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								src/Inputs.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/Inputs.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | import core from '@actions/core'; | ||||||
|  | import { NoFileOption } from './NoFileOption'; | ||||||
|  |  | ||||||
|  | export class Inputs { | ||||||
|  |     static get ArtifactName(): string { | ||||||
|  |         return core.getInput("name"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get ArtifactPath(): string { | ||||||
|  |         return core.getInput("path"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get Retention(): string { | ||||||
|  |         return core.getInput("retention-days"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get Endpoint(): string { | ||||||
|  |         return core.getInput("retention-days"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static get NoFileBehvaior(): NoFileOption { | ||||||
|  |         const notFoundAction = core.getInput("if-no-files-found"); | ||||||
|  |         const noFileBehavior: NoFileOption = NoFileOption[notFoundAction as keyof typeof NoFileOption]; | ||||||
|  |  | ||||||
|  |         if (!noFileBehavior) { | ||||||
|  |             core.setFailed( | ||||||
|  |                 `Unrecognized ${"ifNoFilesFound"} input. Provided: ${notFoundAction}. Available options: ${Object.keys( | ||||||
|  |                     NoFileOption | ||||||
|  |                 )}` | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return noFileBehavior; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								src/NoFileOption.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/NoFileOption.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | export enum NoFileOption { | ||||||
|  |     /** | ||||||
|  |      * Default. Output a warning but do not fail the action | ||||||
|  |      */ | ||||||
|  |     warn = 'warn', | ||||||
|  |    | ||||||
|  |     /** | ||||||
|  |      * Fail the action with an error message | ||||||
|  |      */ | ||||||
|  |     error = 'error', | ||||||
|  |    | ||||||
|  |     /** | ||||||
|  |      * Do not output any warnings or errors, the action does not fail | ||||||
|  |      */ | ||||||
|  |     ignore = 'ignore', | ||||||
|  |   } | ||||||
| @@ -1 +1,5 @@ | |||||||
| console.log("hello world"); | import { Inputs } from './Inputs'; | ||||||
|  | import { NextcloudArtifact } from './nextcloud/NextcloudArtifact'; | ||||||
|  |  | ||||||
|  | var artifact = new NextcloudArtifact(Inputs.ArtifactName, Inputs.ArtifactPath, Inputs.NoFileBehvaior); | ||||||
|  | artifact.run(); | ||||||
							
								
								
									
										64
									
								
								src/nextcloud/NextcloudArtifact.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/nextcloud/NextcloudArtifact.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | import core from '@actions/core'; | ||||||
|  | import { FileFinder } from '../FileFinder'; | ||||||
|  | import { Inputs } from '../Inputs'; | ||||||
|  | import { NextcloudClient } from './NextcloudClient'; | ||||||
|  | import { NoFileOption } from '../NoFileOption'; | ||||||
|  |  | ||||||
|  | export class NextcloudArtifact { | ||||||
|  |     public constructor( | ||||||
|  |         private name: string, | ||||||
|  |         private path: string, | ||||||
|  |         private errorBehavior: NoFileOption) { } | ||||||
|  |  | ||||||
|  |     public async run() { | ||||||
|  |         const fileFinder = new FileFinder(this.path); | ||||||
|  |         const files = await fileFinder.findFiles(); | ||||||
|  |  | ||||||
|  |         if (files.filesToUpload.length > 0) { | ||||||
|  |             await this.uploadFiles(files); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             this.logNoFilesFound(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async uploadFiles(files: { filesToUpload: string[]; rootDirectory: string; }) { | ||||||
|  |         this.logUpload(files.filesToUpload.length, files.rootDirectory); | ||||||
|  |  | ||||||
|  |         const client = new NextcloudClient(Inputs.Endpoint, this.name, files.rootDirectory); | ||||||
|  |  | ||||||
|  |         await client.uploadFiles(files.filesToUpload); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private logUpload(fileCount: number, rootDirectory: string) { | ||||||
|  |         const s = fileCount === 1 ? '' : 's'; | ||||||
|  |         core.info( | ||||||
|  |             `With the provided path, there will be ${fileCount} file${s} uploaded` | ||||||
|  |         ); | ||||||
|  |         core.debug(`Root artifact directory is ${rootDirectory}`); | ||||||
|  |  | ||||||
|  |         if (fileCount > 10000) { | ||||||
|  |             core.warning( | ||||||
|  |                 `There are over 10,000 files in this artifact, consider create an archive before upload to improve the upload performance.` | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private logNoFilesFound() { | ||||||
|  |         const errorMessage = `No files were found with the provided path: ${this.path}. No artifacts will be uploaded.`; | ||||||
|  |         switch (this.errorBehavior) { | ||||||
|  |             case NoFileOption.warn: { | ||||||
|  |                 core.warning(errorMessage); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case NoFileOption.error: { | ||||||
|  |                 core.setFailed(errorMessage); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case NoFileOption.ignore: { | ||||||
|  |                 core.info(errorMessage); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										132
									
								
								src/nextcloud/NextcloudClient.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/nextcloud/NextcloudClient.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | |||||||
|  | import * as fsSync from 'fs' | ||||||
|  | import * as fs from 'fs/promises' | ||||||
|  | import * as path from 'path' | ||||||
|  | import core from '@actions/core'; | ||||||
|  | import * as os from 'os'; | ||||||
|  | import { randomUUID } from 'crypto'; | ||||||
|  | import * as archiver from 'archiver'; | ||||||
|  | import { URL } from 'url'; | ||||||
|  | import fetch from 'node-fetch'; | ||||||
|  |  | ||||||
|  | interface FileSpec { | ||||||
|  |     absolutePath: string, | ||||||
|  |     uploadPath: string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export class NextcloudClient { | ||||||
|  |     public constructor( | ||||||
|  |         private endpoint: string, | ||||||
|  |         private artifact: string, | ||||||
|  |         private rootDirectory: string) { } | ||||||
|  |  | ||||||
|  |     public async uploadFiles(files: string[]) { | ||||||
|  |         const spec = this.uploadSpec(files); | ||||||
|  |         var zip = await this.zipFiles(spec); | ||||||
|  |         await this.upload(zip); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private uploadSpec(files: string[]): FileSpec[] { | ||||||
|  |         const specifications = []; | ||||||
|  |         if (!fsSync.existsSync(this.rootDirectory)) { | ||||||
|  |             throw new Error(`this.rootDirectory ${this.rootDirectory} does not exist`); | ||||||
|  |         } | ||||||
|  |         if (!fsSync.lstatSync(this.rootDirectory).isDirectory()) { | ||||||
|  |             throw new Error(`this.rootDirectory ${this.rootDirectory} is not a valid directory`); | ||||||
|  |         } | ||||||
|  |         // Normalize and resolve, this allows for either absolute or relative paths to be used | ||||||
|  |         let root = path.normalize(this.rootDirectory); | ||||||
|  |         root = path.resolve(root); | ||||||
|  |         /* | ||||||
|  |            Example to demonstrate behavior | ||||||
|  |             | ||||||
|  |            Input: | ||||||
|  |              artifactName: my-artifact | ||||||
|  |              rootDirectory: '/home/user/files/plz-upload' | ||||||
|  |              artifactFiles: [ | ||||||
|  |                '/home/user/files/plz-upload/file1.txt', | ||||||
|  |                '/home/user/files/plz-upload/file2.txt', | ||||||
|  |                '/home/user/files/plz-upload/dir/file3.txt' | ||||||
|  |              ] | ||||||
|  |             | ||||||
|  |            Output: | ||||||
|  |              specifications: [ | ||||||
|  |                ['/home/user/files/plz-upload/file1.txt', 'my-artifact/file1.txt'], | ||||||
|  |                ['/home/user/files/plz-upload/file1.txt', 'my-artifact/file2.txt'], | ||||||
|  |                ['/home/user/files/plz-upload/file1.txt', 'my-artifact/dir/file3.txt'] | ||||||
|  |              ] | ||||||
|  |         */ | ||||||
|  |         for (let file of files) { | ||||||
|  |             if (!fsSync.existsSync(file)) { | ||||||
|  |                 throw new Error(`File ${file} does not exist`); | ||||||
|  |             } | ||||||
|  |             if (!fsSync.lstatSync(file).isDirectory()) { | ||||||
|  |                 // Normalize and resolve, this allows for either absolute or relative paths to be used | ||||||
|  |                 file = path.normalize(file); | ||||||
|  |                 file = path.resolve(file); | ||||||
|  |                 if (!file.startsWith(root)) { | ||||||
|  |                     throw new Error(`The rootDirectory: ${root} is not a parent directory of the file: ${file}`); | ||||||
|  |                 } | ||||||
|  |                 // Check for forbidden characters in file paths that will be rejected during upload | ||||||
|  |                 const uploadPath = file.replace(root, ''); | ||||||
|  |                 /* | ||||||
|  |                   uploadFilePath denotes where the file will be uploaded in the file container on the server. During a run, if multiple artifacts are uploaded, they will all | ||||||
|  |                   be saved in the same container. The artifact name is used as the root directory in the container to separate and distinguish uploaded artifacts | ||||||
|  |            | ||||||
|  |                   path.join handles all the following cases and would return 'artifact-name/file-to-upload.txt | ||||||
|  |                     join('artifact-name/', 'file-to-upload.txt') | ||||||
|  |                     join('artifact-name/', '/file-to-upload.txt') | ||||||
|  |                     join('artifact-name', 'file-to-upload.txt') | ||||||
|  |                     join('artifact-name', '/file-to-upload.txt') | ||||||
|  |                 */ | ||||||
|  |                 specifications.push({ | ||||||
|  |                     absolutePath: file, | ||||||
|  |                     uploadPath: path.join(this.artifact, uploadPath) | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 // Directories are rejected by the server during upload | ||||||
|  |                 core.debug(`Removing ${file} from rawSearchResults because it is a directory`); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return specifications; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     private async zipFiles(specs: FileSpec[]): Promise<string> { | ||||||
|  |         const tempArtifactDir = path.join(os.tmpdir(), randomUUID()); | ||||||
|  |         const artifactPath = path.join(tempArtifactDir, `artifact-${this.artifact}`); | ||||||
|  |         await fs.mkdir(artifactPath, { recursive: true }); | ||||||
|  |         for (let spec of specs) { | ||||||
|  |             await fs.copyFile(spec.absolutePath, path.join(artifactPath, spec.uploadPath)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         const archivePath = path.join(artifactPath, `${this.artifact}.zip`); | ||||||
|  |         await this.zip(path.join(artifactPath, this.artifact), archivePath); | ||||||
|  |  | ||||||
|  |         return archivePath; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async zip(dirpath: string, destpath: string) { | ||||||
|  |         const archive = archiver.create('zip', { zlib: { level: 9 } }); | ||||||
|  |         const stream = fsSync.createWriteStream(destpath); | ||||||
|  |         archive.directory(dirpath, false) | ||||||
|  |             .on('error', e => Promise.reject()) | ||||||
|  |             .on('close', () => Promise.resolve()) | ||||||
|  |             .pipe(stream); | ||||||
|  |  | ||||||
|  |         return archive.finalize(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async upload(file: string) { | ||||||
|  |         const url = new URL(this.endpoint, '/remote.php/dav/files/user/path/to/file'); | ||||||
|  |         const stream = fsSync.createReadStream(file); | ||||||
|  |         await fetch(url.href, { | ||||||
|  |             method: 'PUT', | ||||||
|  |             body: stream | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private shareFile() { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ |     "target": "es6",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ | ||||||
|     "module": "commonjs",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ |     "module": "commonjs",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ | ||||||
|     "strict": true,                                 /* Enable all strict type-checking options. */ |     "strict": true,                                 /* Enable all strict type-checking options. */ | ||||||
|     "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ |     "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ | ||||||
| @@ -8,6 +8,7 @@ | |||||||
|     "forceConsistentCasingInFileNames": true,       /* Disallow inconsistently-cased references to the same file. */ |     "forceConsistentCasingInFileNames": true,       /* Disallow inconsistently-cased references to the same file. */ | ||||||
|     "rootDir": "src", |     "rootDir": "src", | ||||||
|     "outDir": "dist", |     "outDir": "dist", | ||||||
|     "sourceMap": true |     "sourceMap": true, | ||||||
|  |     "lib": ["es6"] | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Trym Lund Flogard
					Trym Lund Flogard