Code Freeze CLI: Add Milestone command (#37723)

Add milestone computation cli
This commit is contained in:
Paul Sealock 2023-04-25 16:55:14 +12:00 committed by GitHub
parent 99fd4a1e09
commit 5798e87200
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 649 additions and 11 deletions

View File

@ -2268,6 +2268,8 @@ importers:
specifiers:
'@actions/core': ^1.10.0
'@commander-js/extra-typings': ^0.1.0
'@octokit/graphql': 4.8.0
'@octokit/graphql-schema': ^14.1.0
'@types/jest': ^27.4.1
'@types/node': ^16.18.18
'@woocommerce/eslint-plugin': workspace:*
@ -2275,15 +2277,25 @@ importers:
commander: ^9.4.0
dotenv: ^10.0.0
eslint: ^8.32.0
graphql: ^16.6.0
jest: ^29.5.0
octokit: ^2.0.14
ora: ^5.4.1
semver: ^7.3.2
ts-jest: ^29.1.0
typescript: ^4.9.5
dependencies:
'@actions/core': 1.10.0
'@commander-js/extra-typings': 0.1.0_commander@9.4.0
'@octokit/graphql': 4.8.0
'@octokit/graphql-schema': 14.1.0
chalk: 4.1.2
commander: 9.4.0
dotenv: 10.0.0
graphql: 16.6.0
octokit: 2.0.14
ora: 5.4.1
semver: 7.3.8
devDependencies:
'@types/jest': 27.4.1
'@types/node': 16.18.21
@ -10383,6 +10395,80 @@ packages:
resolution: {integrity: sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ==}
engines: {node: '>=12.0.0'}
/@octokit/app/13.1.2:
resolution: {integrity: sha512-Kf+h5sa1SOI33hFsuHvTsWj1jUrjp1x4MuiJBq7U/NicfEGa6nArPUoDnyfP/YTmcQ5cQ5yvOgoIBkbwPg6kzQ==}
engines: {node: '>= 14'}
dependencies:
'@octokit/auth-app': 4.0.9
'@octokit/auth-unauthenticated': 3.0.4
'@octokit/core': 4.0.5
'@octokit/oauth-app': 4.2.0
'@octokit/plugin-paginate-rest': 6.0.0_@octokit+core@4.0.5
'@octokit/types': 9.0.0
'@octokit/webhooks': 10.9.1
transitivePeerDependencies:
- encoding
dev: false
/@octokit/auth-app/4.0.9:
resolution: {integrity: sha512-VFpKIXhHO+kVJtane5cEvdYPtjDKCOI0uKsRrsZfJP+uEu7rcPbQCLCcRKgyT+mUIzGr1IIOmwP/lFqSip1dXA==}
engines: {node: '>= 14'}
dependencies:
'@octokit/auth-oauth-app': 5.0.5
'@octokit/auth-oauth-user': 2.1.1
'@octokit/request': 6.2.1
'@octokit/request-error': 3.0.1
'@octokit/types': 9.0.0
'@types/lru-cache': 5.1.1
deprecation: 2.3.1
lru-cache: 6.0.0
universal-github-app-jwt: 1.1.1
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/auth-oauth-app/5.0.5:
resolution: {integrity: sha512-UPX1su6XpseaeLVCi78s9droxpGtBWIgz9XhXAx9VXabksoF0MyI5vaa1zo1njyYt6VaAjFisC2A2Wchcu2WmQ==}
engines: {node: '>= 14'}
dependencies:
'@octokit/auth-oauth-device': 4.0.4
'@octokit/auth-oauth-user': 2.1.1
'@octokit/request': 6.2.1
'@octokit/types': 9.0.0
'@types/btoa-lite': 1.0.0
btoa-lite: 1.0.0
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/auth-oauth-device/4.0.4:
resolution: {integrity: sha512-Xl85BZYfqCMv+Uvz33nVVUjE7I/PVySNaK6dRRqlkvYcArSr9vRcZC9KVjXYObGRTCN6mISeYdakAZvWEN4+Jw==}
engines: {node: '>= 14'}
dependencies:
'@octokit/oauth-methods': 2.0.5
'@octokit/request': 6.2.3
'@octokit/types': 9.0.0
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/auth-oauth-user/2.1.1:
resolution: {integrity: sha512-JgqnNNPf9CaWLxWm9uh2WgxcaVYhxBR09NVIPTiMU2dVZ3FObOHs3njBiLNw+zq84k+rEdm5Y7AsiASrZ84Apg==}
engines: {node: '>= 14'}
dependencies:
'@octokit/auth-oauth-device': 4.0.4
'@octokit/oauth-methods': 2.0.5
'@octokit/request': 6.2.1
'@octokit/types': 9.0.0
btoa-lite: 1.0.0
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/auth-token/2.5.0:
resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==}
dependencies:
@ -10396,6 +10482,14 @@ packages:
'@octokit/types': 7.4.0
dev: false
/@octokit/auth-unauthenticated/3.0.4:
resolution: {integrity: sha512-AT74XGBylcLr4lmUp1s6mjSUgphGdlse21Qjtv5DzpX1YOl5FXKwvNcZWESdhyBbpDT8VkVyLFqa/7a7eqpPNw==}
engines: {node: '>= 14'}
dependencies:
'@octokit/request-error': 3.0.1
'@octokit/types': 9.0.0
dev: false
/@octokit/core/3.5.1:
resolution: {integrity: sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==}
dependencies:
@ -10428,7 +10522,7 @@ packages:
/@octokit/endpoint/6.0.12:
resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==}
dependencies:
'@octokit/types': 6.34.0
'@octokit/types': 6.41.0
is-plain-object: 5.0.0
universal-user-agent: 6.0.0
@ -10441,11 +10535,18 @@ packages:
universal-user-agent: 6.0.0
dev: false
/@octokit/graphql-schema/14.1.0:
resolution: {integrity: sha512-RMq/ghKcszEhXmzW1FFxnWUY2P9zM3PvfQtgVyTIRmDL+sfGj2Q+3mMPMVnTrIcFVtHH0bErJB54UWYYKw6eRg==}
dependencies:
graphql: 16.6.0
graphql-tag: 2.12.6_graphql@16.6.0
dev: false
/@octokit/graphql/4.8.0:
resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==}
dependencies:
'@octokit/request': 5.6.3
'@octokit/types': 6.34.0
'@octokit/types': 6.41.0
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
@ -10461,16 +10562,55 @@ packages:
- encoding
dev: false
/@octokit/oauth-app/4.2.0:
resolution: {integrity: sha512-gyGclT77RQMkVUEW3YBeAKY+LBSc5u3eC9Wn/Uwt3WhuKuu9mrV18EnNpDqmeNll+mdV02yyBROU29Tlili6gg==}
engines: {node: '>= 14'}
dependencies:
'@octokit/auth-oauth-app': 5.0.5
'@octokit/auth-oauth-user': 2.1.1
'@octokit/auth-unauthenticated': 3.0.4
'@octokit/core': 4.0.5
'@octokit/oauth-authorization-url': 5.0.0
'@octokit/oauth-methods': 2.0.5
'@types/aws-lambda': 8.10.114
fromentries: 1.3.2
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/oauth-authorization-url/5.0.0:
resolution: {integrity: sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==}
engines: {node: '>= 14'}
dev: false
/@octokit/oauth-methods/2.0.5:
resolution: {integrity: sha512-yQP6B5gE3axNxuM3U9KqWs/ErAQ+WLPaPgC/7EjsZsQibkf8sjdAfF8/y/EJW+Dd05XQvadX4WhQZPMnO1SE1A==}
engines: {node: '>= 14'}
dependencies:
'@octokit/oauth-authorization-url': 5.0.0
'@octokit/request': 6.2.3
'@octokit/request-error': 3.0.3
'@octokit/types': 9.0.0
btoa-lite: 1.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/openapi-types/11.2.0:
resolution: {integrity: sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==}
dev: true
/@octokit/openapi-types/12.11.0:
resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==}
dev: true
/@octokit/openapi-types/13.10.0:
resolution: {integrity: sha512-wPQDpTyy35D6VS/lekXDaKcxy6LI2hzcbmXBnP180Pdgz3dXRzoHdav0w09yZzzWX8HHLGuqwAeyMqEPtWY2XA==}
/@octokit/openapi-types/16.0.0:
resolution: {integrity: sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==}
dev: false
/@octokit/plugin-paginate-rest/2.21.3_@octokit+core@3.5.1:
resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==}
peerDependencies:
@ -10490,6 +10630,16 @@ packages:
'@octokit/types': 7.4.0
dev: false
/@octokit/plugin-paginate-rest/6.0.0_@octokit+core@4.0.5:
resolution: {integrity: sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==}
engines: {node: '>= 14'}
peerDependencies:
'@octokit/core': '>=4'
dependencies:
'@octokit/core': 4.0.5
'@octokit/types': 9.0.0
dev: false
/@octokit/plugin-request-log/1.0.4_@octokit+core@3.5.1:
resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==}
peerDependencies:
@ -10527,10 +10677,43 @@ packages:
deprecation: 2.3.1
dev: false
/@octokit/plugin-rest-endpoint-methods/7.0.1_@octokit+core@4.0.5:
resolution: {integrity: sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==}
engines: {node: '>= 14'}
peerDependencies:
'@octokit/core': '>=3'
dependencies:
'@octokit/core': 4.0.5
'@octokit/types': 9.0.0
deprecation: 2.3.1
dev: false
/@octokit/plugin-retry/4.1.3_@octokit+core@4.0.5:
resolution: {integrity: sha512-3YKBj7d0J/4mpEc4xzMociWsMNl5lZqrpAnYcW6mqiSGF3wFjU+c6GHih6GLClk31JNvKDr0x9jc5cfm7evkZg==}
engines: {node: '>= 14'}
peerDependencies:
'@octokit/core': '>=3'
dependencies:
'@octokit/core': 4.0.5
'@octokit/types': 9.0.0
bottleneck: 2.19.5
dev: false
/@octokit/plugin-throttling/5.0.1_@octokit+core@4.0.5:
resolution: {integrity: sha512-I4qxs7wYvYlFuY3PAUGWAVPhFXG3RwnvTiSr5Fu/Auz7bYhDLnzS2MjwV8nGLq/FPrWwYiweeZrI5yjs1YG4tQ==}
engines: {node: '>= 14'}
peerDependencies:
'@octokit/core': ^4.0.0
dependencies:
'@octokit/core': 4.0.5
'@octokit/types': 9.0.0
bottleneck: 2.19.5
dev: false
/@octokit/request-error/2.1.0:
resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==}
dependencies:
'@octokit/types': 6.34.0
'@octokit/types': 6.41.0
deprecation: 2.3.1
once: 1.4.0
@ -10542,12 +10725,21 @@ packages:
deprecation: 2.3.1
once: 1.4.0
/@octokit/request-error/3.0.3:
resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==}
engines: {node: '>= 14'}
dependencies:
'@octokit/types': 9.0.0
deprecation: 2.3.1
once: 1.4.0
dev: false
/@octokit/request/5.6.3:
resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==}
dependencies:
'@octokit/endpoint': 6.0.12
'@octokit/request-error': 2.1.0
'@octokit/types': 6.34.0
'@octokit/types': 6.41.0
is-plain-object: 5.0.0
node-fetch: 2.6.7
universal-user-agent: 6.0.0
@ -10568,6 +10760,20 @@ packages:
- encoding
dev: false
/@octokit/request/6.2.3:
resolution: {integrity: sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==}
engines: {node: '>= 14'}
dependencies:
'@octokit/endpoint': 7.0.2
'@octokit/request-error': 3.0.3
'@octokit/types': 9.0.0
is-plain-object: 5.0.0
node-fetch: 2.6.7
universal-user-agent: 6.0.0
transitivePeerDependencies:
- encoding
dev: false
/@octokit/rest/18.12.0:
resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==}
dependencies:
@ -10595,18 +10801,43 @@ packages:
resolution: {integrity: sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==}
dependencies:
'@octokit/openapi-types': 11.2.0
dev: true
/@octokit/types/6.41.0:
resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==}
dependencies:
'@octokit/openapi-types': 12.11.0
dev: true
/@octokit/types/7.4.0:
resolution: {integrity: sha512-ln1GW0p72+P8qeRjHGj0wyR5ePy6slqvczveOqonMk1w1UWua6UgrkwFzv6S0vKWjSqt/ijYXF1ehNVRRRSvLA==}
dependencies:
'@octokit/openapi-types': 13.10.0
/@octokit/types/9.0.0:
resolution: {integrity: sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==}
dependencies:
'@octokit/openapi-types': 16.0.0
dev: false
/@octokit/webhooks-methods/3.0.2:
resolution: {integrity: sha512-Vlnv5WBscf07tyAvfDbp7pTkMZUwk7z7VwEF32x6HqI+55QRwBTcT+D7DDjZXtad/1dU9E32x0HmtDlF9VIRaQ==}
engines: {node: '>= 14'}
dev: false
/@octokit/webhooks-types/6.11.0:
resolution: {integrity: sha512-AanzbulOHljrku1NGfafxdpTCfw2ENaWzH01N2vqQM+cUFbk868Cgh0xylz0JIM9BoKbfI++bdD6EYX0Q/UTEw==}
dev: false
/@octokit/webhooks/10.9.1:
resolution: {integrity: sha512-5NXU4VfsNOo2VSU/SrLrpPH2Z1ZVDOWFcET4EpnEBX1uh/v8Uz65UVuHIRx5TZiXhnWyRE9AO1PXHa+M/iWwZA==}
engines: {node: '>= 14'}
dependencies:
'@octokit/request-error': 3.0.1
'@octokit/webhooks-methods': 3.0.2
'@octokit/webhooks-types': 6.11.0
aggregate-error: 3.1.0
dev: false
/@playwright/test/1.30.0:
resolution: {integrity: sha512-SVxkQw1xvn/Wk/EvBnqWIq6NLo1AppwbYOjNLmyU0R1RoQ3rLEBtmjTnElcnz8VEtn11fptj1ECxK0tgURhajw==}
engines: {node: '>=14'}
@ -14345,6 +14576,10 @@ packages:
/@types/aria-query/4.2.2:
resolution: {integrity: sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==}
/@types/aws-lambda/8.10.114:
resolution: {integrity: sha512-M8WpEGfC9iQ6V2Ccq6nGIXoQgeVc6z0Ngk8yCOL5V/TYIxshvb0MWQYLFFTZDesL0zmsoBc4OBjG9DB/4rei6w==}
dev: false
/@types/babel__core/7.1.16:
resolution: {integrity: sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==}
dependencies:
@ -14383,6 +14618,10 @@ packages:
'@types/node': 16.18.21
dev: true
/@types/btoa-lite/1.0.0:
resolution: {integrity: sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==}
dev: false
/@types/cacheable-request/6.0.2:
resolution: {integrity: sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==}
dependencies:
@ -14592,6 +14831,12 @@ packages:
/@types/json5/0.0.29:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
/@types/jsonwebtoken/9.0.1:
resolution: {integrity: sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw==}
dependencies:
'@types/node': 16.18.21
dev: false
/@types/keyv/3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies:
@ -14614,6 +14859,10 @@ packages:
/@types/lodash/4.14.184:
resolution: {integrity: sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q==}
/@types/lru-cache/5.1.1:
resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==}
dev: false
/@types/md5/2.3.2:
resolution: {integrity: sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==}
dev: true
@ -19134,7 +19383,6 @@ packages:
dependencies:
clean-stack: 2.2.0
indent-string: 4.0.0
dev: true
/airbnb-js-shims/2.2.1:
resolution: {integrity: sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ==}
@ -21044,6 +21292,10 @@ packages:
/boolbase/1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
/bottleneck/2.19.5:
resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==}
dev: false
/boxen/1.3.0:
resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==}
engines: {node: '>=4'}
@ -21278,6 +21530,10 @@ packages:
dependencies:
node-int64: 0.4.0
/btoa-lite/1.0.0:
resolution: {integrity: sha512-gvW7InbIyF8AicrqWoptdW08pUxuhq8BEgowNajy9RhiE86fmGAGl+bLKo6oB8QP0CkqHLowfN0oJdKC/J6LbA==}
dev: false
/buffer-alloc-unsafe/1.1.0:
resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==}
dev: true
@ -21292,6 +21548,10 @@ packages:
/buffer-crc32/0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
/buffer-equal-constant-time/1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
dev: false
/buffer-fill/1.0.0:
resolution: {integrity: sha1-+PeLdniYiO858gXNY39o5wISKyw=}
dev: true
@ -21933,7 +22193,6 @@ packages:
/clean-stack/2.2.0:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
dev: true
/clean-stack/3.0.1:
resolution: {integrity: sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==}
@ -23976,6 +24235,12 @@ packages:
jsbn: 0.1.1
safer-buffer: 2.1.2
/ecdsa-sig-formatter/1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
dependencies:
safe-buffer: 5.2.1
dev: false
/ee-first/1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@ -26654,6 +26919,10 @@ packages:
readable-stream: 2.3.7
dev: true
/fromentries/1.3.2:
resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
dev: false
/fs-constants/1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
@ -27343,6 +27612,21 @@ packages:
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
/graphql-tag/2.12.6_graphql@16.6.0:
resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==}
engines: {node: '>=10'}
peerDependencies:
graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
dependencies:
graphql: 16.6.0
tslib: 2.5.0
dev: false
/graphql/16.6.0:
resolution: {integrity: sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==}
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
dev: false
/gridicons/3.4.0_react@17.0.2:
resolution: {integrity: sha512-GikyCOcfhwHSN8tfsZvcWwWSaRLebVZCvDzfFg0X50E+dIAnG2phfFUTNa06dXA09kqRYCdnu8sPO8pSYO3UVA==}
peerDependencies:
@ -31964,6 +32248,16 @@ packages:
engines: {'0': node >= 0.2.0}
dev: true
/jsonwebtoken/9.0.0:
resolution: {integrity: sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==}
engines: {node: '>=12', npm: '>=6'}
dependencies:
jws: 3.2.2
lodash: 4.17.21
ms: 2.1.3
semver: 7.3.8
dev: false
/jsprim/1.4.1:
resolution: {integrity: sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==}
engines: {'0': node >=0.6.0}
@ -31993,6 +32287,21 @@ packages:
resolution: {integrity: sha512-u8HXJ3HlNrTzY7zrYYKjNEfBlyjqhdBkoyTVdjtn7p02RJD5NvR8rIClzeGA7t+UYP1/7eAkWNLU0+P3QrEqKQ==}
dev: true
/jwa/1.4.1:
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
dev: false
/jws/3.2.2:
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
dependencies:
jwa: 1.4.1
safe-buffer: 5.2.1
dev: false
/keyv/4.1.1:
resolution: {integrity: sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==}
dependencies:
@ -34642,6 +34951,22 @@ packages:
- supports-color
dev: true
/octokit/2.0.14:
resolution: {integrity: sha512-z6cgZBFxirpFEQ1La8Lg83GCs5hOV2EPpkYYdjsGNbfQMv8qUGjq294MiRBCbZqLufviakGsPUxaNKe3JrPmsA==}
engines: {node: '>= 14'}
dependencies:
'@octokit/app': 13.1.2
'@octokit/core': 4.0.5
'@octokit/oauth-app': 4.2.0
'@octokit/plugin-paginate-rest': 6.0.0_@octokit+core@4.0.5
'@octokit/plugin-rest-endpoint-methods': 7.0.1_@octokit+core@4.0.5
'@octokit/plugin-retry': 4.1.3_@octokit+core@4.0.5
'@octokit/plugin-throttling': 5.0.1_@octokit+core@4.0.5
'@octokit/types': 9.0.0
transitivePeerDependencies:
- encoding
dev: false
/octonode/0.10.2:
resolution: {integrity: sha512-lxKJxAvrw3BuM0Wu3A/TRyFkYxMFWbMm8p7fDO3EoG9KDgOy53d91bjlGR1mmNk1EoF5LjGBx7BmIB+PfmMKLQ==}
engines: {node: '>0.4.11'}
@ -41934,6 +42259,13 @@ packages:
unist-util-visit-parents: 3.1.1
dev: true
/universal-github-app-jwt/1.1.1:
resolution: {integrity: sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==}
dependencies:
'@types/jsonwebtoken': 9.0.1
jsonwebtoken: 9.0.0
dev: false
/universal-user-agent/6.0.0:
resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}

