From 85ab71705efc709ed14489066c9fa1da029f5227 Mon Sep 17 00:00:00 2001 From: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> Date: Wed, 9 Nov 2022 01:26:36 +0530 Subject: [PATCH] Migrate to Typescript + Update YamlCreate (#41) * Migrate to Typescript * Update .all-contributorsrc Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> * Update README.md Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> * Update README.md Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> * Update package.json Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> * Update README.md Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> * Update YamlCreate & other things * YamlCreate: Don't preserve volatile fields * Minor fixes * Bump YamlCreate version one more time Signed-off-by: Vedant <83997633+vedantmgoyal2009@users.noreply.github.com> --- .all-contributorsrc | 2 +- .github/workflows/codeql-analysis.yml | 65 +++-- CODE_OF_CONDUCT.md | 28 +- CONTRIBUTING.md | 9 +- LICENSE.md | 140 ++++----- README.md | 8 +- dist/index.js | 395 +++++++++++--------------- package-lock.json | 57 +++- package.json | 21 +- YamlCreate.ps1 => src/YamlCreate.ps1 | 212 ++++++++------ index.js => src/main.ts | 66 ++--- tsconfig.json | 104 +++++++ 12 files changed, 631 insertions(+), 476 deletions(-) rename YamlCreate.ps1 => src/YamlCreate.ps1 (83%) rename index.js => src/main.ts (81%) create mode 100644 tsconfig.json diff --git a/.all-contributorsrc b/.all-contributorsrc index 254bed2..9dcc1ac 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -3,7 +3,7 @@ "README.md" ], "imageSize": 90, - "commit": false, + "commit": true, "contributorsPerLine": 7, "contributorsSortAlphabetically": true, "projectName": "winget-releaser", diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d0bfc10..c205db9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -9,14 +9,14 @@ # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # -name: "CodeQL" +name: 'CodeQL' on: push: - branches: [ "main" ] + branches: ['main'] pull_request: # The branches below must be a subset of the branches above - branches: [ "main" ] + branches: ['main'] schedule: - cron: '11 21 * * 4' @@ -32,43 +32,42 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ['javascript'] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{matrix.language}}' diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index bf1b96b..933054c 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the overall +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or advances of +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email address, +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities @@ -119,14 +119,14 @@ version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by -[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. +[Mozilla's code of conduct enforcement ladder][mozilla coc]. For answers to common questions about this code of conduct, see the FAQ at -[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html -[Mozilla CoC]: https://github.com/mozilla/diversity -[FAQ]: https://www.contributor-covenant.org/faq +[mozilla coc]: https://github.com/mozilla/diversity +[faq]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f807973..a99bf11 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,11 @@ ## Contributing Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. -* If you have suggestions for adding or removing projects, feel free to [open an issue](https://github.com/vedantmgoyal2009/winget-releaser/issues/new) to discuss it, or directly create a pull request after you edit the *README.md* file with necessary changes. -* Please make sure you check your spelling and grammar. -* Create individual PR for each suggestion. -* Please also read through the [Code Of Conduct](https://github.com/vedantmgoyal2009/winget-releaser/blob/main/CODE_OF_CONDUCT.md) before posting your first idea as well. + +- If you have suggestions for adding or removing projects, feel free to [open an issue](https://github.com/vedantmgoyal2009/winget-releaser/issues/new) to discuss it, or directly create a pull request after you edit the _README.md_ file with necessary changes. +- Please make sure you check your spelling and grammar. +- Create individual PR for each suggestion. +- Please also read through the [Code Of Conduct](https://github.com/vedantmgoyal2009/winget-releaser/blob/main/CODE_OF_CONDUCT.md) before posting your first idea as well. ### Creating A Pull Request diff --git a/LICENSE.md b/LICENSE.md index cba6f6a..74c892a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -204,23 +204,23 @@ produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: -- a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. -- b) The work must carry prominent notices stating that it is - released under this License and any conditions added under - section 7. This requirement modifies the requirement in section 4 - to "keep intact all notices". -- c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. -- d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. +- a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. +- b) The work must carry prominent notices stating that it is + released under this License and any conditions added under + section 7. This requirement modifies the requirement in section 4 + to "keep intact all notices". +- c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. +- d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, @@ -239,42 +239,42 @@ sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: -- a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. -- b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the Corresponding - Source from a network server at no charge. -- c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. -- d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. -- e) Convey the object code using peer-to-peer transmission, - provided you inform other peers where the object code and - Corresponding Source of the work are being offered to the general - public at no charge under subsection 6d. +- a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. +- b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the Corresponding + Source from a network server at no charge. +- c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. +- d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. +- e) Convey the object code using peer-to-peer transmission, + provided you inform other peers where the object code and + Corresponding Source of the work are being offered to the general + public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be @@ -350,23 +350,23 @@ Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: -- a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or -- b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or -- c) Prohibiting misrepresentation of the origin of that material, - or requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or -- d) Limiting the use for publicity purposes of names of licensors - or authors of the material; or -- e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or -- f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions - of it) with contractual assumptions of liability to the recipient, - for any liability that these contractual assumptions directly - impose on those licensors and authors. +- a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or +- b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or +- c) Prohibiting misrepresentation of the origin of that material, + or requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or +- d) Limiting the use for publicity purposes of names of licensors + or authors of the material; or +- e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or +- f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions + of it) with contractual assumptions of liability to the recipient, + for any liability that these contractual assumptions directly + impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you diff --git a/README.md b/README.md index f53ce89..d733dd6 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ WinGet Releaser allows you to automate this process, with pull requests that are - Give `workflow` permission to the token you created in Step 1. This will allow the action to automatically update your fork with the upstream repository. - You can use **[ Pull App][pull-app-auto-update-forks]** which keeps your fork up-to-date with the upstream repository via automated pull requests. +3. Please note that releases in draft or unpublished status can't be submitted to WinGet, simply because their binaries are not available for general download. + @@ -131,7 +133,7 @@ jobs:
Workflow with the minimal configuration
-## Configuration Options +## Configuration Options âš’ī¸ ### Package Identifier (identifier) @@ -180,12 +182,12 @@ delete-previous-version: 'true' # don't forget to quotes ### Release tag (release-tag) -- Required: ❌ (Default value: `${{ github.event.release.tag_name || github.ref }}`) +- Required: ❌ (Default value: `${{ github.event.release.tag_name || github.ref_name }}`) The GitHub release tag of the release you want to publish to Windows Package Manager (WinGet). ```yaml -release-tag: ${{ github.event.inputs.version }} # workflow_dispatch input `version` +release-tag: ${{ inputs.version }} # workflow_dispatch input `version` ``` ### Token (token) diff --git a/dist/index.js b/dist/index.js index 179e6df..494a0ea 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1174,7 +1174,7 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getOctokitOptions = exports.GitHub = exports.context = void 0; +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; const Context = __importStar(__nccwpck_require__(4087)); const Utils = __importStar(__nccwpck_require__(7914)); // octokit + plugins @@ -1183,13 +1183,13 @@ const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); const plugin_paginate_rest_1 = __nccwpck_require__(4193); exports.context = new Context.Context(); const baseUrl = Utils.getApiBaseUrl(); -const defaults = { +exports.defaults = { baseUrl, request: { agent: Utils.getProxyAgent(baseUrl) } }; -exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(defaults); +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); /** * Convience function to correctly format Octokit Options to pass into the constructor. * @@ -4347,63 +4347,67 @@ exports.request = request; /***/ 3682: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { -var register = __nccwpck_require__(4670) -var addHook = __nccwpck_require__(5549) -var removeHook = __nccwpck_require__(6819) +var register = __nccwpck_require__(4670); +var addHook = __nccwpck_require__(5549); +var removeHook = __nccwpck_require__(6819); // bind with array of arguments: https://stackoverflow.com/a/21792913 -var bind = Function.bind -var bindable = bind.bind(bind) +var bind = Function.bind; +var bindable = bind.bind(bind); -function bindApi (hook, state, name) { - var removeHookRef = bindable(removeHook, null).apply(null, name ? [state, name] : [state]) - hook.api = { remove: removeHookRef } - hook.remove = removeHookRef - - ;['before', 'error', 'after', 'wrap'].forEach(function (kind) { - var args = name ? [state, kind, name] : [state, kind] - hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args) - }) +function bindApi(hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply( + null, + name ? [state, name] : [state] + ); + hook.api = { remove: removeHookRef }; + hook.remove = removeHookRef; + ["before", "error", "after", "wrap"].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind]; + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args); + }); } -function HookSingular () { - var singularHookName = 'h' +function HookSingular() { + var singularHookName = "h"; var singularHookState = { - registry: {} - } - var singularHook = register.bind(null, singularHookState, singularHookName) - bindApi(singularHook, singularHookState, singularHookName) - return singularHook + registry: {}, + }; + var singularHook = register.bind(null, singularHookState, singularHookName); + bindApi(singularHook, singularHookState, singularHookName); + return singularHook; } -function HookCollection () { +function HookCollection() { var state = { - registry: {} - } + registry: {}, + }; - var hook = register.bind(null, state) - bindApi(hook, state) + var hook = register.bind(null, state); + bindApi(hook, state); - return hook + return hook; } -var collectionHookDeprecationMessageDisplayed = false -function Hook () { +var collectionHookDeprecationMessageDisplayed = false; +function Hook() { if (!collectionHookDeprecationMessageDisplayed) { - console.warn('[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4') - collectionHookDeprecationMessageDisplayed = true + console.warn( + '[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4' + ); + collectionHookDeprecationMessageDisplayed = true; } - return HookCollection() + return HookCollection(); } -Hook.Singular = HookSingular.bind() -Hook.Collection = HookCollection.bind() +Hook.Singular = HookSingular.bind(); +Hook.Collection = HookCollection.bind(); -module.exports = Hook +module.exports = Hook; // expose constructors as a named property for TypeScript -module.exports.Hook = Hook -module.exports.Singular = Hook.Singular -module.exports.Collection = Hook.Collection +module.exports.Hook = Hook; +module.exports.Singular = Hook.Singular; +module.exports.Collection = Hook.Collection; /***/ }), @@ -9686,197 +9690,144 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"] /******/ /************************************************************************/ var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +// This entry need to be wrapped in an IIFE because it need to be in strict mode. (() => { -const { getInput, info, getBooleanInput, error } = __nccwpck_require__(2186); -const { context, getOctokit } = __nccwpck_require__(5438); -const { execSync } = __nccwpck_require__(2081); -const { resolve } = __nccwpck_require__(1017); +"use strict"; +var exports = __webpack_exports__; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const core_1 = __nccwpck_require__(2186); +const github_1 = __nccwpck_require__(5438); +const child_process_1 = __nccwpck_require__(2081); +const path_1 = __nccwpck_require__(1017); (async () => { - // check if the runner operating system is windows - if (process.platform != 'win32') { - error('This action only works on Windows.'); - process.exit(1); - } - - // get the inputs from the action - const pkgid = getInput('identifier'); - const version = getInput('version'); - const instRegex = getInput('installers-regex'); - const releaseRepository = getInput('release-repository'); - const releaseTag = getInput('release-tag'); - const delPrevVersion = getBooleanInput('delete-previous-version'); - const token = getInput('token'); - const forkUser = getInput('fork-user'); - - // get only data, and exclude status, url, and headers - releaseInfo = { - ...( - await getOctokit(token).rest.repos.getReleaseByTag({ - owner: context.repo.owner, - // https://github.blog/changelog/2022-09-27-github-actions-additional-information-available-in-github-event-payload-for-scheduled-workflow-runs - repo: releaseRepository, // || context.repo.repo, - tag: releaseTag, - }) - ).data, - }; - - // install powershell-yaml, clone winget-pkgs repo and configure remotes, update yamlcreate, and - // download wingetdev from vedantmgoyal2009/vedantmgoyal2009 (winget-pkgs-automation) - info( - `::group::Install powershell-yaml, clone winget-pkgs and configure remotes, update YamlCreate, download wingetdev...` - ); - execSync( - `Install-Module -Name powershell-yaml -Repository PSGallery -Scope CurrentUser -Force`, - { shell: 'pwsh', stdio: 'inherit' } - ); - // remove winget-pkgs directory if it exists, in case the action is run multiple times for - // publishing multiple packages in the same workflow - execSync( - `If (Test-Path -Path .\\winget-pkgs\\) { Remove-Item -Path .\\winget-pkgs\\ -Recurse -Force -ErrorAction SilentlyContinue }`, - { shell: 'pwsh', stdio: 'inherit' } - ); - execSync( - `git clone https://x-access-token:${token}@github.com/microsoft/winget-pkgs.git`, - { stdio: 'inherit' } - ); - execSync(`git -C winget-pkgs config --local user.name github-actions`, { - stdio: 'inherit', - }); - execSync( - `git -C winget-pkgs config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, - { stdio: 'inherit' } - ); - execSync(`git -C winget-pkgs remote rename origin upstream`, { - stdio: 'inherit', - }); - execSync( - `git -C winget-pkgs remote add origin https://github.com/${forkUser}/winget-pkgs.git`, - { stdio: 'inherit' } - ); - execSync( - `Invoke-WebRequest -Uri https://github.com/vedantmgoyal2009/winget-releaser/raw/${process.env.GITHUB_ACTION_REF}/YamlCreate.ps1 -OutFile .\\winget-pkgs\\Tools\\YamlCreate.ps1`, - { shell: 'pwsh', stdio: 'inherit' } - ); - execSync(`git -C winget-pkgs commit --all -m \"Update YamlCreate.ps1\"`, { - stdio: 'inherit', - }); - execSync( - `svn checkout https://github.com/vedantmgoyal2009/vedantmgoyal2009/trunk/tools/wingetdev`, - { stdio: 'inherit' } - ); - info(`::endgroup::`); - - // resolve wingetdev path (./wingetdev/wingetdev.exe) - process.env.WINGETDEV = resolve('wingetdev', 'wingetdev.exe'); - - info(`::group::Update manifests and create pull request`); - const inputObject = JSON.stringify({ - PackageIdentifier: pkgid, - PackageVersion: - version || new RegExp(/(?<=v).*/g).exec(releaseInfo.tag_name)[0], - InstallerUrls: releaseInfo.assets - .filter((asset) => { - return new RegExp(instRegex, 'g').test(asset.name); - }) - .map((asset) => { - return asset.browser_download_url; - }), - ReleaseNotesUrl: releaseInfo.html_url, - ReleaseDate: new Date(releaseInfo.published_at).toISOString().slice(0, 10), - DeletePreviousVersion: delPrevVersion, - }); - execSync(`.\\YamlCreate.ps1 \'${inputObject}\'`, { - cwd: 'winget-pkgs/Tools', - shell: 'pwsh', - stdio: 'inherit', - env: { ...process.env, GH_TOKEN: token }, // set GH_TOKEN env variable for GitHub CLI (gh) - }); - info(`::endgroup::`); - - info(`::group::Checking for action updates...`); - // check if action version is a version (starts with `v`) and not a pinned commit ref - if (/^v\d+$/g.test(process.env.GITHUB_ACTION_REF)) { - const latestVersion = ( - await getOctokit(token).rest.repos.getLatestRelease({ - owner: 'vedantmgoyal2009', - repo: 'winget-releaser', - }) - ).data.tag_name; - - info(`Current action version: ${process.env.GITHUB_ACTION_REF}`); - info(`Latest version found: ${latestVersion}`); - - // if the latest version is greater than the current version, then update the action - if (latestVersion > process.env.GITHUB_ACTION_REF) { - execSync( - `git clone https://x-access-token:${token}@github.com/${process.env.GITHUB_REPOSITORY}.git`, - { - stdio: 'inherit', - } - ); - execSync(`git config --local user.name github-actions`, { + // check if the runner operating system is windows + if (process.platform !== 'win32') { + (0, core_1.error)('This action only works on Windows.'); + process.exit(1); + } + // get the inputs from the action + const pkgid = (0, core_1.getInput)('identifier'); + const version = (0, core_1.getInput)('version'); + const instRegex = (0, core_1.getInput)('installers-regex'); + const releaseRepository = (0, core_1.getInput)('release-repository'); + const releaseTag = (0, core_1.getInput)('release-tag'); + const delPrevVersion = (0, core_1.getBooleanInput)('delete-previous-version'); + const token = (0, core_1.getInput)('token'); + const forkUser = (0, core_1.getInput)('fork-user'); + // get only data, and exclude status, url, and headers + const releaseInfo = { + ...(await (0, github_1.getOctokit)(token).rest.repos.getReleaseByTag({ + owner: github_1.context.repo.owner, + // https://github.blog/changelog/2022-09-27-github-actions-additional-information-available-in-github-event-payload-for-scheduled-workflow-runs + repo: releaseRepository, + tag: releaseTag, + })).data, + }; + // install powershell-yaml, clone winget-pkgs repo and configure remotes, update yamlcreate, and + // download wingetdev from vedantmgoyal2009/vedantmgoyal2009 (winget-pkgs-automation) + (0, core_1.info)(`::group::Install powershell-yaml, clone winget-pkgs and configure remotes, update YamlCreate, download wingetdev...`); + (0, child_process_1.execSync)(`Install-Module -Name powershell-yaml -Repository PSGallery -Scope CurrentUser -Force`, { shell: 'pwsh', stdio: 'inherit' }); + // remove winget-pkgs directory if it exists, in case the action is run multiple times for + // publishing multiple packages in the same workflow + (0, child_process_1.execSync)(`If (Test-Path -Path .\\winget-pkgs\\) { Remove-Item -Path .\\winget-pkgs\\ -Recurse -Force -ErrorAction SilentlyContinue }`, { shell: 'pwsh', stdio: 'inherit' }); + (0, child_process_1.execSync)(`git clone https://x-access-token:${token}@github.com/microsoft/winget-pkgs.git`, { stdio: 'inherit' }); + (0, child_process_1.execSync)(`git -C winget-pkgs config --local user.name github-actions`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - }); - execSync( - `git config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, - { stdio: 'inherit', cwd: process.env.GITHUB_REPOSITORY.split('/')[1] } - ); - // replace the version in the workflow file using `find` and `sed` - execSync( - `find -name '*.yml' -or -name '*.yaml' -exec sed -i 's/vedantmgoyal2009\\/winget-releaser@${process.env.GITHUB_ACTION_REF}/vedantmgoyal2009\\/winget-releaser@${latestVersion}/g' {} +`, - { - stdio: 'inherit', - cwd: `${ - process.env.GITHUB_REPOSITORY.split('/')[1] - }/.github/workflows`, - shell: 'bash', - } - ); - // create a new branch, commit and push the changes, and create a pull request - execSync( - `git commit --all -m \"ci(winget-releaser): update action from ${process.env.GITHUB_ACTION_REF} to ${latestVersion}\"`, - { - stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - } - ); - execSync(`git switch -c winget-releaser/update-to-${latestVersion}`, { + }); + (0, child_process_1.execSync)(`git -C winget-pkgs config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, { stdio: 'inherit' }); + (0, child_process_1.execSync)(`git -C winget-pkgs remote rename origin upstream`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - }); - execSync( - `git push --force-with-lease --set-upstream origin winget-releaser/update-to-${latestVersion}`, - { - stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - } - ); - execSync( - `@\" -This PR was automatically created by the [WinGet Releaser GitHub Action](https://github.com/vedantmgoyal2009/winget-releaser) to update the action version from \`${process.env.GITHUB_ACTION_REF}\` to \`${newVersion}\`.\`r\`n + }); + (0, child_process_1.execSync)(`git -C winget-pkgs remote add origin https://github.com/${forkUser}/winget-pkgs.git`, { stdio: 'inherit' }); + (0, child_process_1.execSync)(`Invoke-WebRequest -Uri https://github.com/vedantmgoyal2009/winget-releaser/raw/${process.env.GITHUB_ACTION_REF}/src/YamlCreate.ps1 -OutFile .\\winget-pkgs\\Tools\\YamlCreate.ps1`, { shell: 'pwsh', stdio: 'inherit' }); + (0, child_process_1.execSync)(`git -C winget-pkgs commit --all -m \"Update YamlCreate.ps1\"`, { + stdio: 'inherit', + }); + (0, child_process_1.execSync)(`svn checkout https://github.com/vedantmgoyal2009/vedantmgoyal2009/trunk/tools/wingetdev`, { stdio: 'inherit' }); + (0, core_1.info)(`::endgroup::`); + // resolve wingetdev path (./wingetdev/wingetdev.exe) + process.env.WINGETDEV = (0, path_1.resolve)('wingetdev', 'wingetdev.exe'); + (0, core_1.info)(`::group::Update manifests and create pull request`); + const inputObject = JSON.stringify({ + PackageIdentifier: pkgid, + PackageVersion: version || new RegExp(/(?<=v).*/g).exec(releaseInfo.tag_name)[0], + InstallerUrls: releaseInfo.assets + .filter((asset) => { + return new RegExp(instRegex, 'g').test(asset.name); + }) + .map((asset) => { + return asset.browser_download_url; + }), + ReleaseNotesUrl: releaseInfo.html_url, + ReleaseDate: new Date(releaseInfo.published_at).toISOString().slice(0, 10), + DeletePreviousVersion: delPrevVersion, + }); + (0, child_process_1.execSync)(`.\\YamlCreate.ps1 \'${inputObject}\'`, { + cwd: 'winget-pkgs/Tools', + shell: 'pwsh', + stdio: 'inherit', + env: { ...process.env, GH_TOKEN: token }, // set GH_TOKEN env variable for GitHub CLI (gh) + }); + (0, core_1.info)(`::endgroup::`); + (0, core_1.info)(`::group::Checking for action updates...`); + // check if action version is a version (starts with `v`) and not a pinned commit ref + if (/^v\d+$/g.test(process.env.GITHUB_ACTION_REF)) { + const latestVersion = (await (0, github_1.getOctokit)(token).rest.repos.getLatestRelease({ + owner: 'vedantmgoyal2009', + repo: 'winget-releaser', + })).data.tag_name; + (0, core_1.info)(`Current action version: ${process.env.GITHUB_ACTION_REF}`); + (0, core_1.info)(`Latest version found: ${latestVersion}`); + // if the latest version is greater than the current version, then update the action + if (latestVersion > process.env.GITHUB_ACTION_REF) { + (0, child_process_1.execSync)(`git clone https://x-access-token:${token}@github.com/${process.env.GITHUB_REPOSITORY}.git`, { + stdio: 'inherit', + }); + (0, child_process_1.execSync)(`git config --local user.name github-actions`, { + stdio: 'inherit', + cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + }); + (0, child_process_1.execSync)(`git config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, { stdio: 'inherit', cwd: process.env.GITHUB_REPOSITORY.split('/')[1] }); + // replace the version in the workflow file using `find` and `sed` + (0, child_process_1.execSync)(`find -name '*.yml' -or -name '*.yaml' -exec sed -i 's/vedantmgoyal2009\\/winget-releaser@${process.env.GITHUB_ACTION_REF}/vedantmgoyal2009\\/winget-releaser@${latestVersion}/g' {} +`, { + stdio: 'inherit', + cwd: `${process.env.GITHUB_REPOSITORY.split('/')[1]}/.github/workflows`, + shell: 'bash', + }); + // create a new branch, commit and push the changes, and create a pull request + (0, child_process_1.execSync)(`git commit --all -m \"ci(winget-releaser): update action from ${process.env.GITHUB_ACTION_REF} to ${latestVersion}\"`, { + stdio: 'inherit', + cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + }); + (0, child_process_1.execSync)(`git switch -c winget-releaser/update-to-${latestVersion}`, { + stdio: 'inherit', + cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + }); + (0, child_process_1.execSync)(`git push --force-with-lease --set-upstream origin winget-releaser/update-to-${latestVersion}`, { + stdio: 'inherit', + cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + }); + (0, child_process_1.execSync)(`@\" +This PR was automatically created by the [WinGet Releaser GitHub Action](https://github.com/vedantmgoyal2009/winget-releaser) to update the action version from \`${process.env.GITHUB_ACTION_REF}\` to \`${latestVersion}\`.\`r\`n The auto-update function help maintainers keep their workflows up-to-date with the latest version of the action.\`r\`n You can close this pull request if you don't want to update the action version.\`r\`n Mentioning @vedantmgoyal2009 for a second pair of eyes, in case any breaking changes have been introduced in the new version of the action. -\"@ | gh pr create --fill --body-file -`, - { - stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - shell: 'pwsh', - env: { ...process.env, GH_TOKEN: token }, // set GH_TOKEN env variable for GitHub CLI (gh) +\"@ | gh pr create --fill --body-file -`, { + stdio: 'inherit', + cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + shell: 'pwsh', + env: { ...process.env, GH_TOKEN: token }, // set GH_TOKEN env variable for GitHub CLI (gh) + }); + } + else { + (0, core_1.info)(`No updates found. Bye bye!`); } - ); - } else { - info(`No updates found. Bye bye!`); } - } else { - info( - `The workflow maintainer has pinned the action to a commit ref. Skipping update check...` - ); - } - info(`::endgroup::`); + else { + (0, core_1.info)(`The workflow maintainer has pinned the action to a commit ref. Skipping update check...`); + } + (0, core_1.info)(`::endgroup::`); })(); })(); diff --git a/package-lock.json b/package-lock.json index 246b2c9..e322505 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,10 @@ "@actions/github": "^5.1.1" }, "devDependencies": { - "@vercel/ncc": "^0.34.0" + "@types/node": "^18.11.9", + "@vercel/ncc": "^0.34.0", + "prettier": "^2.7.1", + "typescript": "^4.8.4" } }, "node_modules/@actions/core": { @@ -145,6 +148,12 @@ "@octokit/openapi-types": "^12.11.0" } }, + "node_modules/@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "dev": true + }, "node_modules/@vercel/ncc": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz", @@ -199,6 +208,21 @@ "wrappy": "1" } }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -212,6 +236,19 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", @@ -369,6 +406,12 @@ "@octokit/openapi-types": "^12.11.0" } }, + "@types/node": { + "version": "18.11.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", + "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==", + "dev": true + }, "@vercel/ncc": { "version": "0.34.0", "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz", @@ -406,6 +449,12 @@ "wrappy": "1" } }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -416,6 +465,12 @@ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true + }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", diff --git a/package.json b/package.json index 51ea909..d7fc202 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,17 @@ "description": "Publish new releases of your application to Windows Package Manager easily.", "main": "dist/index.js", "scripts": { - "build": "npx ncc build index.js --license licenses.txt", + "all": "npm run format && npm run build && rm src/main.js", + "format": "prettier --write src *.* .github", + "build": "tsc && ncc build src/main.js --license licenses.txt", "test": "echo \"Error: no test specified\" && exit 1" }, + "prettier": { + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true + }, "repository": { "type": "git", "url": "git+https://github.com/vedantmgoyal2009/winget-releaser.git" @@ -27,12 +35,9 @@ "@actions/github": "^5.1.1" }, "devDependencies": { - "@vercel/ncc": "^0.34.0" - }, - "prettier": { - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "singleQuote": true + "@types/node": "^18.11.9", + "@vercel/ncc": "^0.34.0", + "prettier": "^2.7.1", + "typescript": "^4.8.4" } } diff --git a/YamlCreate.ps1 b/src/YamlCreate.ps1 similarity index 83% rename from YamlCreate.ps1 rename to src/YamlCreate.ps1 index 6b4e9fb..7483fac 100644 --- a/YamlCreate.ps1 +++ b/src/YamlCreate.ps1 @@ -6,21 +6,29 @@ Param [Parameter(Mandatory = $true)] $InputObject ) +$ProgressPreference = 'SilentlyContinue' -$ScriptHeader = '# Created with YamlCreate.ps1 v2.1.3 using InputObject 🤖' +$ScriptHeader = '# Created with YamlCreate.ps1 v2.2.1 using InputObject 🤖' $ManifestVersion = '1.2.0' $PSDefaultParameterValues = @{ '*:Encoding' = 'UTF8' } $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False $ofs = ', ' +$useDirectSchemaLink = (Invoke-WebRequest "https://aka.ms/winget-manifest.version.$ManifestVersion.schema.json" -UseBasicParsing).BaseResponse.ContentLength -eq -1 +$SchemaUrls = @{ + version = if ($useDirectSchemaLink) { "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.version.$ManifestVersion.json" } else { "https://aka.ms/winget-manifest.version.$ManifestVersion.schema.json" } + defaultLocale = if ($useDirectSchemaLink) { "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.defaultLocale.$ManifestVersion.json" } else { "https://aka.ms/winget-manifest.defaultLocale.$ManifestVersion.schema.json" } + locale = if ($useDirectSchemaLink) { "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.locale.$ManifestVersion.json" } else { "https://aka.ms/winget-manifest.locale.$ManifestVersion.schema.json" } + installer = if ($useDirectSchemaLink) { "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.installer.$ManifestVersion.json" } else { "https://aka.ms/winget-manifest.installer.$ManifestVersion.schema.json" } +} + # Fetch Schema data from github for entry validation, key ordering, and automatic commenting try { - $ProgressPreference = 'SilentlyContinue' - $LocaleSchema = @(Invoke-WebRequest "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.defaultLocale.$ManifestVersion.json" -UseBasicParsing | ConvertFrom-Json) + $LocaleSchema = @(Invoke-WebRequest $SchemaUrls.defaultLocale -UseBasicParsing | ConvertFrom-Json) $LocaleProperties = (ConvertTo-Yaml $LocaleSchema.properties | ConvertFrom-Yaml -Ordered).Keys - $VersionSchema = @(Invoke-WebRequest "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.version.$ManifestVersion.json" -UseBasicParsing | ConvertFrom-Json) + $VersionSchema = @(Invoke-WebRequest $SchemaUrls.version -UseBasicParsing | ConvertFrom-Json) $VersionProperties = (ConvertTo-Yaml $VersionSchema.properties | ConvertFrom-Yaml -Ordered).Keys - $InstallerSchema = @(Invoke-WebRequest "https://raw.githubusercontent.com/microsoft/winget-cli/master/schemas/JSON/manifests/v$ManifestVersion/manifest.installer.$ManifestVersion.json" -UseBasicParsing | ConvertFrom-Json) + $InstallerSchema = @(Invoke-WebRequest $SchemaUrls.installer -UseBasicParsing | ConvertFrom-Json) $InstallerProperties = (ConvertTo-Yaml $InstallerSchema.properties | ConvertFrom-Yaml -Ordered).Keys $InstallerSwitchProperties = (ConvertTo-Yaml $InstallerSchema.definitions.InstallerSwitches.properties | ConvertFrom-Yaml -Ordered).Keys $InstallerEntryProperties = (ConvertTo-Yaml $InstallerSchema.definitions.Installer.properties | ConvertFrom-Yaml -Ordered).Keys @@ -34,6 +42,10 @@ filter TrimString { $_.Trim() } +filter RightTrimString { + $_.TrimEnd() +} + filter UniqueItems { [string]$($_.Split(',').Trim() | Select-Object -Unique) } @@ -50,50 +62,56 @@ $ToNatural = { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) } # Various patterns used in validation to simplify the validation logic $Patterns = @{ - PackageIdentifier = $VersionSchema.properties.PackageIdentifier.pattern - IdentifierMaxLength = $VersionSchema.properties.PackageIdentifier.maxLength - PackageVersion = $InstallerSchema.definitions.PackageVersion.pattern - VersionMaxLength = $VersionSchema.properties.PackageVersion.maxLength - InstallerSha256 = $InstallerSchema.definitions.Installer.properties.InstallerSha256.pattern - InstallerUrl = $InstallerSchema.definitions.Installer.properties.InstallerUrl.pattern - InstallerUrlMaxLength = $InstallerSchema.definitions.Installer.properties.InstallerUrl.maxLength - ValidArchitectures = $InstallerSchema.definitions.Architecture.enum - ValidInstallerTypes = $InstallerSchema.definitions.InstallerType.enum - SilentSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.Silent.maxLength - ProgressSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.SilentWithProgress.maxLength - CustomSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.Custom.maxLength - SignatureSha256 = $InstallerSchema.definitions.Installer.properties.SignatureSha256.pattern - FamilyName = $InstallerSchema.definitions.PackageFamilyName.pattern - FamilyNameMaxLength = $InstallerSchema.definitions.PackageFamilyName.maxLength - PackageLocale = $LocaleSchema.properties.PackageLocale.pattern - InstallerLocaleMaxLength = $InstallerSchema.definitions.Locale.maxLength - ProductCodeMinLength = $InstallerSchema.definitions.ProductCode.minLength - ProductCodeMaxLength = $InstallerSchema.definitions.ProductCode.maxLength - MaxItemsFileExtensions = $InstallerSchema.definitions.FileExtensions.maxItems - MaxItemsProtocols = $InstallerSchema.definitions.Protocols.maxItems - MaxItemsCommands = $InstallerSchema.definitions.Commands.maxItems - MaxItemsSuccessCodes = $InstallerSchema.definitions.InstallerSuccessCodes.maxItems - MaxItemsInstallModes = $InstallerSchema.definitions.InstallModes.maxItems - PackageLocaleMaxLength = $LocaleSchema.properties.PackageLocale.maxLength - PublisherMaxLength = $LocaleSchema.properties.Publisher.maxLength - PackageNameMaxLength = $LocaleSchema.properties.PackageName.maxLength - MonikerMaxLength = $LocaleSchema.definitions.Tag.maxLength - GenericUrl = $LocaleSchema.definitions.Url.pattern - GenericUrlMaxLength = $LocaleSchema.definitions.Url.maxLength - AuthorMinLength = $LocaleSchema.properties.Author.minLength - AuthorMaxLength = $LocaleSchema.properties.Author.maxLength - LicenseMaxLength = $LocaleSchema.properties.License.maxLength - CopyrightMinLength = $LocaleSchema.properties.Copyright.minLength - CopyrightMaxLength = $LocaleSchema.properties.Copyright.maxLength - TagsMaxItems = $LocaleSchema.properties.Tags.maxItems - ShortDescriptionMaxLength = $LocaleSchema.properties.ShortDescription.maxLength - DescriptionMinLength = $LocaleSchema.properties.Description.minLength - DescriptionMaxLength = $LocaleSchema.properties.Description.maxLength - ValidInstallModes = $InstallerSchema.definitions.InstallModes.items.enum - FileExtension = $InstallerSchema.definitions.FileExtensions.items.pattern - FileExtensionMaxLength = $InstallerSchema.definitions.FileExtensions.items.maxLength - ReleaseNotesMinLength = $LocaleSchema.properties.ReleaseNotes.MinLength - ReleaseNotesMaxLength = $LocaleSchema.properties.ReleaseNotes.MaxLength + PackageIdentifier = $VersionSchema.properties.PackageIdentifier.pattern + IdentifierMaxLength = $VersionSchema.properties.PackageIdentifier.maxLength + PackageVersion = $InstallerSchema.definitions.PackageVersion.pattern + VersionMaxLength = $VersionSchema.properties.PackageVersion.maxLength + InstallerSha256 = $InstallerSchema.definitions.Installer.properties.InstallerSha256.pattern + InstallerUrl = $InstallerSchema.definitions.Installer.properties.InstallerUrl.pattern + InstallerUrlMaxLength = $InstallerSchema.definitions.Installer.properties.InstallerUrl.maxLength + ValidArchitectures = $InstallerSchema.definitions.Architecture.enum + ValidInstallerTypes = $InstallerSchema.definitions.InstallerType.enum + ValidNestedInstallerTypes = $InstallerSchema.definitions.NestedInstallerType.enum + SilentSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.Silent.maxLength + ProgressSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.SilentWithProgress.maxLength + CustomSwitchMaxLength = $InstallerSchema.definitions.InstallerSwitches.properties.Custom.maxLength + SignatureSha256 = $InstallerSchema.definitions.Installer.properties.SignatureSha256.pattern + FamilyName = $InstallerSchema.definitions.PackageFamilyName.pattern + FamilyNameMaxLength = $InstallerSchema.definitions.PackageFamilyName.maxLength + PackageLocale = $LocaleSchema.properties.PackageLocale.pattern + InstallerLocaleMaxLength = $InstallerSchema.definitions.Locale.maxLength + ProductCodeMinLength = $InstallerSchema.definitions.ProductCode.minLength + ProductCodeMaxLength = $InstallerSchema.definitions.ProductCode.maxLength + MaxItemsFileExtensions = $InstallerSchema.definitions.FileExtensions.maxItems + MaxItemsProtocols = $InstallerSchema.definitions.Protocols.maxItems + MaxItemsCommands = $InstallerSchema.definitions.Commands.maxItems + MaxItemsSuccessCodes = $InstallerSchema.definitions.InstallerSuccessCodes.maxItems + MaxItemsInstallModes = $InstallerSchema.definitions.InstallModes.maxItems + PackageLocaleMaxLength = $LocaleSchema.properties.PackageLocale.maxLength + PublisherMaxLength = $LocaleSchema.properties.Publisher.maxLength + PackageNameMaxLength = $LocaleSchema.properties.PackageName.maxLength + MonikerMaxLength = $LocaleSchema.definitions.Tag.maxLength + GenericUrl = $LocaleSchema.definitions.Url.pattern + GenericUrlMaxLength = $LocaleSchema.definitions.Url.maxLength + AuthorMinLength = $LocaleSchema.properties.Author.minLength + AuthorMaxLength = $LocaleSchema.properties.Author.maxLength + LicenseMaxLength = $LocaleSchema.properties.License.maxLength + CopyrightMinLength = $LocaleSchema.properties.Copyright.minLength + CopyrightMaxLength = $LocaleSchema.properties.Copyright.maxLength + TagsMaxItems = $LocaleSchema.properties.Tags.maxItems + ShortDescriptionMaxLength = $LocaleSchema.properties.ShortDescription.maxLength + DescriptionMinLength = $LocaleSchema.properties.Description.minLength + DescriptionMaxLength = $LocaleSchema.properties.Description.maxLength + ValidInstallModes = $InstallerSchema.definitions.InstallModes.items.enum + FileExtension = $InstallerSchema.definitions.FileExtensions.items.pattern + FileExtensionMaxLength = $InstallerSchema.definitions.FileExtensions.items.maxLength + ReleaseNotesMinLength = $LocaleSchema.properties.ReleaseNotes.MinLength + ReleaseNotesMaxLength = $LocaleSchema.properties.ReleaseNotes.MaxLength + RelativeFilePathMinLength = $InstallerSchema.Definitions.NestedInstallerFiles.items.properties.RelativeFilePath.minLength + RelativeFilePathMaxLength = $InstallerSchema.Definitions.NestedInstallerFiles.items.properties.RelativeFilePath.maxLength + PortableCommandAliasMinLength = $InstallerSchema.Definitions.NestedInstallerFiles.items.properties.PortableCommandAlias.minLength + PortableCommandAliasMaxLength = $InstallerSchema.Definitions.NestedInstallerFiles.items.properties.PortableCommandAlias.maxLength + ArchiveInstallerTypes = @('zip') } # This function validates whether a string matches Minimum Length, Maximum Length, and Regex pattern @@ -360,9 +378,13 @@ Function Restore-YamlKeyOrder { 'PackageFamilyName' 'InstallerLocale' 'InstallerType' + 'NestedInstallerType' + 'NestedInstallerFiles' 'Scope' 'UpgradeBehavior' 'Dependencies' + 'InstallationMetadata' + 'Platform' ) $_Temp = [ordered] @{} @@ -445,13 +467,17 @@ Function Write-VersionManifest { # Create the folder for the file if it doesn't exist New-Item -ItemType 'Directory' -Force -Path $AppFolder | Out-Null - $VersionManifestPath = $AppFolder + "\$PackageIdentifier" + '.yaml' + $script:VersionManifestPath = Join-Path $AppFolder -ChildPath "$PackageIdentifier.yaml" # Write the manifest to the file - $ScriptHeader + " `$debug=QUSU.$($PSVersionTable.PSVersion -Replace '\.', '-')`n# yaml-language-server: `$schema=https://aka.ms/winget-manifest.version.$ManifestVersion.schema.json`n" > $VersionManifestPath + $ScriptHeader + " `$debug=QUSU.$(switch (([System.Environment]::NewLine).Length) { + 1 { 'LF' } + 2 { 'CRLF' } + Default { 'XX' } + }).$($PSVersionTable.PSVersion -Replace '\.', '-')`n# yaml-language-server: `$schema=https://aka.ms/winget-manifest.version.$ManifestVersion.schema.json`n" > $VersionManifestPath ConvertTo-Yaml $VersionManifest >> $VersionManifestPath $(Get-Content $VersionManifestPath -Encoding UTF8) -replace "(.*)$([char]0x2370)", "# `$1" | Out-File -FilePath $VersionManifestPath -Force - $MyRawString = Get-Content -Raw $VersionManifestPath | TrimString + $MyRawString = Get-Content $VersionManifestPath | RightTrimString | Select-Object -SkipLast 1 # Skip the last one because it will always just be an empty newline [System.IO.File]::WriteAllLines($VersionManifestPath, $MyRawString, $Utf8NoBomEncoding) # Tell user the file was created and the path to the file @@ -470,7 +496,11 @@ Function Write-InstallerManifest { # Add the properties to the manifest Add-YamlParameter -Object $InstallerManifest -Parameter 'PackageIdentifier' -Value $PackageIdentifier Add-YamlParameter -Object $InstallerManifest -Parameter 'PackageVersion' -Value $PackageVersion - $InstallerManifest['MinimumOSVersion'] = If ($MinimumOSVersion) { $MinimumOSVersion } Else { '10.0.0.0' } + If ($MinimumOSVersion) { + $InstallerManifest['MinimumOSVersion'] = $MinimumOSVersion + } Else { + If ($InstallerManifest['MinimumOSVersion']) { $_InstallerManifest.Remove('MinimumOSVersion') } + } $_ListSections = [ordered]@{ 'FileExtensions' = $FileExtensions @@ -501,7 +531,7 @@ Function Write-InstallerManifest { $InstallerManifest['Dependencies'] = Restore-YamlKeyOrder $InstallerManifest['Dependencies'] $InstallerDependencyProperties -NoComments } # Move Installer Level Keys to Manifest Level - $_KeysToMove = $InstallerEntryProperties | Where-Object { $_ -in $InstallerProperties -and $_ -ne 'ProductCode' } + $_KeysToMove = $InstallerEntryProperties | Where-Object { $_ -in $InstallerProperties -and $_ -notin @('ProductCode', 'NestedInstallerFiles', 'NestedInstallerType') } foreach ($_Key in $_KeysToMove) { if ($_Key -in $InstallerManifest.Installers[0].Keys) { # Handle the switches specially @@ -570,13 +600,17 @@ Function Write-InstallerManifest { # Create the folder for the file if it doesn't exist New-Item -ItemType 'Directory' -Force -Path $AppFolder | Out-Null - $script:InstallerManifestPath = $AppFolder + "\$PackageIdentifier" + '.installer' + '.yaml' + $script:InstallerManifestPath = Join-Path $AppFolder -ChildPath "$PackageIdentifier.installer.yaml" # Write the manifest to the file - $ScriptHeader + " `$debug=QUSU.$($PSVersionTable.PSVersion -Replace '\.', '-')`n# yaml-language-server: `$schema=https://aka.ms/winget-manifest.installer.$ManifestVersion.schema.json`n" > $InstallerManifestPath + $ScriptHeader + " `$debug=QUSU.$(switch (([System.Environment]::NewLine).Length) { + 1 { 'LF' } + 2 { 'CRLF' } + Default { 'XX' } + }).$($PSVersionTable.PSVersion -Replace '\.', '-')`n# yaml-language-server: `$schema=https://aka.ms/winget-manifest.installer.$ManifestVersion.schema.json`n" > $InstallerManifestPath ConvertTo-Yaml $InstallerManifest >> $InstallerManifestPath $(Get-Content $InstallerManifestPath -Encoding UTF8) -replace "(.*)$([char]0x2370)", "# `$1" | Out-File -FilePath $InstallerManifestPath -Force - $MyRawString = Get-Content -Raw $InstallerManifestPath | TrimString + $MyRawString = Get-Content $InstallerManifestPath | RightTrimString | Select-Object -SkipLast 1 # Skip the last one because it will always just be an empty newline [System.IO.File]::WriteAllLines($InstallerManifestPath, $MyRawString, $Utf8NoBomEncoding) # Tell user the file was created and the path to the file @@ -628,7 +662,7 @@ Function Write-LocaleManifest { # Clean up the volatile fields if ($LocaleManifest['ReleaseNotes'] -and (Test-String $script:ReleaseNotes -IsNull)) { $LocaleManifest.Remove('ReleaseNotes') } - if ($LocaleManifest['ReleaseNotesUrl'] -and (Test-String $script:ReleaseNotes -IsNull)) { $LocaleManifest.Remove('ReleaseNotesUrl') } + if ($LocaleManifest['ReleaseNotesUrl'] -and (Test-String $script:ReleaseNotesUrl -IsNull)) { $LocaleManifest.Remove('ReleaseNotesUrl') } if ($InputKeys -contains 'Locales') { $InputLocales = ($InputObject.Locales | Get-Member | Where-Object { $_.MemberType -eq 'NoteProperty' }).Name } foreach ($_Key in $LocaleProperties) { if ($InputKeys -contains $_Key) { $LocaleManifest[$_Key] = $InputObject.$_Key } } @@ -640,17 +674,21 @@ Function Write-LocaleManifest { $LocaleManifest = Restore-YamlKeyOrder $LocaleManifest $LocaleProperties # Set the appropriate langage server depending on if it is a default locale file or generic locale file - if ($LocaleManifest.ManifestType -eq 'defaultLocale') { $yamlServer = "# yaml-language-server: `$schema=https://aka.ms/winget-manifest.defaultLocale.$ManifestVersion.schema.json" } else { $yamlServer = "# yaml-language-server: `$schema=https://aka.ms/winget-manifest.locale.$ManifestVersion.schema.json" } + if ($LocaleManifest.ManifestType -eq 'defaultLocale') { $yamlServer = "# yaml-language-server: `$schema=$($SchemaUrls.defaultLocale)" } else { $yamlServer = "# yaml-language-server: `$schema=$($SchemaUrls.locale)" } # Create the folder for the file if it doesn't exist New-Item -ItemType 'Directory' -Force -Path $AppFolder | Out-Null - $script:LocaleManifestPath = $AppFolder + "\$PackageIdentifier" + '.locale.' + "$PackageLocale" + '.yaml' + $script:LocaleManifestPath = Join-Path $AppFolder -ChildPath "$PackageIdentifier.locale.$PackageLocale.yaml" # Write the manifest to the file - $ScriptHeader + " `$debug=QUSU.$($PSVersionTable.PSVersion -Replace '\.', '-')`n$yamlServer`n" > $LocaleManifestPath + $ScriptHeader + " `$debug=QUSU.$(switch (([System.Environment]::NewLine).Length) { + 1 { 'LF' } + 2 { 'CRLF' } + Default { 'XX' } + }).$($PSVersionTable.PSVersion -Replace '\.', '-')`n$yamlServer`n" > $LocaleManifestPath ConvertTo-Yaml $LocaleManifest >> $LocaleManifestPath $(Get-Content $LocaleManifestPath -Encoding UTF8) -replace "(.*)$([char]0x2370)", "# `$1" | Out-File -FilePath $LocaleManifestPath -Force - $MyRawString = Get-Content -Raw $LocaleManifestPath | TrimString + $MyRawString = Get-Content $LocaleManifestPath | RightTrimString | Select-Object -SkipLast 1 # Skip the last one because it will always just be an empty newline [System.IO.File]::WriteAllLines($LocaleManifestPath, $MyRawString, $Utf8NoBomEncoding) # Copy over all locale files from previous version that aren't the same @@ -667,17 +705,21 @@ Function Write-LocaleManifest { # Clean up the volatile fields if ($OldLocaleManifest['ReleaseNotes'] -and (Test-String $script:ReleaseNotes -IsNull)) { $OldLocaleManifest.Remove('ReleaseNotes') } - if ($OldLocaleManifest['ReleaseNotesUrl'] -and (Test-String $script:ReleaseNotes -IsNull)) { $OldLocaleManifest.Remove('ReleaseNotesUrl') } + if ($OldLocaleManifest['ReleaseNotesUrl'] -and (Test-String $script:ReleaseNotesUrl -IsNull)) { $OldLocaleManifest.Remove('ReleaseNotesUrl') } $script:OldLocaleManifest = Restore-YamlKeyOrder $script:OldLocaleManifest $LocaleProperties $yamlServer = "# yaml-language-server: `$schema=https://aka.ms/winget-manifest.locale.$ManifestVersion.schema.json" - $ScriptHeader + " `$debug=QUSU.$($PSVersionTable.PSVersion -Replace '\.', '-')`n$yamlServer`n" > ($AppFolder + '\' + $DifLocale.Name) - ConvertTo-Yaml $OldLocaleManifest >> ($AppFolder + '\' + $DifLocale.Name) - $(Get-Content $($AppFolder + '\' + $DifLocale.Name) -Encoding UTF8) -replace "(.*)$([char]0x2370)", "# `$1" | Out-File -FilePath $($AppFolder + '\' + $DifLocale.Name) -Force - $MyRawString = Get-Content -Raw $($AppFolder + '\' + $DifLocale.Name) | TrimString - [System.IO.File]::WriteAllLines($($AppFolder + '\' + $DifLocale.Name), $MyRawString, $Utf8NoBomEncoding) + $ScriptHeader + " `$debug=QUSU.$(switch (([System.Environment]::NewLine).Length) { + 1 { 'LF' } + 2 { 'CRLF' } + Default { 'XX' } + }).$($PSVersionTable.PSVersion -Replace '\.', '-')`n$yamlServer`n" > ($AppFolder + '\' + $DifLocale.Name) + ConvertTo-Yaml $OldLocaleManifest >> (Join-Path $AppFolder -ChildPath $DifLocale.Name) + $(Get-Content $(Join-Path $AppFolder -ChildPath $DifLocale.Name) -Encoding UTF8) -replace "(.*)$([char]0x2370)", "# `$1" | Out-File -FilePath $(Join-Path $AppFolder -ChildPath $DifLocale.Name) -Force + $MyRawString = Get-Content $(Join-Path $AppFolder -ChildPath $DifLocale.Name) | RightTrimString | Select-Object -SkipLast 1 # Skip the last one because it will always just be an empty newline + [System.IO.File]::WriteAllLines($(Join-Path $AppFolder -ChildPath $DifLocale.Name), $MyRawString, $Utf8NoBomEncoding) } } } @@ -687,20 +729,6 @@ Function Write-LocaleManifest { Write-Host "Yaml file created: $LocaleManifestPath" } -function Remove-ManifestVersion { - [CmdletBinding(SupportsShouldProcess)] - Param( - [Parameter(Mandatory = $true, Position = 1)] - [string] $PathToVersion - ) - - # Remove the manifest, and then any parent folders so long as the parent folders are empty - do { - Remove-Item -Path $PathToVersion -Recurse -Force - $PathToVersion = Split-Path $PathToVersion - } while (@(Get-ChildItem $PathToVersion).Count -eq 0) -} - ## START OF MAIN SCRIPT ## # Initialize the return value to be a success @@ -744,7 +772,7 @@ if ($script:Option -in @('NewLocale'; 'EditMetadata'; 'RemoveManifest')) { } # If a new version is entered, we need to be sure to update the folder for writing manifests $LastVersion = $PromptVersion - $script:AppFolder = (Split-Path $AppFolder) + "\$LastVersion" + $script:AppFolder = Join-Path (Split-Path $AppFolder) -ChildPath $LastVersion $script:PackageVersion = $LastVersion } } @@ -752,7 +780,7 @@ if ($script:Option -in @('NewLocale'; 'EditMetadata'; 'RemoveManifest')) { # If the user selected `QuickUpdateVersion`, the old manifests must exist # If the user selected `New`, the old manifest type is specified as none if (-not (Test-Path -Path "$AppFolder\..")) { - throw 'This option requires manifest of previous version of the package. If you want to create a new package, please select Option 1.'; exit + throw 'This option requires manifest of previous version of the package. If you want to create a new package, please select Option 1.' $script:OldManifestType = 'None' } @@ -881,7 +909,7 @@ if ($OldManifests -and $Option -ne 'NewLocale') { 'ShortDescription'; 'Description' 'Channel' 'Platform'; 'MinimumOSVersion' - 'InstallerType' + 'InstallerType'; 'NestedInstallerType' 'Scope' 'UpgradeBehavior' 'PackageFamilyName'; 'ProductCode' @@ -896,7 +924,12 @@ if ($OldManifests -and $Option -ne 'NewLocale') { } } -# Run the data entry and creation of manifests +# If the old manifests exist, make sure to use the same casing as the existing package identifier +if ($OldManifests) { + $script:PackageIdentifier = $OldManifests.Where({ $_.Name -like "$PackageIdentifier.yaml" }).BaseName +} + +# Run the data entry and creation of manifests appropriate to the option the user selected $script:InputKeys = ($InputObject | Get-Member | Where-Object { $_.MemberType -eq 'NoteProperty' }).Name $InputObject.InstallerUrls = Sort-Object -InputObject $InputObject.InstallerUrls if (-not $InputObject.InstallerUrls.GetType().IsArray) { @@ -1029,7 +1062,12 @@ Write-InstallerManifest Write-VersionManifest # Delete previous manifests if $InputObject.DeletePreviousVersion is true if ($InputObject.DeletePreviousVersion) { - Remove-ManifestVersion "$AppFolder\..\$LastVersion" + $PathToVersion = "$AppFolder\..\$LastVersion" + # Remove the manifest, and then any parent folders so long as the parent folders are empty + do { + Remove-Item -Path $PathToVersion -Recurse -Force + $PathToVersion = Split-Path $PathToVersion + } while (@(Get-ChildItem $PathToVersion).Count -eq 0) } # If the user has winget installed, attempt to validate the manifests diff --git a/index.js b/src/main.ts similarity index 81% rename from index.js rename to src/main.ts index 3d3592b..fe5e6da 100644 --- a/index.js +++ b/src/main.ts @@ -1,11 +1,11 @@ -const { getInput, info, getBooleanInput, error } = require('@actions/core'); -const { context, getOctokit } = require('@actions/github'); -const { execSync } = require('child_process'); -const { resolve } = require('path'); +import { getInput, info, getBooleanInput, error } from '@actions/core'; +import { context, getOctokit } from '@actions/github'; +import { execSync } from 'child_process'; +import { resolve } from 'path'; (async () => { // check if the runner operating system is windows - if (process.platform != 'win32') { + if (process.platform !== 'win32') { error('This action only works on Windows.'); process.exit(1); } @@ -21,7 +21,7 @@ const { resolve } = require('path'); const forkUser = getInput('fork-user'); // get only data, and exclude status, url, and headers - releaseInfo = { + const releaseInfo = { ...( await getOctokit(token).rest.repos.getReleaseByTag({ owner: context.repo.owner, @@ -35,46 +35,46 @@ const { resolve } = require('path'); // install powershell-yaml, clone winget-pkgs repo and configure remotes, update yamlcreate, and // download wingetdev from vedantmgoyal2009/vedantmgoyal2009 (winget-pkgs-automation) info( - `::group::Install powershell-yaml, clone winget-pkgs and configure remotes, update YamlCreate, download wingetdev...` + `::group::Install powershell-yaml, clone winget-pkgs and configure remotes, update YamlCreate, download wingetdev...`, ); execSync( `Install-Module -Name powershell-yaml -Repository PSGallery -Scope CurrentUser -Force`, - { shell: 'pwsh', stdio: 'inherit' } + { shell: 'pwsh', stdio: 'inherit' }, ); // remove winget-pkgs directory if it exists, in case the action is run multiple times for // publishing multiple packages in the same workflow execSync( `If (Test-Path -Path .\\winget-pkgs\\) { Remove-Item -Path .\\winget-pkgs\\ -Recurse -Force -ErrorAction SilentlyContinue }`, - { shell: 'pwsh', stdio: 'inherit' } + { shell: 'pwsh', stdio: 'inherit' }, ); execSync( `git clone https://x-access-token:${token}@github.com/microsoft/winget-pkgs.git`, - { stdio: 'inherit' } + { stdio: 'inherit' }, ); execSync(`git -C winget-pkgs config --local user.name github-actions`, { stdio: 'inherit', }); execSync( `git -C winget-pkgs config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, - { stdio: 'inherit' } + { stdio: 'inherit' }, ); execSync(`git -C winget-pkgs remote rename origin upstream`, { stdio: 'inherit', }); execSync( `git -C winget-pkgs remote add origin https://github.com/${forkUser}/winget-pkgs.git`, - { stdio: 'inherit' } + { stdio: 'inherit' }, ); execSync( - `Invoke-WebRequest -Uri https://github.com/vedantmgoyal2009/winget-releaser/raw/${process.env.GITHUB_ACTION_REF}/YamlCreate.ps1 -OutFile .\\winget-pkgs\\Tools\\YamlCreate.ps1`, - { shell: 'pwsh', stdio: 'inherit' } + `Invoke-WebRequest -Uri https://github.com/vedantmgoyal2009/winget-releaser/raw/${process.env.GITHUB_ACTION_REF}/src/YamlCreate.ps1 -OutFile .\\winget-pkgs\\Tools\\YamlCreate.ps1`, + { shell: 'pwsh', stdio: 'inherit' }, ); execSync(`git -C winget-pkgs commit --all -m \"Update YamlCreate.ps1\"`, { stdio: 'inherit', }); execSync( `svn checkout https://github.com/vedantmgoyal2009/vedantmgoyal2009/trunk/tools/wingetdev`, - { stdio: 'inherit' } + { stdio: 'inherit' }, ); info(`::endgroup::`); @@ -85,7 +85,7 @@ const { resolve } = require('path'); const inputObject = JSON.stringify({ PackageIdentifier: pkgid, PackageVersion: - version || new RegExp(/(?<=v).*/g).exec(releaseInfo.tag_name)[0], + version || new RegExp(/(?<=v).*/g).exec(releaseInfo.tag_name)![0], InstallerUrls: releaseInfo.assets .filter((asset) => { return new RegExp(instRegex, 'g').test(asset.name); @@ -94,7 +94,7 @@ const { resolve } = require('path'); return asset.browser_download_url; }), ReleaseNotesUrl: releaseInfo.html_url, - ReleaseDate: new Date(releaseInfo.published_at).toISOString().slice(0, 10), + ReleaseDate: new Date(releaseInfo.published_at!).toISOString().slice(0, 10), DeletePreviousVersion: delPrevVersion, }); execSync(`.\\YamlCreate.ps1 \'${inputObject}\'`, { @@ -107,7 +107,7 @@ const { resolve } = require('path'); info(`::group::Checking for action updates...`); // check if action version is a version (starts with `v`) and not a pinned commit ref - if (/^v\d+$/g.test(process.env.GITHUB_ACTION_REF)) { + if (/^v\d+$/g.test(process.env.GITHUB_ACTION_REF!)) { const latestVersion = ( await getOctokit(token).rest.repos.getLatestRelease({ owner: 'vedantmgoyal2009', @@ -119,20 +119,20 @@ const { resolve } = require('path'); info(`Latest version found: ${latestVersion}`); // if the latest version is greater than the current version, then update the action - if (latestVersion > process.env.GITHUB_ACTION_REF) { + if (latestVersion > process.env.GITHUB_ACTION_REF!) { execSync( `git clone https://x-access-token:${token}@github.com/${process.env.GITHUB_REPOSITORY}.git`, { stdio: 'inherit', - } + }, ); execSync(`git config --local user.name github-actions`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + cwd: process.env.GITHUB_REPOSITORY!.split('/')[1], }); execSync( `git config --local user.email 41898282+github-actions[bot]@users.noreply.github.com`, - { stdio: 'inherit', cwd: process.env.GITHUB_REPOSITORY.split('/')[1] } + { stdio: 'inherit', cwd: process.env.GITHUB_REPOSITORY!.split('/')[1] }, ); // replace the version in the workflow file using `find` and `sed` execSync( @@ -140,50 +140,50 @@ const { resolve } = require('path'); { stdio: 'inherit', cwd: `${ - process.env.GITHUB_REPOSITORY.split('/')[1] + process.env.GITHUB_REPOSITORY!.split('/')[1] }/.github/workflows`, shell: 'bash', - } + }, ); // create a new branch, commit and push the changes, and create a pull request execSync( `git commit --all -m \"ci(winget-releaser): update action from ${process.env.GITHUB_ACTION_REF} to ${latestVersion}\"`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - } + cwd: process.env.GITHUB_REPOSITORY!.split('/')[1], + }, ); execSync(`git switch -c winget-releaser/update-to-${latestVersion}`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + cwd: process.env.GITHUB_REPOSITORY!.split('/')[1], }); execSync( `git push --force-with-lease --set-upstream origin winget-releaser/update-to-${latestVersion}`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], - } + cwd: process.env.GITHUB_REPOSITORY!.split('/')[1], + }, ); execSync( `@\" -This PR was automatically created by the [WinGet Releaser GitHub Action](https://github.com/vedantmgoyal2009/winget-releaser) to update the action version from \`${process.env.GITHUB_ACTION_REF}\` to \`${newVersion}\`.\`r\`n +This PR was automatically created by the [WinGet Releaser GitHub Action](https://github.com/vedantmgoyal2009/winget-releaser) to update the action version from \`${process.env.GITHUB_ACTION_REF}\` to \`${latestVersion}\`.\`r\`n The auto-update function help maintainers keep their workflows up-to-date with the latest version of the action.\`r\`n You can close this pull request if you don't want to update the action version.\`r\`n Mentioning @vedantmgoyal2009 for a second pair of eyes, in case any breaking changes have been introduced in the new version of the action. \"@ | gh pr create --fill --body-file -`, { stdio: 'inherit', - cwd: process.env.GITHUB_REPOSITORY.split('/')[1], + cwd: process.env.GITHUB_REPOSITORY!.split('/')[1], shell: 'pwsh', env: { ...process.env, GH_TOKEN: token }, // set GH_TOKEN env variable for GitHub CLI (gh) - } + }, ); } else { info(`No updates found. Bye bye!`); } } else { info( - `The workflow maintainer has pinned the action to a commit ref. Skipping update check...` + `The workflow maintainer has pinned the action to a commit ref. Skipping update check...`, ); } info(`::endgroup::`); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d5a2f78 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,104 @@ +{ + "exclude": ["node_modules"], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}