View File

@ -10,9 +10,15 @@
"dependencies": {
"@actions/core": "^1.10.0",
"@commander-js/extra-typings": "^0.1.0",
"@octokit/graphql": "4.8.0",
"@octokit/graphql-schema": "^14.1.0",
"chalk": "^4.1.2",
"commander": "^9.4.0",
"dotenv": "^10.0.0"
"dotenv": "^10.0.0",
"graphql": "^16.6.0",
"octokit": "^2.0.14",
"ora": "^5.4.1",
"semver": "^7.3.2"
},
"devDependencies": {
"@types/jest": "^27.4.1",

View File

@ -7,9 +7,11 @@ import { Command } from '@commander-js/extra-typings';
* Internal dependencies
*/
import { verifyDayCommand } from './verify-day';
import { milesStoneCommand } from './milestone';
const program = new Command( 'code-freeze' )
.description( 'Code freeze utilities' )
.addCommand( verifyDayCommand );
.addCommand( verifyDayCommand )
.addCommand( milesStoneCommand );
export default program;

View File

@ -0,0 +1,152 @@
/**
* External dependencies
*/
import { Command } from '@commander-js/extra-typings';
import chalk from 'chalk';
import ora from 'ora';
/**
* Internal dependencies
*/
import { getLatestReleaseVersion } from '../../../github/repo';
import { octokitWithAuth } from '../../../github/api';
import { WPIncrement, setGithubMilestoneOutputs } from './utils';
import { Options } from './types';
export const milesStoneCommand = new Command( 'milestone' )
.description( 'Create a milestone' )
.option(
'-g --github',
'CLI command is used in the Github Actions context.'
)
.option( '-d --dryRun', 'Prepare the milestone but do not create it.' )
.option(
'-o --owner <owner>',
'Repository owner. Default: woocommerce',
'woocommerce'
)
.option(
'-n --name <name>',
'Repository name. Default: woocommerce',
'woocommerce'
)
.option(
'-m --milestone <milestone>',
'Milestone to create. Next milestone is gathered from Github if none is supplied'
)
.action( async ( options: Options ) => {
const { owner, name, dryRun, milestone, github } = options;
if ( milestone && github ) {
console.log(
chalk.red(
"You can't manually supply a milestone using Github mode. Please use the CLI locally to add a milestone."
)
);
process.exit( 1 );
}
let nextMilestone;
let nextReleaseVersion;
if ( milestone ) {
console.log(
chalk.yellow(
`Manually creating milestone ${ milestone } in ${ owner }/${ name }`
)
);
nextMilestone = milestone;
} else {
const versionSpinner = ora(
'No milestone supplied, going off the latest release version'
).start();
const latestReleaseVersion = await getLatestReleaseVersion(
options
);
versionSpinner.succeed();
nextReleaseVersion = WPIncrement( latestReleaseVersion );
nextMilestone = WPIncrement( nextReleaseVersion );
console.log(
chalk.yellow(
`The latest release in ${ owner }/${ name } is version: ${ latestReleaseVersion }`
)
);
console.log(
chalk.yellow(
`The next release in ${ owner }/${ name } will be version: ${ nextReleaseVersion }`
)
);
console.log(
chalk.yellow(
`The next milestone in ${ owner }/${ name } will be: ${ nextMilestone }`
)
);
}
const milestoneSpinner = ora(
`Creating a ${ nextMilestone } milestone`
).start();
if ( dryRun ) {
milestoneSpinner.succeed();
console.log(
chalk.green(
`DRY RUN: Skipping actual creation of milestone ${ nextMilestone }`
)
);
process.exit( 0 );
}
try {
await octokitWithAuth.request(
`POST /repos/${ owner }/${ name }/milestones`,
{
title: nextMilestone,
}
);
} catch ( e ) {
const milestoneAlreadyExistsError = e.response.data.errors?.some(
( error ) => error.code === 'already_exists'
);
if ( milestoneAlreadyExistsError ) {
milestoneSpinner.succeed();
console.log(
chalk.green(
`Milestone ${ nextMilestone } already exists in ${ owner }/${ name }`
)
);
if ( github ) {
setGithubMilestoneOutputs(
nextReleaseVersion,
nextMilestone
);
}
process.exit( 0 );
} else {
milestoneSpinner.fail();
console.log(
chalk.red(
`\nFailed to create milestone ${ nextMilestone } in ${ owner }/${ name }`
)
);
console.log( chalk.red( e.response.data.message ) );
process.exit( 1 );
}
}
milestoneSpinner.succeed();
if ( github ) {
setGithubMilestoneOutputs( nextReleaseVersion, nextMilestone );
}
console.log(
chalk.green(
`Successfully created milestone ${ nextMilestone } in ${ owner }/${ name }`
)
);
} );

View File

@ -0,0 +1,7 @@
export type Options = {
github?: boolean;
dryRun?: boolean;
owner?: string;
name?: string;
milestone?: string;
};

View File

@ -0,0 +1,30 @@
/**
* External dependencies
*/
import { parse, inc } from 'semver';
import { setOutput } from '@actions/core';
/**
* Bumps the version according to WP rules.
*
* @param {string} version Version to increment
* @return {string} Incremented version
*/
export const WPIncrement = ( version: string ): string => {
const parsedVersion = parse( version );
return inc( parsedVersion, parsedVersion.minor === 9 ? 'major' : 'minor' );
};
/**
* Set Github outputs.
*
* @param {string} nextReleaseVersion Next release version
* @param {string} nextMilestone Next milestone
*/
export const setGithubMilestoneOutputs = (
nextReleaseVersion: string,
nextMilestone: string
): void => {
setOutput( 'nextReleaseVersion', nextReleaseVersion );
setOutput( 'nextDevelopmentVersion', nextMilestone );
};

View File

@ -13,7 +13,7 @@ import {
DAYS_BETWEEN_CODE_FREEZE_AND_RELEASE,
getToday,
getFutureDate,
} from '../utils/index';
} from './utils';
export const verifyDayCommand = new Command( 'verify-day' )
.description( 'Verify if today is the code freeze day' )

View File

@ -0,0 +1,58 @@
/**
* Internal dependencies
*/
import { getLatestReleaseVersion } from '../repo';
jest.mock( '../api', () => {
return {
graphqlWithAuth: jest.fn().mockResolvedValue( {
repository: {
releases: {
nodes: [
{
tagName: 'nightly',
isLatest: false,
},
{
tagName: 'wc-beta-tester-99.99.0',
isLatest: false,
},
{
tagName: '1.0.0',
isLatest: false,
},
{
tagName: '1.1.0',
isLatest: false,
},
{
tagName: '1.2.0',
isLatest: false,
},
{
tagName: '2.0.0',
isLatest: false,
},
{
tagName: '2.0.1',
isLatest: true,
},
{
tagName: '1.0.1',
isLatest: false,
},
],
},
},
} ),
};
} );
it( 'should return the latest release version', async () => {
expect(
await getLatestReleaseVersion( {
owner: 'woocommerce',
name: 'woocommerce',
} )
).toBe( '2.0.1' );
} );

View File

@ -0,0 +1,15 @@
/**
* External dependencies
*/
import { graphql } from '@octokit/graphql';
import { Octokit } from 'octokit';
export const graphqlWithAuth = graphql.defaults( {
headers: {
authorization: `Bearer ${ process.env.GITHUB_TOKEN }`,
},
} );
export const octokitWithAuth = new Octokit( {
auth: process.env.GITHUB_TOKEN,
} );

View File

@ -0,0 +1,36 @@
/**
* External dependencies
*/
import { Repository } from '@octokit/graphql-schema';
/**
* Internal dependencies
*/
import { graphqlWithAuth } from './api';
export const getLatestReleaseVersion = async ( options: {
owner?: string;
name?: string;
} ): Promise< string > => {
const { owner, name } = options;
const data = await graphqlWithAuth< { repository: Repository } >( `
{
repository(owner: "${ owner }", name: "${ name }") {
releases(
first: 25
orderBy: { field: CREATED_AT, direction: DESC }
) {
nodes {
tagName
isLatest
}
}
}
}
` );
return data.repository.releases.nodes.find(
( tagName ) => tagName.isLatest
).tagName;
};