├── .codeclimate.yml ├── .eslintignore ├── .eslintrc.yml ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── having-a-question-.md ├── dependabot.yml └── workflows │ ├── auto-git-release-production.yml │ ├── auto-git-release-staging.yml │ ├── check-build-readme-code-snippet-example.yml │ ├── check-build.yml │ ├── run-integration-test.yml │ └── update-codeclimate-coverage.yml ├── .gitignore ├── .idea └── jsLibraryMappings.xml ├── .nvmrc ├── .prettierignore ├── .prettierrc.js ├── CHANGELOG.md ├── LICENSE ├── README.md ├── __tests__ └── main.test.ts ├── action.yml ├── github-action-runtime ├── LICENSE ├── index.js ├── index.js.map └── sourcemap-register.js ├── jest.config.js ├── jest.setup.js ├── lib ├── config.js ├── main.js ├── manageArtifacts.js └── types │ └── variableStatus.js ├── package.json ├── src ├── config.ts ├── main.ts ├── manageArtifacts.ts └── types │ └── variableStatus.ts ├── tsconfig.json └── yarn.lock /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | # XXX See https://docs.codeclimate.com/docs/advanced-configuration 2 | version: "2" 3 | checks: 4 | argument-count: 5 | enabled: true 6 | config: 7 | threshold: 4 8 | complex-logic: 9 | enabled: true 10 | config: 11 | threshold: 4 12 | file-lines: 13 | enabled: true 14 | config: 15 | threshold: 400 # 250 by default 16 | method-complexity: 17 | enabled: true 18 | config: 19 | threshold: 10 20 | method-count: 21 | enabled: true 22 | config: 23 | threshold: 20 24 | method-lines: 25 | enabled: true 26 | config: 27 | threshold: 200 # 25 by default 28 | nested-control-flow: 29 | enabled: true 30 | config: 31 | threshold: 4 32 | return-statements: 33 | enabled: true 34 | config: 35 | threshold: 4 36 | 37 | plugins: 38 | # eslint: # https://docs.codeclimate.com/docs/eslint 39 | # enabled: true 40 | # channel: "eslint-4" # Depends on installed ESLint version - See https://docs.codeclimate.com/docs/eslint#section-eslint-versions 41 | duplication: # https://docs.codeclimate.com/docs/duplication 42 | enabled: true 43 | config: 44 | languages: 45 | javascript: 46 | mass_threshold: 50 # See https://docs.codeclimate.com/docs/duplication#section-understand-the-engine 47 | fixme: # https://docs.codeclimate.com/docs/fixme 48 | enabled: true 49 | config: 50 | strings: # Skip "XXX" as we don't use it for things to fix but rather for highlighting comments (DX) 51 | - FIXME 52 | - BUG 53 | - TODO 54 | - HACK 55 | git-legal: # https://docs.codeclimate.com/docs/git-legal 56 | enabled: true 57 | # tslint: # https://docs.codeclimate.com/docs/tslint 58 | # enabled: true 59 | # config: tslint.json 60 | 61 | # See https://docs.codeclimate.com/docs/excluding-files-and-folders 62 | exclude_patterns: 63 | - "**/*.test.*" 64 | - "**/*.spec.*" 65 | - "__tests__/" 66 | - "lib/" 67 | 68 | # Default CC excluded paths: 69 | - "config/" 70 | - "db/" 71 | - "dist/" 72 | - "features/" 73 | - "**/node_modules/" 74 | - "script/" 75 | - "**/spec/" 76 | - "**/test/" 77 | - "**/tests/" 78 | - "**/vendor/" 79 | - "**/*.d.ts" 80 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | src/**/*.test* 4 | src/gql/** 5 | src/propTypes/** 6 | src/svg/** 7 | src/types/** 8 | src/components/svg/** 9 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | env: 3 | browser: true 4 | commonjs: true 5 | es6: true 6 | node: true 7 | extends: 8 | - plugin:@typescript-eslint/recommended 9 | globals: 10 | Atomics: readonly 11 | SharedArrayBuffer: readonly 12 | plugins: 13 | - jest 14 | parser: '@typescript-eslint/parser' 15 | parserOptions: 16 | project: ./tsconfig.json 17 | rules: # See https://eslint.org/docs/rules 18 | semi: 19 | - error 20 | - always # Always put commas, to avoid multilines git diff when new lines are added 21 | quotes: 22 | - error 23 | - single # Prefer simple quotes 24 | - allowTemplateLiterals: true # Allow the use of `` instead of '' and don't try to replace it, even when `` isn't needed 25 | comma-spacing: 26 | - error 27 | - before: false 28 | after: true 29 | indent: 30 | - error 31 | - 2 32 | - SwitchCase: 1 33 | arrow-parens: 34 | - error 35 | - always 36 | max-len: 0 # Disable line length checks, because the IDE is already configured to warn about it, and it's a waste of time to check for lines that are too long, especially in comments (like this one!) 37 | strict: 'off' 38 | no-console: 0 39 | allowArrowFunctions: 0 40 | no-unused-vars: 0 # Disabled, already handled by @typescript-eslint/no-unused-vars 41 | import/prefer-default-export: 0 # When there is only a single export from a module, don't enforce a default export, but rather let developer choose what's best 42 | no-else-return: 0 # Don't enforce, let developer choose. Sometimes we like to specifically use "return" for the sake of comprehensibility and avoid ambiguity 43 | no-underscore-dangle: 0 # Allow _ before/after variables and functions, convention for something meant to be "private" 44 | arrow-body-style: 0 # Don't enforce, let developer choose. Sometimes we like to specifically use "return" for ease of debugging and printing 45 | quote-props: 46 | - warn 47 | - consistent-as-needed # Enforce consistency with quotes on props, either all must be quoted, or all unquoted for a given object 48 | no-return-await: 0 # Useful before, but recent node.js enhancements make it useless on node 12+ (we use 10, but still, for consistency) - Read https://stackoverflow.com/questions/44806135/why-no-return-await-vs-const-x-await 49 | no-extra-boolean-cast: 0 # Don't enforce, let developer choose. Using "!!!" is sometimes useful (edge cases), and has a semantic value (dev intention) 50 | object-curly-newline: 51 | - warn 52 | - ObjectExpression: 53 | multiline: true 54 | minProperties: 5 55 | consistent: true 56 | ObjectPattern: 57 | multiline: true 58 | minProperties: 5 59 | consistent: true 60 | ImportDeclaration: 61 | multiline: true 62 | minProperties: 8 # Doesn't play so well with webstorm, which wraps based on the number of chars in the row, not based on the number of props #sucks 63 | consistent: true 64 | ExportDeclaration: 65 | multiline: true 66 | minProperties: 5 67 | consistent: true 68 | linebreak-style: 69 | - error 70 | - unix 71 | '@typescript-eslint/ban-ts-comment': warn # ts-ignore are sometimes the only way to bypass a TS issue, we trust we will use them for good and not abuse them 72 | '@typescript-eslint/no-use-before-define': warn 73 | '@typescript-eslint/no-unused-vars': 74 | - warn 75 | - vars: 'all' # We don't want unused variables (noise) - XXX Note that this will be a duplicate of "no-unused-vars" rule 76 | args: 'none' # Sometimes it's useful to have unused arguments for later use, such as describing what args are available (DX) 77 | ignoreRestSiblings: true # Sometimes it's useful to have unused props for later use, such as describing what props are available (DX) 78 | '@typescript-eslint/ban-types': 79 | - error 80 | - extendDefaults: true 81 | types: 82 | '{}': false # Allow writing `type Props = {}` - See https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-632833366 83 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | dist/** -diff linguist-generated=true -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | liberapay: unlyEd 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/having-a-question-.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Having a question? 3 | about: Use the community Discussions 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please ask questions in the [Discussions](https://github.com/UnlyEd/github-action-store-variable/discussions)! :) 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Keeping your actions up to date with Dependabot 2 | # You can use Dependabot to keep the actions you use updated to the latest versions. 3 | # See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot#enabling-dependabot-version-updates-for-actions 4 | 5 | version: 2 6 | updates: 7 | # Enable version updates for npm 8 | - package-ecosystem: 'github-actions' 9 | # Look for `package.json` and `lock` files in the `root` directory 10 | directory: '/' 11 | # Check the npm registry for updates every day (weekdays) 12 | schedule: 13 | interval: 'daily' 14 | -------------------------------------------------------------------------------- /.github/workflows/auto-git-release-production.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Automatically tag and release when changes land on the "main" branch. 3 | # It uses "semantic-version" to resolve the next version to use, and then we use GitHub CLI to create or update the releases. 4 | # 5 | # See https://github.com/PaulHatch/semantic-version https://github.com/PaulHatch/semantic-version/tree/v5.0.2 6 | # See https://github.com/softprops/action-gh-release https://github.com/softprops/action-gh-release/tree/v1 7 | 8 | name: 'Auto release' 9 | on: 10 | push: 11 | branches: 12 | - main 13 | 14 | jobs: 15 | tag-and-release: 16 | runs-on: ubuntu-22.04 17 | steps: 18 | - name: Fetching all commits for the current branch 19 | uses: actions/checkout@v3 20 | with: 21 | fetch-depth: 0 # Force fetch all commits - See https://github.com/PaulHatch/semantic-version#important-note-regarding-the-checkout-action 22 | 23 | - run: "echo \"GITHUB_SHA: ${{ github.sha }}\"" 24 | 25 | # Outputs documentation: https://github.com/PaulHatch/semantic-version/blob/master/src/main.ts#L22-L33 26 | - name: Resolving next Release Candidate version using semantic-version 27 | uses: paulhatch/semantic-version@v5.0.3 28 | id: next_semantic_version 29 | with: # See https://github.com/PaulHatch/semantic-version#usage 30 | tag_prefix: "v" # The prefix to use to identify tags 31 | major_pattern: "(MAJOR)" # A string which, if present in a git commit, indicates that a change represents a major (breaking) change 32 | minor_pattern: "(MINOR)" # Same as above except indicating a minor change 33 | version_format: "${major}.${minor}.${patch}-rc.${increment}" # A string to determine the format of the version output 34 | bump_each_commit: true # If this input is set to true, every commit will be treated as a new version, bumping the patch, minor, or major version based on the commit message. 35 | 36 | - name: Printing semantic-version outputs (for debugging) 37 | run: | 38 | echo "Most useful outputs:" 39 | echo "Next version: ${{steps.next_semantic_version.outputs.version}}" 40 | echo "Next version tag: ${{steps.next_semantic_version.outputs.version_tag}}" 41 | echo -e "\n All outputs:" 42 | echo "version: ${{steps.next_semantic_version.outputs.version}}" 43 | echo "major: ${{steps.next_semantic_version.outputs.major}}" 44 | echo "minor: ${{steps.next_semantic_version.outputs.minor}}" 45 | echo "patch: ${{steps.next_semantic_version.outputs.patch}}" 46 | echo "increment: ${{steps.next_semantic_version.outputs.increment}}" 47 | echo "version_type: ${{steps.next_semantic_version.outputs.version_type}}" 48 | echo "changed: ${{steps.next_semantic_version.outputs.changed}}" 49 | echo "authors: ${{steps.next_semantic_version.outputs.authors}}" 50 | echo "version_tag: ${{steps.next_semantic_version.outputs.version_tag}}" 51 | echo "previous_commit: ${{steps.next_semantic_version.outputs.previous_commit}}" 52 | echo "current_commit: ${{steps.next_semantic_version.outputs.current_commit}}" 53 | 54 | - name: Creating Git release tag for the "${{steps.next_semantic_version.outputs.version_tag}}" version 55 | run: | 56 | gh release create ${{steps.next_semantic_version.outputs.version_tag}} \ 57 | --title "${{steps.next_semantic_version.outputs.version_tag}}" \ 58 | --latest \ 59 | --generate-notes \ 60 | --target "${{github.sha}}" 61 | env: 62 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 63 | 64 | # Check if the major version already exists (if it doesn't, we'll create it - if it does, we'll update it) 65 | - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}" exists 66 | uses: mukunku/tag-exists-action@v1.2.0 67 | id: majorTagExists 68 | with: # See https://github.com/mukunku/tag-exists-action#inputs 69 | tag: "v${{steps.next_semantic_version.outputs.major}}" 70 | 71 | - run: "echo \"Check if majorTagExists: ${{ steps.majorTagExists.outputs.exists }}\"" 72 | 73 | # See https://cli.github.com/manual/gh_release_create 74 | - name: Creating new release for the major "v${{steps.next_semantic_version.outputs.major}}" version 75 | if: ${{ steps.majorTagExists.outputs.exists == 'false' }} 76 | run: | 77 | gh release create v${{steps.next_semantic_version.outputs.major}} \ 78 | --title "v${{steps.next_semantic_version.outputs.major}} MAJOR release (auto-updated)" \ 79 | --generate-notes \ 80 | --target "${{github.sha}}" 81 | env: 82 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 83 | 84 | # See https://cli.github.com/manual/gh_release_edit 85 | - name: Recreating existing release for the major "v${{steps.next_semantic_version.outputs.major}}" version 86 | if: ${{ steps.majorTagExists.outputs.exists == 'true' }} 87 | run: | 88 | # Delete and create the release again 89 | gh release delete v${{steps.next_semantic_version.outputs.major}} --cleanup-tag --yes 90 | 91 | gh release create v${{steps.next_semantic_version.outputs.major}} \ 92 | --title "v${{steps.next_semantic_version.outputs.major}} MAJOR release (auto-updated)" \ 93 | --generate-notes \ 94 | --target "${{github.sha}}" 95 | env: 96 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 97 | 98 | # Check if the minor version already exists (if it doesn't, we'll create it - if it does, we'll update it) 99 | - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" exists 100 | uses: mukunku/tag-exists-action@v1.2.0 101 | id: minorTagExists 102 | with: # See https://github.com/mukunku/tag-exists-action#inputs 103 | tag: "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" 104 | 105 | - run: "echo \"Check if minorTagExists: ${{ steps.minorTagExists.outputs.exists }}\"" 106 | 107 | # See https://cli.github.com/manual/gh_release_create 108 | - name: Creating new release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" version 109 | if: ${{ steps.minorTagExists.outputs.exists == 'false' }} 110 | run: | 111 | gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} \ 112 | --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} MINOR release (auto-updated)" \ 113 | --generate-notes \ 114 | --target "${{github.sha}}" 115 | env: 116 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 117 | 118 | # See https://cli.github.com/manual/gh_release_edit 119 | - name: Recreating existing release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}" version 120 | if: ${{ steps.minorTagExists.outputs.exists == 'true' }} 121 | run: | 122 | # Delete and create the release again 123 | gh release delete v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} --cleanup-tag --yes 124 | 125 | gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} \ 126 | --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}} MINOR release (auto-updated)" \ 127 | --generate-notes \ 128 | --target "${{github.sha}}" 129 | env: 130 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 131 | -------------------------------------------------------------------------------- /.github/workflows/auto-git-release-staging.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Automatically tag and release when changes land on the "main" branch. 3 | # It uses "semantic-version" to resolve the next version to use, and then we use GitHub CLI to create or update the releases. 4 | # 5 | # See https://github.com/PaulHatch/semantic-version https://github.com/PaulHatch/semantic-version/tree/v5.0.2 6 | # See https://github.com/softprops/action-gh-release https://github.com/softprops/action-gh-release/tree/v1 7 | 8 | name: 'Auto release (release candidate)' 9 | on: 10 | push: 11 | branches-ignore: 12 | - main 13 | 14 | jobs: 15 | tag-and-release: 16 | runs-on: ubuntu-22.04 17 | steps: 18 | - name: Fetching all commits for the current branch 19 | uses: actions/checkout@v3 20 | with: 21 | fetch-depth: 0 # Force fetch all commits - See https://github.com/PaulHatch/semantic-version#important-note-regarding-the-checkout-action 22 | 23 | - run: "echo \"GITHUB_SHA: ${{ github.sha }}\"" 24 | 25 | # Outputs documentation: https://github.com/PaulHatch/semantic-version/blob/master/src/main.ts#L22-L33 26 | - name: Resolving next Release Candidate version using semantic-version 27 | uses: paulhatch/semantic-version@v5.0.3 28 | id: next_semantic_version 29 | with: # See https://github.com/PaulHatch/semantic-version#usage 30 | tag_prefix: "v" # The prefix to use to identify tags 31 | major_pattern: "(MAJOR)" # A string which, if present in a git commit, indicates that a change represents a major (breaking) change 32 | minor_pattern: "(MINOR)" # Same as above except indicating a minor change 33 | version_format: "${major}.${minor}.${patch}-rc.${increment}" # A string to determine the format of the version output 34 | bump_each_commit: false # If this input is set to true, every commit will be treated as a new version, bumping the patch, minor, or major version based on the commit message. 35 | 36 | - name: Printing semantic-version outputs (for debugging) 37 | run: | 38 | echo "Most useful outputs:" 39 | echo "Next version: ${{steps.next_semantic_version.outputs.version}}" 40 | echo "Next version tag: ${{steps.next_semantic_version.outputs.version_tag}}" 41 | echo -e "\n All outputs:" 42 | echo "version: ${{steps.next_semantic_version.outputs.version}}" 43 | echo "major: ${{steps.next_semantic_version.outputs.major}}" 44 | echo "minor: ${{steps.next_semantic_version.outputs.minor}}" 45 | echo "patch: ${{steps.next_semantic_version.outputs.patch}}" 46 | echo "increment: ${{steps.next_semantic_version.outputs.increment}}" 47 | echo "version_type: ${{steps.next_semantic_version.outputs.version_type}}" 48 | echo "changed: ${{steps.next_semantic_version.outputs.changed}}" 49 | echo "authors: ${{steps.next_semantic_version.outputs.authors}}" 50 | echo "version_tag: ${{steps.next_semantic_version.outputs.version_tag}}" 51 | echo "previous_commit: ${{steps.next_semantic_version.outputs.previous_commit}}" 52 | echo "current_commit: ${{steps.next_semantic_version.outputs.current_commit}}" 53 | 54 | # Check if the major version already exists (if it doesn't, we'll create it - if it does, we'll update it) 55 | - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}-rc" exists 56 | uses: mukunku/tag-exists-action@v1.2.0 57 | id: majorTagExists 58 | with: # See https://github.com/mukunku/tag-exists-action#inputs 59 | tag: "v${{steps.next_semantic_version.outputs.major}}-rc" 60 | 61 | - run: "echo \"Check if majorTagExists: ${{ steps.majorTagExists.outputs.exists }}\"" 62 | 63 | # See https://cli.github.com/manual/gh_release_create 64 | - name: Creating new release for the major "v${{steps.next_semantic_version.outputs.major}}-rc" version 65 | if: ${{ steps.majorTagExists.outputs.exists == 'false' }} 66 | run: | 67 | gh release create v${{steps.next_semantic_version.outputs.major}}-rc \ 68 | --title "v${{steps.next_semantic_version.outputs.major}}-rc MAJOR release (auto-updated)" \ 69 | --generate-notes \ 70 | --prerelease \ 71 | --target "${{github.sha}}" 72 | env: 73 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 74 | 75 | # See https://cli.github.com/manual/gh_release_edit 76 | - name: Recreating existing release for the major "v${{steps.next_semantic_version.outputs.major}}-rc" version 77 | if: ${{ steps.majorTagExists.outputs.exists == 'true' }} 78 | run: | 79 | # Delete and create the release again 80 | gh release delete v${{steps.next_semantic_version.outputs.major}}-rc --cleanup-tag --yes 81 | 82 | gh release create v${{steps.next_semantic_version.outputs.major}}-rc \ 83 | --title "v${{steps.next_semantic_version.outputs.major}}-rc MAJOR release (auto-updated)" \ 84 | --generate-notes \ 85 | --prerelease \ 86 | --target "${{github.sha}}" 87 | env: 88 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 89 | 90 | # Check if the minor version already exists (if it doesn't, we'll create it - if it does, we'll update it) 91 | - name: Check if tag "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" exists 92 | uses: mukunku/tag-exists-action@v1.2.0 93 | id: minorTagExists 94 | with: # See https://github.com/mukunku/tag-exists-action#inputs 95 | tag: "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" 96 | 97 | - run: "echo \"Check if minorTagExists: ${{ steps.minorTagExists.outputs.exists }}\"" 98 | 99 | # See https://cli.github.com/manual/gh_release_create 100 | - name: Creating new release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" version 101 | if: ${{ steps.minorTagExists.outputs.exists == 'false' }} 102 | run: | 103 | gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc \ 104 | --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc MINOR release (auto-updated)" \ 105 | --generate-notes \ 106 | --prerelease \ 107 | --target "${{github.sha}}" 108 | env: 109 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 110 | 111 | # See https://cli.github.com/manual/gh_release_edit 112 | - name: Recreating existing release for the minor "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc" version 113 | if: ${{ steps.minorTagExists.outputs.exists == 'true' }} 114 | run: | 115 | # Delete and create the release again 116 | gh release delete v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc --cleanup-tag --yes 117 | 118 | gh release create v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc \ 119 | --title "v${{steps.next_semantic_version.outputs.major}}.${{steps.next_semantic_version.outputs.minor}}-rc MINOR release (auto-updated)" \ 120 | --generate-notes \ 121 | --prerelease \ 122 | --target "${{github.sha}}" 123 | env: 124 | GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" 125 | -------------------------------------------------------------------------------- /.github/workflows/check-build-readme-code-snippet-example.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Tests the example used in README.md, to make sure the example we show is always working. 3 | # 4 | # See https://github.com/actions/checkout https://github.com/actions/checkout/releases/tag/v3 5 | 6 | name: 'GitHub Action code snippet' 7 | on: 8 | push: 9 | 10 | jobs: 11 | # We want to wait for the auto-git-release-x to be done, so that we always test the MAJOR version that was just updated 12 | await-release: 13 | name: Sleep for 45 seconds 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - run: sleep 45s 17 | shell: bash 18 | 19 | # On some job, do some stuff and persist variables meant to be re-used in other jobs 20 | compute-data: 21 | name: Compute data 22 | runs-on: ubuntu-22.04 23 | needs: await-release 24 | steps: 25 | # Do your own internal business logic... 26 | - name: Compute resources 27 | run: | 28 | MAGIC_NUMBER=42 29 | echo "Found universal answer: $MAGIC_NUMBER" 30 | echo "Exporting it as ENV variable..." 31 | echo "MAGIC_NUMBER=$MAGIC_NUMBER" >> $GITHUB_ENV 32 | 33 | # XXX We recommend to export all your variables at once, at the end of your job 34 | - name: Export variable MAGIC_NUMBER for next jobs 35 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 36 | with: 37 | # Persist (store) our MAGIC_NUMBER ENV variable into our store, for the next jobs 38 | variables: | 39 | MAGIC_NUMBER=${{ env.MAGIC_NUMBER }} 40 | 41 | # In another job, read the previously stored variable and use it 42 | retrieve-data: 43 | name: Find & re-use data 44 | runs-on: ubuntu-22.04 45 | needs: compute-data 46 | steps: 47 | - name: Import variable MAGIC_NUMBER 48 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 49 | with: 50 | # List all variables you want to retrieve from the store 51 | # XXX They'll be automatically added to your ENV 52 | variables: | 53 | MAGIC_NUMBER 54 | - name: Debug output 55 | run: echo "We have access to $MAGIC_NUMBER" 56 | 57 | save-many-variables-by-using-custom-delimiter: 58 | name: Save many variables by using a custom delimiter (comma) 59 | runs-on: ubuntu-22.04 60 | needs: await-release 61 | steps: 62 | - name: Export variable for next jobs 63 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 64 | with: 65 | delimiter: ',' 66 | variables: FOO=BAR,STAGE=production 67 | 68 | retrieve-data-saved-with-a-custom-delimiter: 69 | name: Retrieve variables using a custom delimiter 70 | runs-on: ubuntu-22.04 71 | needs: save-many-variables-by-using-custom-delimiter 72 | steps: 73 | - name: Import variable MAGIC_NUMBER 74 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 75 | with: 76 | delimiter: ';' 77 | variables: FOO;STAGE 78 | failIfNotFound: true 79 | - name: Debug output 80 | run: echo "Found FOO=$FOO and STAGE=$STAGE" 81 | -------------------------------------------------------------------------------- /.github/workflows/check-build.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Test if the GitHub Action builds correctly. 3 | # Makes sure the GitHub Action builds when being built by GitHub Actions. 4 | # 5 | # See https://github.com/actions/checkout https://github.com/actions/checkout/releases/tag/v3 6 | 7 | name: 'GitHub Action build test' 8 | on: 9 | pull_request: 10 | push: 11 | 12 | jobs: 13 | run-build-test: 14 | strategy: 15 | matrix: 16 | version: [ 18, 20 ] 17 | runs-on: ubuntu-22.04 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: actions/setup-node@v4 21 | with: 22 | node-version: '20' 23 | - run: | 24 | yarn 25 | yarn build:once 26 | yarn test:once 27 | yarn lint 28 | yarn format:preview 29 | -------------------------------------------------------------------------------- /.github/workflows/run-integration-test.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Test the GitHub Action using an integration test. 3 | # Makes sure the GitHub Action works properly when running on a clean machine, without building anything (integration test). 4 | # 5 | # See https://github.com/actions/checkout https://github.com/actions/checkout/releases/tag/v3 6 | 7 | name: 'GitHub Action integration test' 8 | on: 9 | pull_request: 10 | push: 11 | 12 | jobs: 13 | run-integration-test1: 14 | runs-on: ubuntu-22.04 15 | steps: 16 | - uses: actions/checkout@v3 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version: '20' 20 | - run: yarn # Install all dependencies 21 | - uses: ./ 22 | id: store-variables 23 | with: 24 | variables: | 25 | URL=https://github.com 26 | - run: | 27 | echo "Exported variable URL=$URL" 28 | env: 29 | URL: ${{ env.URL }} 30 | run-integration-test2: 31 | runs-on: ubuntu-22.04 32 | needs: run-integration-test1 33 | steps: 34 | - uses: actions/checkout@v3 35 | - uses: actions/setup-node@v4 36 | with: 37 | node-version: '20' 38 | - run: yarn # Install all dependencies 39 | - uses: ./ 40 | with: 41 | variables: | 42 | URL 43 | SECOND_URL=https://github.com/UnlyEd 44 | - run: | 45 | echo "Found from previous job URL=$URL" 46 | echo "Exported variable SECOND_URL=$SECOND_URL" 47 | env: 48 | URL: ${{ env.URL }} 49 | SECOND_URL: ${{ env.SECOND_URL }} 50 | run-integration-test3: 51 | runs-on: ubuntu-22.04 52 | needs: run-integration-test2 53 | steps: 54 | - uses: actions/checkout@v3 55 | - uses: actions/setup-node@v4 56 | with: 57 | node-version: '20' 58 | - run: yarn # Install all dependencies 59 | - uses: ./ 60 | with: 61 | variables: | 62 | URL 63 | SECOND_URL 64 | - run: | 65 | echo "Found from previous job URL=$URL" 66 | echo "Found from previous job SECOND_URL=$SECOND_URL" 67 | env: 68 | URL: ${{ env.URL }} 69 | SECOND_URL: ${{ env.SECOND_URL }} 70 | 71 | should-not-fail-on-retrieving-UNKNOWN_VAR: 72 | runs-on: ubuntu-22.04 73 | steps: 74 | - uses: actions/checkout@v3 75 | - uses: actions/setup-node@v4 76 | with: 77 | node-version: '20' 78 | - run: yarn # Install all dependencies 79 | - uses: ./ 80 | with: 81 | variables: | 82 | UNKNOWN_VAR 83 | failIfNotFound: false # Default is false 84 | -------------------------------------------------------------------------------- /.github/workflows/update-codeclimate-coverage.yml: -------------------------------------------------------------------------------- 1 | # Summary: 2 | # Run Unit and coverage tests, then upload it to Code Climate dashboard 3 | # 4 | # See https://github.com/actions/checkout https://github.com/actions/checkout/releases/tag/v3 5 | # See https://github.com/paambaati/codeclimate-action https://github.com/paambaati/codeclimate-action/tree/v3.2.0 6 | 7 | name: Update Code Climate test coverage 8 | 9 | on: 10 | push: 11 | branches: 12 | - main # Change this branch name by your CodeClimate "main" branch use 13 | 14 | jobs: 15 | # Configures the deployment environment, install dependencies (like node, npm, etc.) that are requirements for the upcoming jobs 16 | # Ex: Necessary to run `yarn test:coverage` 17 | setup-environment: 18 | name: Setup deployment environment (Ubuntu 22.04 - Node 18.x) 19 | runs-on: ubuntu-22.04 20 | steps: 21 | - name: Installing node.js 22 | uses: actions/setup-node@v3 # Used to install node environment - XXX https://github.com/actions/setup-node 23 | with: 24 | node-version: 18 25 | run-tests-coverage: 26 | name: Run tests coverage and send report to Code Climate 27 | runs-on: ubuntu-22.04 28 | steps: 29 | - uses: actions/checkout@v3 30 | - name: Installing dependencies 31 | run: yarn install 32 | - uses: paambaati/codeclimate-action@v3.2.0 33 | env: 34 | CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} # XXX Define this secret in "Github repo > Settings > Secrets", you can get it from Code Climate in "Repo settings > Test coverage". 35 | with: 36 | coverageCommand: yarn test:coverage 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/webstorm 2 | 3 | ### WebStorm ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 6 | 7 | # User-specific stuff 8 | .idea/**/workspace.xml 9 | .idea/**/tasks.xml 10 | .idea/**/usage.statistics.xml 11 | .idea/**/dictionaries 12 | .idea/**/shelf 13 | 14 | # Sensitive or high-churn files 15 | .idea/**/dataSources/ 16 | .idea/**/dataSources.ids 17 | .idea/**/dataSources.local.xml 18 | .idea/**/sqlDataSources.xml 19 | .idea/**/dynamic.xml 20 | .idea/**/uiDesigner.xml 21 | .idea/**/dbnavigator.xml 22 | 23 | # Gradle 24 | .idea/**/gradle.xml 25 | .idea/**/libraries 26 | 27 | # Gradle and Maven with auto-import 28 | # When using Gradle or Maven with auto-import, you should exclude module files, 29 | # since they will be recreated, and may cause churn. Uncomment if using 30 | # auto-import. 31 | # .idea/modules.xml 32 | # .idea/*.iml 33 | # .idea/modules 34 | 35 | # CMake 36 | cmake-build-*/ 37 | 38 | # Mongo Explorer plugin 39 | .idea/**/mongoSettings.xml 40 | 41 | # File-based project format 42 | *.iws 43 | 44 | # IntelliJ 45 | out/ 46 | 47 | # mpeltonen/sbt-idea plugin 48 | .idea_modules/ 49 | 50 | # JIRA plugin 51 | atlassian-ide-plugin.xml 52 | 53 | # Cursive Clojure plugin 54 | .idea/replstate.xml 55 | 56 | # Crashlytics plugin (for Android Studio and IntelliJ) 57 | com_crashlytics_export_strings.xml 58 | crashlytics.properties 59 | crashlytics-build.properties 60 | fabric.properties 61 | 62 | # Editor-based Rest Client 63 | .idea/httpRequests 64 | 65 | ### WebStorm Patch ### 66 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 67 | 68 | # TODO Comment those if you've cloned the project and are using WebStorm as they should be tracked in your project, but shouldn't be tracked in the boilerplate to avoid conflicts when cloning 69 | *.iml 70 | modules.xml 71 | .idea/misc.xml 72 | .idea/codeStyles 73 | *.ipr 74 | vcs.xml 75 | 76 | # Sonarlint plugin 77 | .idea/sonarlint 78 | 79 | .idea/inspectionProfiles/Project_Default.xml 80 | 81 | 82 | # End of https://www.gitignore.io/api/webstorm 83 | 84 | ######################### CUSTOM/MANUAL ############################# 85 | 86 | # See https://help.github.com/ignore-files/ for more about ignoring files. 87 | 88 | # IDE plugins 89 | .idea/markdown-navigator*/** 90 | 91 | # package directories 92 | #node_modules # XXX Necessary for GitHub Actions 93 | jspm_packages 94 | 95 | # Serverless directories 96 | .serverless 97 | .webpack 98 | .next 99 | dist 100 | 101 | .DS_Store 102 | .sls-simulate-registry 103 | 104 | # Builds 105 | build 106 | .firebase 107 | coverage/ 108 | 109 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 110 | 111 | # dependencies 112 | /.pnp 113 | .pnp.js 114 | 115 | # testing 116 | /coverage 117 | 118 | # Environment variables 119 | .env* 120 | .env*.local 121 | !.env*.example 122 | 123 | # debug 124 | npm-debug.log* 125 | yarn-debug.log* 126 | yarn-error.log* 127 | 128 | # Tmp files (cache, etc.) 129 | *.cache 130 | .vercel 131 | github-action-runtime/stats.json 132 | 133 | # NPM modules 134 | node_modules/ 135 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v20 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | coverage/ 3 | node_modules/ 4 | lib/ 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 160, 3 | trailingComma: 'all', 4 | semi: true, 5 | singleQuote: true, 6 | quoteProps: 'consistent', 7 | }; 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | CHANGELOG 2 | === 3 | 4 | ## Migrating (breaking changes) 5 | 6 | ### v3 7 | No breaking changes. 8 | 9 | - [v3 uses Node16 instead of node12](https://github.com/UnlyEd/github-action-store-variable/releases/tag/v3.0.0). 10 | 11 | ### v2 12 | _I don't remember._ 13 | 14 | --- 15 | 16 | Please visit [our releases page](../../releases) for more details. 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Unly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unly logo 2 | [![Maintainability](https://api.codeclimate.com/v1/badges/9e073b5db2eec4c4e5c8/maintainability)](https://codeclimate.com/github/UnlyEd/github-action-store-variable/maintainability) 3 | [![Test Coverage](https://api.codeclimate.com/v1/badges/9e073b5db2eec4c4e5c8/test_coverage)](https://codeclimate.com/github/UnlyEd/github-action-store-variable/test_coverage) 4 | 5 | ![GitHub Action integration test](https://github.com/UnlyEd/github-action-store-variable/workflows/GitHub%20Action%20integration%20test/badge.svg) 6 | ![GitHub Action build test](https://github.com/UnlyEd/github-action-store-variable/workflows/GitHub%20Action%20build%20test/badge.svg) 7 | ![Update Code Climate test coverage](https://github.com/UnlyEd/github-action-store-variable/workflows/Update%20Code%20Climate%20test%20coverage/badge.svg) 8 | 9 | # GitHub Action - Store variables between your jobs 10 | 11 | ## Overview 12 | 13 | This GitHub Action was originally created **in 2021** to allow you to **store variables** in a global store and then **read them in 14 | later jobs**—something that was not natively possible in GitHub Actions. It automatically adds read variables to 15 | your `${{ env }}` so that they become available for subsequent steps. 16 | 17 | ## But… GitHub Actions native outputs make this library largely unnecessary! 18 | 19 | ### What Are Native Outputs? 20 | 21 | GitHub Actions now provides native support for sharing data between jobs through the use of step outputs and job 22 | outputs. You can: 23 | 24 | - **Set a step output:** Write key/value pairs to `$GITHUB_OUTPUT` in a step. 25 | - **Define job outputs:** Map outputs from a step to a job-level output. 26 | - **Access job outputs:** In downstream jobs, access these outputs using the `needs` context. 27 | 28 | Similarly, the `$GITHUB_ENV` file allows you to persist environment variables across steps in the same job. 29 | 30 | Source: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/passing-information-between-jobs 31 | 32 | ### Why Is This a Game Changer? 33 | 34 | Originally, this library provided a way to emulate global variable sharing: 35 | 36 | - **Before:** GitHub Actions did not support sharing environment variables between jobs. 37 | - **Now:** Native outputs let you write a variable in one job and read it in another without extra actions or artifacts. 38 | 39 | This native support simplifies your workflows, reduces dependencies, and improves reliability. 40 | 41 | --- 42 | 43 | ## Converting a Use Case 44 | 45 | ### Old Approach (Using `UnlyEd/github-action-store-variable`) - ⚠️ DEPRECATED 46 | 47 | Below is an example of how you might have stored and retrieved a variable with the library: 48 | 49 | ```yaml 50 | jobs: 51 | compute-data: 52 | runs-on: ubuntu-22.04 53 | steps: 54 | - name: Compute data 55 | run: | 56 | MY_VAR="Hello, World!" 57 | echo "MY_VAR=$MY_VAR" >> $GITHUB_ENV 58 | 59 | - name: Store variable using the library 60 | uses: UnlyEd/github-action-store-variable@v2.1.0 61 | with: 62 | variables: | 63 | MY_VAR=${{ env.MY_VAR }} 64 | 65 | use-data: 66 | runs-on: ubuntu-22.04 67 | needs: compute-data 68 | steps: 69 | - name: Retrieve variable using the library 70 | uses: UnlyEd/github-action-store-variable@v2.1.0 71 | with: 72 | variables: | 73 | MY_VAR 74 | - name: Use variable 75 | run: echo "MY_VAR is $MY_VAR" 76 | ``` 77 | 78 | ### New Approach (Using Native Outputs) 79 | Here’s how you can achieve the same result without an external action: 80 | 81 | ```yaml 82 | jobs: 83 | compute-data: 84 | runs-on: ubuntu-22.04 85 | outputs: 86 | MY_VAR: ${{ steps.set-output.outputs.MY_VAR }} 87 | steps: 88 | - name: Compute data 89 | run: | 90 | MY_VAR="Hello, World!" 91 | echo "MY_VAR=$MY_VAR" >> $GITHUB_ENV 92 | 93 | - name: Set step output 94 | id: set-output 95 | run: | 96 | # Export MY_VAR as a step output, so it can be mapped to the job output 97 | echo "MY_VAR=${MY_VAR}" >> $GITHUB_OUTPUT 98 | 99 | use-data: 100 | runs-on: ubuntu-22.04 101 | needs: compute-data 102 | steps: 103 | - name: Use variable from job outputs 104 | run: echo "MY_VAR is ${{ needs.compute-data.outputs.MY_VAR }}" 105 | 106 | ``` 107 | 108 | --- 109 | 110 | # Former documentation 111 | 112 | ## Code snippet example (minimal example) 113 | 114 | ```yaml 115 | name: 'GitHub Action code snippet' 116 | on: 117 | push: 118 | 119 | jobs: 120 | # On some job, do some stuff and persist variables meant to be re-used in other jobs 121 | compute-data: 122 | name: Compute data 123 | runs-on: ubuntu-22.04 124 | steps: 125 | # Do your own internal business logic... 126 | - name: Compute resources 127 | run: | 128 | MAGIC_NUMBER=42 129 | echo "Found universal answer: $MAGIC_NUMBER" 130 | echo "Exporting it as ENV variable..." 131 | echo "MAGIC_NUMBER=$MAGIC_NUMBER" >> $GITHUB_ENV 132 | 133 | # XXX We recommend to export all your variables at once, at the end of your job 134 | - name: Export variable MAGIC_NUMBER for next jobs 135 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 136 | with: 137 | # Persist (store) our MAGIC_NUMBER ENV variable into our store, for the next jobs 138 | variables: | 139 | MAGIC_NUMBER=${{ env.MAGIC_NUMBER }} 140 | 141 | # In another job, read the previously stored variable and use it 142 | retrieve-data: 143 | name: Find & re-use data 144 | runs-on: ubuntu-22.04 145 | needs: compute-data 146 | steps: 147 | - name: Import variable MAGIC_NUMBER 148 | uses: UnlyEd/github-action-store-variable@v3 # See https://github.com/UnlyEd/github-action-store-variable 149 | with: 150 | # List all variables you want to retrieve from the store 151 | # XXX They'll be automatically added to your ENV 152 | variables: | 153 | MAGIC_NUMBER 154 | - name: Debug output 155 | run: echo "We have access to $MAGIC_NUMBER" 156 | ``` 157 | 158 | > If you want to see a real output, check out the output of our code snippet example [here](https://github.com/UnlyEd/github-action-store-variable/actions/runs/537556204). 159 | 160 | See the [Examples section](#examples) for more advanced examples. 161 | 162 | ## What does this GitHub Action do? 163 | 164 | You can use this action to **store variables** in a sort of "global store" for your GitHub Actions. 165 | 166 | Then, you can **read the variables** that have been stored previously. 167 | 168 | The variables stored can be read by any job within the same workflow. 169 | 170 | > **N.B**: When you read a variable, **it is automatically added as an ENV variable** and will erase any variable with the same name. 171 | > 172 | > This behavior helps keeping the code cleaner by only manipulating (reading/writing) ENV variables. 173 | > In v1, we had to read the variables from a JSON object, and [it was ugly](https://github.com/UnlyEd/github-action-store-variable/blob/c4143c0d7f/.github/workflows/run-integration-test.yml#L29). 174 | 175 | > N.B: You can both **read and write** in the same action. 176 | 177 | ## Why/when should you use it? 178 | 179 | GitHub Actions doesn't allow to natively re-use variables between jobs. 180 | 181 | If you need to **re-use variables defined in a job in other** (subsequent) jobs, then you can use this action. 182 | 183 | ### Action's API 184 | 185 | #### Inputs 186 | 187 | Name | Required | Default | Description 188 | --- | --- |--- |--- 189 | `variables`|✅| | Write variable: `VAR=VALUE` - Read variable: `VAR` 190 | `delimiter`|✖️|`\r?\n`| Regex delimiter between each variable, defaults to normal line break 191 | `failIfNotFound`|✖️|`false`| If true, will throw an error (and crash CI) when attempting to read a variable that doesn't exist in the store 192 | 193 | #### Outputs 194 | 195 | There are no outputs for this action, reading variables **automatically** adds these variables in `${{ env }}`. 196 | 197 | For example, if you read a variable named `VAR`, you can then access it by using `${{ env.VAR }}`. 198 | 199 | ## Examples 200 | 201 | ### 1. Save one variable 202 | 203 | ```yaml 204 | - name: Export one variable 205 | uses: UnlyEd/github-action-store-variable@v2.1.0 206 | with: 207 | variables: FOO=BAR 208 | ``` 209 | 210 | ### 2. Save many variables 211 | 212 | ```yaml 213 | - name: Export many variables 214 | uses: UnlyEd/github-action-store-variable@v2.1.0 215 | with: 216 | variables: | 217 | FOO=BAR 218 | STAGE=production 219 | ``` 220 | 221 | > Pro-tip: We recommend always using the `variables: |` syntax (multi lines), because it's just simpler to add more variables later on. 222 | 223 | ### 3. Save one variable and read another 224 | 225 | ```yaml 226 | - name: Export one variable 227 | uses: UnlyEd/github-action-store-variable@v2.1.0 228 | with: 229 | # Writes "FOO" and reads "STAGE" 230 | variables: | 231 | FOO=BAR 232 | STAGE 233 | ``` 234 | 235 | ### 4. Save many variables using a custom delimiter 236 | 237 | ```yaml 238 | - name: Export many variables 239 | uses: UnlyEd/github-action-store-variable@v2.1.0 240 | with: 241 | delimiter: ':' 242 | variables: FOO=BAR:STAGE=production 243 | ``` 244 | 245 | ### 5. Retrieve one variable 246 | 247 | ```yaml 248 | - name: Import variable MAGIC_NUMBER 249 | uses: UnlyEd/github-action-store-variable@v2.1.0 250 | with: 251 | variables: FOO 252 | ``` 253 | 254 | ### 6. Retrieve many variables 255 | 256 | ```yaml 257 | - name: Import variable MAGIC_NUMBER 258 | uses: UnlyEd/github-action-store-variable@v2.1.0 259 | with: 260 | variables: | 261 | FOO 262 | STAGE 263 | ``` 264 | 265 | ### 7. Retrieve many variables using a custom delimiter 266 | 267 | ```yaml 268 | - name: Import variable MAGIC_NUMBER 269 | uses: UnlyEd/github-action-store-variable@v2.1.0 270 | with: 271 | delimiter: ';' 272 | variables: FOO;STAGE 273 | ``` 274 | 275 | ### 8. Crash CI if variable doesn't exist 276 | 277 | ```yaml 278 | - name: Import variable MAGIC_NUMBER 279 | uses: UnlyEd/github-action-store-variable@v2.1.0 280 | with: 281 | failIfNotFound: true 282 | variables: WRONG_VARIABLE 283 | ``` 284 | 285 | > N.B: If you want to crash only for some variables, then you can call 2 times the `UnlyEd/github-action-store-variable` and have `failIfNotFound: true` in one of them. 286 | 287 | ## :hugs: Community examples :heart: 288 | 289 | Here are a few community-powered examples, those are usually advanced use-cases! 290 | 291 | - [Next Right Now](https://github.com/UnlyEd/next-right-now/blob/60455642a5c5248c3e0e9604de080e24ef9eed0a/.github/workflows/deploy-vercel-staging.yml#L250-L260) _(Disclosure: We're the author!)_ 292 | 293 | --- 294 | 295 | # Advanced debugging 296 | 297 | > Learn how to enable logging, from within the `github-action-store-variable` action. 298 | 299 | ## How to enable debug logs 300 | 301 | Our GitHub Action is written using the GitHub Actions 302 | native [`core.debug` API](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#step-debug-logs). 303 | 304 | Therefore, it allows you to enable logging whenever you need to debug **what's happening within our action**. 305 | 306 | **To enable debug mode**, you have to set a [**GitHub Secret**](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets#creating-encrypted-secrets), such as: 307 | 308 | - `ACTIONS_STEP_DEBUG` of value `true` 309 | 310 | Please see [the official documentation](https://github.com/actions/toolkit/blob/main/docs/action-debugging.md#how-to-access-step-debug-logs) for more information. 311 | 312 | > Enabling debugging using `ACTIONS_STEP_DEBUG` will also enable debugging for all other GitHub Actions you use that are using the `core.debug` API. 313 | 314 | --- 315 | 316 | # Contributing 317 | 318 | We gladly accept PRs, but please open an issue first, so we can discuss it beforehand. 319 | 320 | --- 321 | 322 | # Changelog 323 | 324 | [Changelog](./CHANGELOG.md) 325 | 326 | --- 327 | 328 | # Releases versioning 329 | 330 | We follow Semantic Versioning. (`major.minor.patch`) 331 | 332 | Our versioning process is completely automated, any changes landing on the `main` branch will trigger a new [release](../../releases). 333 | 334 | - `(MAJOR)`: Behavioral change of the existing API that would result in a breaking change. 335 | - E.g: Removing an input, or changing the output would result in a breaking change and thus would be released as a new MAJOR version. 336 | - `(MINOR)`: Behavioral change of the existing API that would **not** result in a breaking change. 337 | - E.g: Adding an optional input would result in a non-breaking change and thus would be released as a new MINOR version. 338 | - `Patch`: Any other change. 339 | - E.g: Documentation, tests, refactoring, bug fix, etc. 340 | 341 | ## Releases versions: 342 | 343 | The examples above use an auto-updated major version tag (`@v1`). 344 | It is also possible to use the `@latest` tag. (RC stands for "Release candidate", which is similar to a Beta version) 345 | 346 | While those options can be useful, we intend to give some "production-grade" best practices. 347 | 348 | - **Do NOT use `@latest` for production**, ever. While only "supposed-to-be-stable" versions will be tagged 349 | as `@latest`, it could harbor bugs nonetheless. 350 | - You can use auto-upgrading major version, such as `@v1` or `@v1.2`, but this is not always the best practice, see our explanations below. 351 | 352 | ### Special tags and best practices for production-grade apps 353 | 354 | Here are a few useful options you can use to pin a more-or-less specific version of our GitHub Action, alongside some " 355 | production-grade" best practices. 356 | 357 | - `@{COMMIT-SHA}`, e.g: `@1271dc3fc4c4c8bc62ba5a4e248dac95cb82d0e3`, recommended for all production-grade apps, it's the 358 | only truly safe way to pinpoint a version that cannot change against your will (**SAFEST**) 359 | - `@{MAJOR}-{MINOR}-{PATCH}`, e.g: `@v1.2.31`, while not as safe as the `COMMIT-SHA` way, it's what most people use ( 360 | SAFER) 361 | - `@{MAJOR}`, e.g: `@v1`, can be used on production, but we do not advise to do so (SAFE-ISH) 362 | - `@{MAJOR}-rc`, e.g: `@v1-rc`, **reserved for development mode**, useful when debugging on a specific prerelease 363 | version (UNSAFE) 364 | - `@{MAJOR}.{MINOR}`, e.g: `@v1.2`, can be used on production, but we do not advise to do so (SAFE-ISH) 365 | - `@{MAJOR}.{MINOR}-rc`, e.g: `@v1.2-rc`, **reserved for development mode**, useful when debugging on a specific prerelease 366 | version (UNSAFE) 367 | - `@latest`, **reserved for development mode**, useful when debugging (UNSAFE) 368 | 369 | **"But, what is the issue with the `@{MAJOR}-{MINOR}-{PATCH}` way to pin a specific version"?** 370 | 371 | > Well, if this repository gets hacked by a 3rd party, **they can easily change all Git tags to a different commit**, 372 | which could contain malicious code. 373 | 374 | That's why **pinning a specific commit SHA is the only truly safe option**. This way, the code you're using **cannot be 375 | changed against your will**. 376 | 377 | Most people won't care about this and will use a MAJOR version tag instead anyway, such as `@v1`. It's common, but not 378 | often the best practice. 379 | 380 | It all comes down to the risks you're ready to take, and it's up to you to decide what's best in your situation. 381 | 382 | --- 383 | 384 | # License 385 | 386 | [MIT](./LICENSE) 387 | 388 | --- 389 | 390 | # Vulnerability disclosure 391 | 392 | [See our policy](https://github.com/UnlyEd/Unly). 393 | 394 | --- 395 | 396 | # Contributors and maintainers 397 | 398 | This project is being authored by: 399 | 400 | - [Unly] Ambroise Dhenain ([Vadorequest](https://github.com/vadorequest)) **(active)** 401 | - Hugo Martin ([Demmonius](https://github.com/demmonius)) **(active)** 402 | 403 | --- 404 | 405 | # **[ABOUT UNLY]** Unly logo 406 | 407 | > [Unly](https://unly.org) is a socially responsible company, fighting inequality and facilitating access to higher education. 408 | > Unly is committed to making education more inclusive, through responsible funding for students. 409 | 410 | We provide technological solutions to help students find the necessary funding for their studies. 411 | 412 | We proudly participate in many TechForGood initiatives. To support and learn more about our actions to make education accessible, visit : 413 | 414 | - https://twitter.com/UnlyEd 415 | - https://www.facebook.com/UnlyEd/ 416 | - https://www.linkedin.com/company/unly 417 | - [Interested to work with us?](https://jobs.zenploy.io/unly/about) 418 | 419 | Tech tips and tricks from our CTO on our [Medium page](https://medium.com/unly-org/tech/home)! 420 | 421 | # TECHFORGOOD #EDUCATIONFORALL 422 | -------------------------------------------------------------------------------- /__tests__/main.test.ts: -------------------------------------------------------------------------------- 1 | import * as cp from 'child_process'; 2 | import * as path from 'path'; 3 | import * as process from 'process'; 4 | import { BUILD_DIR, BUILD_MAIN_FILENAME } from '../src/config'; 5 | 6 | /** 7 | * Enhance the Node.js environment "global" variable to add our own types 8 | * 9 | * @see https://stackoverflow.com/a/42304473/2391795 10 | */ 11 | declare global { 12 | let muteConsole: () => any; 13 | let muteConsoleButLog: () => any; 14 | let unmuteConsole: () => any; 15 | } 16 | 17 | /** 18 | * Executes the compiled version of the Action's main file. (.js) 19 | * 20 | * The goal is to test the file that is actually executed by GitHub Action. 21 | * Additionally, we could also test the TS files, but we didn't do it to avoid over-complicating things (didn't seem necessary). 22 | * 23 | * @param options 24 | */ 25 | function exec_lib(options: cp.ExecFileSyncOptions): string { 26 | /** 27 | * Path of the node.js binary being used. 28 | * 29 | * @example/usr/local/Cellar/node/14.3.0/bin/node 30 | */ 31 | const nodeBinaryPath = process.execPath; 32 | 33 | /** 34 | * Path of the compiled version of the Action file entrypoint. 35 | * 36 | * @example .../github-action-store-variable/lib/main.js 37 | */ 38 | const mainFilePath = path.join(__dirname, '..', BUILD_DIR, BUILD_MAIN_FILENAME); 39 | 40 | try { 41 | // console.debug(`Running command "${nodeBinaryPath} ${mainFilePath}"`); 42 | return cp.execFileSync(nodeBinaryPath, [mainFilePath], options).toString(); 43 | } catch (e) { 44 | console.error(e?.output?.toString()); 45 | console.error(e); 46 | throw e; 47 | } 48 | } 49 | 50 | describe('Functional test', () => { 51 | describe('should pass when', () => { 52 | beforeEach(() => { 53 | // @ts-ignore 54 | global.console = global.unmuteConsole(); 55 | }); 56 | 57 | describe('when storing variables using a special delimiter', () => { 58 | const options: cp.ExecFileSyncOptions = { 59 | env: { 60 | INPUT_VARIABLES: 'VAR=TEST,OTHER_VAR=OTHER_TEST,UNKNOWN_VAR', 61 | INPUT_DELIMITER: ',', 62 | }, 63 | }; 64 | const output = exec_lib(options); 65 | console.log('output:\n', output); 66 | 67 | test('output should display all received variables', () => { 68 | expect(output.includes('::debug::Received variables: VAR=TEST,OTHER_VAR=OTHER_TEST,UNKNOWN_VAR')).toBe(true); 69 | }); 70 | 71 | test('output should display used delimiter', () => { 72 | expect(output.includes('::debug::Using delimiter: ","')).toBe(true); 73 | }); 74 | 75 | test('output should display warning about UNKNOWN_VAR not being found', () => { 76 | expect(output.includes('::warning::Cannot retrieve variable UNKNOWN_VAR')).toBe(true); 77 | }); 78 | }); 79 | 80 | describe('when storing variables', () => { 81 | const options: cp.ExecFileSyncOptions = { 82 | env: { 83 | INPUT_VARIABLES: 'VAR1=1,VAR2=SOME_STRING', 84 | INPUT_DELIMITER: ',', 85 | }, 86 | }; 87 | const output = exec_lib(options); 88 | console.log('output:\n', output); 89 | 90 | test('output should display all received variables', () => { 91 | expect(output.includes('::debug::Received variables: VAR1=1,VAR2=SOME_STRING')).toBe(true); 92 | }); 93 | 94 | test('output should display used delimiter', () => { 95 | expect(output.includes('::debug::Using delimiter: ","')).toBe(true); 96 | }); 97 | 98 | test('output should NOT display warning about UNKNOWN_VAR not being found (because we did not try to read it)', () => { 99 | expect(output.includes('::warning::Cannot retrieve variable UNKNOWN_VAR')).toBe(false); 100 | }); 101 | }); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Store variables' 2 | description: 'Easily persist and read variables to reuse them between GitHub Action jobs' 3 | branding: 4 | icon: bookmark 5 | color: red 6 | inputs: 7 | variables: 8 | description: 'Write variable: `VAR=VALUE` | Read variable: `VAR`' 9 | required: true 10 | delimiter: 11 | description: 'Regex delimiter between each variable' 12 | required: false 13 | default: "\\r?\\n" # Regex splitting line with a '\n' or '\r'. They also need to be escaped, as they are special chars. 14 | failIfNotFound: 15 | description: "If true, will throw an error (and crash CI) when attempting to read a variable that doesn't exist in the store" 16 | required: false 17 | default: 'false' 18 | runs: 19 | using: 'node20' 20 | main: 'github-action-runtime/index.js' 21 | -------------------------------------------------------------------------------- /github-action-runtime/LICENSE: -------------------------------------------------------------------------------- 1 | @actions/artifact 2 | MIT 3 | The MIT License (MIT) 4 | 5 | Copyright 2019 GitHub 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 12 | 13 | @actions/core 14 | MIT 15 | The MIT License (MIT) 16 | 17 | Copyright 2019 GitHub 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | @actions/http-client 26 | MIT 27 | Actions Http Client for Node.js 28 | 29 | Copyright (c) GitHub, Inc. 30 | 31 | All rights reserved. 32 | 33 | MIT License 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 36 | associated documentation files (the "Software"), to deal in the Software without restriction, 37 | including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 38 | and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 39 | subject to the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 44 | LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 45 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 46 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 47 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | 49 | 50 | @actions/io 51 | MIT 52 | 53 | balanced-match 54 | MIT 55 | (MIT) 56 | 57 | Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> 58 | 59 | Permission is hereby granted, free of charge, to any person obtaining a copy of 60 | this software and associated documentation files (the "Software"), to deal in 61 | the Software without restriction, including without limitation the rights to 62 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 63 | of the Software, and to permit persons to whom the Software is furnished to do 64 | so, subject to the following conditions: 65 | 66 | The above copyright notice and this permission notice shall be included in all 67 | copies or substantial portions of the Software. 68 | 69 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 70 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 71 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 72 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 73 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 74 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 75 | SOFTWARE. 76 | 77 | 78 | brace-expansion 79 | MIT 80 | MIT License 81 | 82 | Copyright (c) 2013 Julian Gruber 83 | 84 | Permission is hereby granted, free of charge, to any person obtaining a copy 85 | of this software and associated documentation files (the "Software"), to deal 86 | in the Software without restriction, including without limitation the rights 87 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 88 | copies of the Software, and to permit persons to whom the Software is 89 | furnished to do so, subject to the following conditions: 90 | 91 | The above copyright notice and this permission notice shall be included in all 92 | copies or substantial portions of the Software. 93 | 94 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 95 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 96 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 97 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 98 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 99 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 100 | SOFTWARE. 101 | 102 | 103 | concat-map 104 | MIT 105 | This software is released under the MIT license: 106 | 107 | Permission is hereby granted, free of charge, to any person obtaining a copy of 108 | this software and associated documentation files (the "Software"), to deal in 109 | the Software without restriction, including without limitation the rights to 110 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 111 | the Software, and to permit persons to whom the Software is furnished to do so, 112 | subject to the following conditions: 113 | 114 | The above copyright notice and this permission notice shall be included in all 115 | copies or substantial portions of the Software. 116 | 117 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 118 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 119 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 120 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 121 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 122 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 123 | 124 | 125 | fs.realpath 126 | ISC 127 | The ISC License 128 | 129 | Copyright (c) Isaac Z. Schlueter and Contributors 130 | 131 | Permission to use, copy, modify, and/or distribute this software for any 132 | purpose with or without fee is hereby granted, provided that the above 133 | copyright notice and this permission notice appear in all copies. 134 | 135 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 136 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 137 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 138 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 139 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 140 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 141 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 142 | 143 | ---- 144 | 145 | This library bundles a version of the `fs.realpath` and `fs.realpathSync` 146 | methods from Node.js v0.10 under the terms of the Node.js MIT license. 147 | 148 | Node's license follows, also included at the header of `old.js` which contains 149 | the licensed code: 150 | 151 | Copyright Joyent, Inc. and other Node contributors. 152 | 153 | Permission is hereby granted, free of charge, to any person obtaining a 154 | copy of this software and associated documentation files (the "Software"), 155 | to deal in the Software without restriction, including without limitation 156 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 157 | and/or sell copies of the Software, and to permit persons to whom the 158 | Software is furnished to do so, subject to the following conditions: 159 | 160 | The above copyright notice and this permission notice shall be included in 161 | all copies or substantial portions of the Software. 162 | 163 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 164 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 165 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 166 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 167 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 168 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 169 | DEALINGS IN THE SOFTWARE. 170 | 171 | 172 | glob 173 | ISC 174 | The ISC License 175 | 176 | Copyright (c) Isaac Z. Schlueter and Contributors 177 | 178 | Permission to use, copy, modify, and/or distribute this software for any 179 | purpose with or without fee is hereby granted, provided that the above 180 | copyright notice and this permission notice appear in all copies. 181 | 182 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 183 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 184 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 185 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 186 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 187 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 188 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 189 | 190 | ## Glob Logo 191 | 192 | Glob's logo created by Tanya Brassie , licensed 193 | under a Creative Commons Attribution-ShareAlike 4.0 International License 194 | https://creativecommons.org/licenses/by-sa/4.0/ 195 | 196 | 197 | inflight 198 | ISC 199 | The ISC License 200 | 201 | Copyright (c) Isaac Z. Schlueter 202 | 203 | Permission to use, copy, modify, and/or distribute this software for any 204 | purpose with or without fee is hereby granted, provided that the above 205 | copyright notice and this permission notice appear in all copies. 206 | 207 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 208 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 209 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 210 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 211 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 212 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 213 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 214 | 215 | 216 | inherits 217 | ISC 218 | The ISC License 219 | 220 | Copyright (c) Isaac Z. Schlueter 221 | 222 | Permission to use, copy, modify, and/or distribute this software for any 223 | purpose with or without fee is hereby granted, provided that the above 224 | copyright notice and this permission notice appear in all copies. 225 | 226 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 227 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 228 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 229 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 230 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 231 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 232 | PERFORMANCE OF THIS SOFTWARE. 233 | 234 | 235 | 236 | minimatch 237 | ISC 238 | The ISC License 239 | 240 | Copyright (c) Isaac Z. Schlueter and Contributors 241 | 242 | Permission to use, copy, modify, and/or distribute this software for any 243 | purpose with or without fee is hereby granted, provided that the above 244 | copyright notice and this permission notice appear in all copies. 245 | 246 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 247 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 248 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 249 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 250 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 251 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 252 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 253 | 254 | 255 | once 256 | ISC 257 | The ISC License 258 | 259 | Copyright (c) Isaac Z. Schlueter and Contributors 260 | 261 | Permission to use, copy, modify, and/or distribute this software for any 262 | purpose with or without fee is hereby granted, provided that the above 263 | copyright notice and this permission notice appear in all copies. 264 | 265 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 266 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 267 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 268 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 269 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 270 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 271 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 272 | 273 | 274 | path-is-absolute 275 | MIT 276 | The MIT License (MIT) 277 | 278 | Copyright (c) Sindre Sorhus (sindresorhus.com) 279 | 280 | Permission is hereby granted, free of charge, to any person obtaining a copy 281 | of this software and associated documentation files (the "Software"), to deal 282 | in the Software without restriction, including without limitation the rights 283 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 284 | copies of the Software, and to permit persons to whom the Software is 285 | furnished to do so, subject to the following conditions: 286 | 287 | The above copyright notice and this permission notice shall be included in 288 | all copies or substantial portions of the Software. 289 | 290 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 291 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 292 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 293 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 294 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 295 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 296 | THE SOFTWARE. 297 | 298 | 299 | rimraf 300 | ISC 301 | The ISC License 302 | 303 | Copyright (c) Isaac Z. Schlueter and Contributors 304 | 305 | Permission to use, copy, modify, and/or distribute this software for any 306 | purpose with or without fee is hereby granted, provided that the above 307 | copyright notice and this permission notice appear in all copies. 308 | 309 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 310 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 311 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 312 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 313 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 314 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 315 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 316 | 317 | 318 | tmp 319 | MIT 320 | The MIT License (MIT) 321 | 322 | Copyright (c) 2014 KARASZI István 323 | 324 | Permission is hereby granted, free of charge, to any person obtaining a copy 325 | of this software and associated documentation files (the "Software"), to deal 326 | in the Software without restriction, including without limitation the rights 327 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 328 | copies of the Software, and to permit persons to whom the Software is 329 | furnished to do so, subject to the following conditions: 330 | 331 | The above copyright notice and this permission notice shall be included in all 332 | copies or substantial portions of the Software. 333 | 334 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 335 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 336 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 337 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 338 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 339 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 340 | SOFTWARE. 341 | 342 | 343 | tmp-promise 344 | MIT 345 | 346 | tunnel 347 | MIT 348 | The MIT License (MIT) 349 | 350 | Copyright (c) 2012 Koichi Kobayashi 351 | 352 | Permission is hereby granted, free of charge, to any person obtaining a copy 353 | of this software and associated documentation files (the "Software"), to deal 354 | in the Software without restriction, including without limitation the rights 355 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 356 | copies of the Software, and to permit persons to whom the Software is 357 | furnished to do so, subject to the following conditions: 358 | 359 | The above copyright notice and this permission notice shall be included in 360 | all copies or substantial portions of the Software. 361 | 362 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 363 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 364 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 365 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 366 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 367 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 368 | THE SOFTWARE. 369 | 370 | 371 | uuid 372 | MIT 373 | The MIT License (MIT) 374 | 375 | Copyright (c) 2010-2020 Robert Kieffer and other contributors 376 | 377 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 378 | 379 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 380 | 381 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 382 | 383 | 384 | wrappy 385 | ISC 386 | The ISC License 387 | 388 | Copyright (c) Isaac Z. Schlueter and Contributors 389 | 390 | Permission to use, copy, modify, and/or distribute this software for any 391 | purpose with or without fee is hereby granted, provided that the above 392 | copyright notice and this permission notice appear in all copies. 393 | 394 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 395 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 396 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 397 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 398 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 399 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR 400 | IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 401 | -------------------------------------------------------------------------------- /github-action-runtime/sourcemap-register.js: -------------------------------------------------------------------------------- 1 | (()=>{var e={650:e=>{var r=Object.prototype.toString;var n=typeof Buffer.alloc==="function"&&typeof Buffer.allocUnsafe==="function"&&typeof Buffer.from==="function";function isArrayBuffer(e){return r.call(e).slice(8,-1)==="ArrayBuffer"}function fromArrayBuffer(e,r,t){r>>>=0;var o=e.byteLength-r;if(o<0){throw new RangeError("'offset' is out of bounds")}if(t===undefined){t=o}else{t>>>=0;if(t>o){throw new RangeError("'length' is out of bounds")}}return n?Buffer.from(e.slice(r,r+t)):new Buffer(new Uint8Array(e.slice(r,r+t)))}function fromString(e,r){if(typeof r!=="string"||r===""){r="utf8"}if(!Buffer.isEncoding(r)){throw new TypeError('"encoding" must be a valid string encoding')}return n?Buffer.from(e,r):new Buffer(e,r)}function bufferFrom(e,r,t){if(typeof e==="number"){throw new TypeError('"value" argument must not be a number')}if(isArrayBuffer(e)){return fromArrayBuffer(e,r,t)}if(typeof e==="string"){return fromString(e,r)}return n?Buffer.from(e):new Buffer(e)}e.exports=bufferFrom},274:(e,r,n)=>{var t=n(339);var o=Object.prototype.hasOwnProperty;var i=typeof Map!=="undefined";function ArraySet(){this._array=[];this._set=i?new Map:Object.create(null)}ArraySet.fromArray=function ArraySet_fromArray(e,r){var n=new ArraySet;for(var t=0,o=e.length;t=0){return r}}else{var n=t.toSetString(e);if(o.call(this._set,n)){return this._set[n]}}throw new Error('"'+e+'" is not in the set.')};ArraySet.prototype.at=function ArraySet_at(e){if(e>=0&&e{var t=n(190);var o=5;var i=1<>1;return r?-n:n}r.encode=function base64VLQ_encode(e){var r="";var n;var i=toVLQSigned(e);do{n=i&a;i>>>=o;if(i>0){n|=u}r+=t.encode(n)}while(i>0);return r};r.decode=function base64VLQ_decode(e,r,n){var i=e.length;var s=0;var l=0;var c,p;do{if(r>=i){throw new Error("Expected more digits in base 64 VLQ value.")}p=t.decode(e.charCodeAt(r++));if(p===-1){throw new Error("Invalid base64 digit: "+e.charAt(r-1))}c=!!(p&u);p&=a;s=s+(p<{var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");r.encode=function(e){if(0<=e&&e{r.GREATEST_LOWER_BOUND=1;r.LEAST_UPPER_BOUND=2;function recursiveSearch(e,n,t,o,i,a){var u=Math.floor((n-e)/2)+e;var s=i(t,o[u],true);if(s===0){return u}else if(s>0){if(n-u>1){return recursiveSearch(u,n,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return n1){return recursiveSearch(e,u,t,o,i,a)}if(a==r.LEAST_UPPER_BOUND){return u}else{return e<0?-1:e}}}r.search=function search(e,n,t,o){if(n.length===0){return-1}var i=recursiveSearch(-1,n.length,e,n,t,o||r.GREATEST_LOWER_BOUND);if(i<0){return-1}while(i-1>=0){if(t(n[i],n[i-1],true)!==0){break}--i}return i}},680:(e,r,n)=>{var t=n(339);function generatedPositionAfter(e,r){var n=e.generatedLine;var o=r.generatedLine;var i=e.generatedColumn;var a=r.generatedColumn;return o>n||o==n&&a>=i||t.compareByGeneratedPositionsInflated(e,r)<=0}function MappingList(){this._array=[];this._sorted=true;this._last={generatedLine:-1,generatedColumn:0}}MappingList.prototype.unsortedForEach=function MappingList_forEach(e,r){this._array.forEach(e,r)};MappingList.prototype.add=function MappingList_add(e){if(generatedPositionAfter(this._last,e)){this._last=e;this._array.push(e)}else{this._sorted=false;this._array.push(e)}};MappingList.prototype.toArray=function MappingList_toArray(){if(!this._sorted){this._array.sort(t.compareByGeneratedPositionsInflated);this._sorted=true}return this._array};r.H=MappingList},758:(e,r)=>{function swap(e,r,n){var t=e[r];e[r]=e[n];e[n]=t}function randomIntInRange(e,r){return Math.round(e+Math.random()*(r-e))}function doQuickSort(e,r,n,t){if(n{var t;var o=n(339);var i=n(345);var a=n(274).I;var u=n(449);var s=n(758).U;function SourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}return n.sections!=null?new IndexedSourceMapConsumer(n,r):new BasicSourceMapConsumer(n,r)}SourceMapConsumer.fromSourceMap=function(e,r){return BasicSourceMapConsumer.fromSourceMap(e,r)};SourceMapConsumer.prototype._version=3;SourceMapConsumer.prototype.__generatedMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_generatedMappings",{configurable:true,enumerable:true,get:function(){if(!this.__generatedMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__generatedMappings}});SourceMapConsumer.prototype.__originalMappings=null;Object.defineProperty(SourceMapConsumer.prototype,"_originalMappings",{configurable:true,enumerable:true,get:function(){if(!this.__originalMappings){this._parseMappings(this._mappings,this.sourceRoot)}return this.__originalMappings}});SourceMapConsumer.prototype._charIsMappingSeparator=function SourceMapConsumer_charIsMappingSeparator(e,r){var n=e.charAt(r);return n===";"||n===","};SourceMapConsumer.prototype._parseMappings=function SourceMapConsumer_parseMappings(e,r){throw new Error("Subclasses must implement _parseMappings")};SourceMapConsumer.GENERATED_ORDER=1;SourceMapConsumer.ORIGINAL_ORDER=2;SourceMapConsumer.GREATEST_LOWER_BOUND=1;SourceMapConsumer.LEAST_UPPER_BOUND=2;SourceMapConsumer.prototype.eachMapping=function SourceMapConsumer_eachMapping(e,r,n){var t=r||null;var i=n||SourceMapConsumer.GENERATED_ORDER;var a;switch(i){case SourceMapConsumer.GENERATED_ORDER:a=this._generatedMappings;break;case SourceMapConsumer.ORIGINAL_ORDER:a=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var u=this.sourceRoot;a.map((function(e){var r=e.source===null?null:this._sources.at(e.source);r=o.computeSourceURL(u,r,this._sourceMapURL);return{source:r,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name===null?null:this._names.at(e.name)}}),this).forEach(e,t)};SourceMapConsumer.prototype.allGeneratedPositionsFor=function SourceMapConsumer_allGeneratedPositionsFor(e){var r=o.getArg(e,"line");var n={source:o.getArg(e,"source"),originalLine:r,originalColumn:o.getArg(e,"column",0)};n.source=this._findSourceIndex(n.source);if(n.source<0){return[]}var t=[];var a=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,i.LEAST_UPPER_BOUND);if(a>=0){var u=this._originalMappings[a];if(e.column===undefined){var s=u.originalLine;while(u&&u.originalLine===s){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}else{var l=u.originalColumn;while(u&&u.originalLine===r&&u.originalColumn==l){t.push({line:o.getArg(u,"generatedLine",null),column:o.getArg(u,"generatedColumn",null),lastColumn:o.getArg(u,"lastGeneratedColumn",null)});u=this._originalMappings[++a]}}}return t};r.SourceMapConsumer=SourceMapConsumer;function BasicSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sources");var u=o.getArg(n,"names",[]);var s=o.getArg(n,"sourceRoot",null);var l=o.getArg(n,"sourcesContent",null);var c=o.getArg(n,"mappings");var p=o.getArg(n,"file",null);if(t!=this._version){throw new Error("Unsupported version: "+t)}if(s){s=o.normalize(s)}i=i.map(String).map(o.normalize).map((function(e){return s&&o.isAbsolute(s)&&o.isAbsolute(e)?o.relative(s,e):e}));this._names=a.fromArray(u.map(String),true);this._sources=a.fromArray(i,true);this._absoluteSources=this._sources.toArray().map((function(e){return o.computeSourceURL(s,e,r)}));this.sourceRoot=s;this.sourcesContent=l;this._mappings=c;this._sourceMapURL=r;this.file=p}BasicSourceMapConsumer.prototype=Object.create(SourceMapConsumer.prototype);BasicSourceMapConsumer.prototype.consumer=SourceMapConsumer;BasicSourceMapConsumer.prototype._findSourceIndex=function(e){var r=e;if(this.sourceRoot!=null){r=o.relative(this.sourceRoot,r)}if(this._sources.has(r)){return this._sources.indexOf(r)}var n;for(n=0;n1){v.source=l+_[1];l+=_[1];v.originalLine=i+_[2];i=v.originalLine;v.originalLine+=1;v.originalColumn=a+_[3];a=v.originalColumn;if(_.length>4){v.name=c+_[4];c+=_[4]}}m.push(v);if(typeof v.originalLine==="number"){d.push(v)}}}s(m,o.compareByGeneratedPositionsDeflated);this.__generatedMappings=m;s(d,o.compareByOriginalPositions);this.__originalMappings=d};BasicSourceMapConsumer.prototype._findMapping=function SourceMapConsumer_findMapping(e,r,n,t,o,a){if(e[n]<=0){throw new TypeError("Line must be greater than or equal to 1, got "+e[n])}if(e[t]<0){throw new TypeError("Column must be greater than or equal to 0, got "+e[t])}return i.search(e,r,o,a)};BasicSourceMapConsumer.prototype.computeColumnSpans=function SourceMapConsumer_computeColumnSpans(){for(var e=0;e=0){var t=this._generatedMappings[n];if(t.generatedLine===r.generatedLine){var i=o.getArg(t,"source",null);if(i!==null){i=this._sources.at(i);i=o.computeSourceURL(this.sourceRoot,i,this._sourceMapURL)}var a=o.getArg(t,"name",null);if(a!==null){a=this._names.at(a)}return{source:i,line:o.getArg(t,"originalLine",null),column:o.getArg(t,"originalColumn",null),name:a}}}return{source:null,line:null,column:null,name:null}};BasicSourceMapConsumer.prototype.hasContentsOfAllSources=function BasicSourceMapConsumer_hasContentsOfAllSources(){if(!this.sourcesContent){return false}return this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(e){return e==null}))};BasicSourceMapConsumer.prototype.sourceContentFor=function SourceMapConsumer_sourceContentFor(e,r){if(!this.sourcesContent){return null}var n=this._findSourceIndex(e);if(n>=0){return this.sourcesContent[n]}var t=e;if(this.sourceRoot!=null){t=o.relative(this.sourceRoot,t)}var i;if(this.sourceRoot!=null&&(i=o.urlParse(this.sourceRoot))){var a=t.replace(/^file:\/\//,"");if(i.scheme=="file"&&this._sources.has(a)){return this.sourcesContent[this._sources.indexOf(a)]}if((!i.path||i.path=="/")&&this._sources.has("/"+t)){return this.sourcesContent[this._sources.indexOf("/"+t)]}}if(r){return null}else{throw new Error('"'+t+'" is not in the SourceMap.')}};BasicSourceMapConsumer.prototype.generatedPositionFor=function SourceMapConsumer_generatedPositionFor(e){var r=o.getArg(e,"source");r=this._findSourceIndex(r);if(r<0){return{line:null,column:null,lastColumn:null}}var n={source:r,originalLine:o.getArg(e,"line"),originalColumn:o.getArg(e,"column")};var t=this._findMapping(n,this._originalMappings,"originalLine","originalColumn",o.compareByOriginalPositions,o.getArg(e,"bias",SourceMapConsumer.GREATEST_LOWER_BOUND));if(t>=0){var i=this._originalMappings[t];if(i.source===n.source){return{line:o.getArg(i,"generatedLine",null),column:o.getArg(i,"generatedColumn",null),lastColumn:o.getArg(i,"lastGeneratedColumn",null)}}}return{line:null,column:null,lastColumn:null}};t=BasicSourceMapConsumer;function IndexedSourceMapConsumer(e,r){var n=e;if(typeof e==="string"){n=o.parseSourceMapInput(e)}var t=o.getArg(n,"version");var i=o.getArg(n,"sections");if(t!=this._version){throw new Error("Unsupported version: "+t)}this._sources=new a;this._names=new a;var u={line:-1,column:0};this._sections=i.map((function(e){if(e.url){throw new Error("Support for url field in sections not implemented.")}var n=o.getArg(e,"offset");var t=o.getArg(n,"line");var i=o.getArg(n,"column");if(t{var t=n(449);var o=n(339);var i=n(274).I;var a=n(680).H;function SourceMapGenerator(e){if(!e){e={}}this._file=o.getArg(e,"file",null);this._sourceRoot=o.getArg(e,"sourceRoot",null);this._skipValidation=o.getArg(e,"skipValidation",false);this._sources=new i;this._names=new i;this._mappings=new a;this._sourcesContents=null}SourceMapGenerator.prototype._version=3;SourceMapGenerator.fromSourceMap=function SourceMapGenerator_fromSourceMap(e){var r=e.sourceRoot;var n=new SourceMapGenerator({file:e.file,sourceRoot:r});e.eachMapping((function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};if(e.source!=null){t.source=e.source;if(r!=null){t.source=o.relative(r,t.source)}t.original={line:e.originalLine,column:e.originalColumn};if(e.name!=null){t.name=e.name}}n.addMapping(t)}));e.sources.forEach((function(t){var i=t;if(r!==null){i=o.relative(r,t)}if(!n._sources.has(i)){n._sources.add(i)}var a=e.sourceContentFor(t);if(a!=null){n.setSourceContent(t,a)}}));return n};SourceMapGenerator.prototype.addMapping=function SourceMapGenerator_addMapping(e){var r=o.getArg(e,"generated");var n=o.getArg(e,"original",null);var t=o.getArg(e,"source",null);var i=o.getArg(e,"name",null);if(!this._skipValidation){this._validateMapping(r,n,t,i)}if(t!=null){t=String(t);if(!this._sources.has(t)){this._sources.add(t)}}if(i!=null){i=String(i);if(!this._names.has(i)){this._names.add(i)}}this._mappings.add({generatedLine:r.line,generatedColumn:r.column,originalLine:n!=null&&n.line,originalColumn:n!=null&&n.column,source:t,name:i})};SourceMapGenerator.prototype.setSourceContent=function SourceMapGenerator_setSourceContent(e,r){var n=e;if(this._sourceRoot!=null){n=o.relative(this._sourceRoot,n)}if(r!=null){if(!this._sourcesContents){this._sourcesContents=Object.create(null)}this._sourcesContents[o.toSetString(n)]=r}else if(this._sourcesContents){delete this._sourcesContents[o.toSetString(n)];if(Object.keys(this._sourcesContents).length===0){this._sourcesContents=null}}};SourceMapGenerator.prototype.applySourceMap=function SourceMapGenerator_applySourceMap(e,r,n){var t=r;if(r==null){if(e.file==null){throw new Error("SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, "+'or the source map\'s "file" property. Both were omitted.')}t=e.file}var a=this._sourceRoot;if(a!=null){t=o.relative(a,t)}var u=new i;var s=new i;this._mappings.unsortedForEach((function(r){if(r.source===t&&r.originalLine!=null){var i=e.originalPositionFor({line:r.originalLine,column:r.originalColumn});if(i.source!=null){r.source=i.source;if(n!=null){r.source=o.join(n,r.source)}if(a!=null){r.source=o.relative(a,r.source)}r.originalLine=i.line;r.originalColumn=i.column;if(i.name!=null){r.name=i.name}}}var l=r.source;if(l!=null&&!u.has(l)){u.add(l)}var c=r.name;if(c!=null&&!s.has(c)){s.add(c)}}),this);this._sources=u;this._names=s;e.sources.forEach((function(r){var t=e.sourceContentFor(r);if(t!=null){if(n!=null){r=o.join(n,r)}if(a!=null){r=o.relative(a,r)}this.setSourceContent(r,t)}}),this)};SourceMapGenerator.prototype._validateMapping=function SourceMapGenerator_validateMapping(e,r,n,t){if(r&&typeof r.line!=="number"&&typeof r.column!=="number"){throw new Error("original.line and original.column are not numbers -- you probably meant to omit "+"the original mapping entirely and only map the generated position. If so, pass "+"null for the original mapping instead of an object with empty or null values.")}if(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0&&!r&&!n&&!t){return}else if(e&&"line"in e&&"column"in e&&r&&"line"in r&&"column"in r&&e.line>0&&e.column>=0&&r.line>0&&r.column>=0&&n){return}else{throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:n,original:r,name:t}))}};SourceMapGenerator.prototype._serializeMappings=function SourceMapGenerator_serializeMappings(){var e=0;var r=1;var n=0;var i=0;var a=0;var u=0;var s="";var l;var c;var p;var f;var g=this._mappings.toArray();for(var h=0,d=g.length;h0){if(!o.compareByGeneratedPositionsInflated(c,g[h-1])){continue}l+=","}}l+=t.encode(c.generatedColumn-e);e=c.generatedColumn;if(c.source!=null){f=this._sources.indexOf(c.source);l+=t.encode(f-u);u=f;l+=t.encode(c.originalLine-1-i);i=c.originalLine-1;l+=t.encode(c.originalColumn-n);n=c.originalColumn;if(c.name!=null){p=this._names.indexOf(c.name);l+=t.encode(p-a);a=p}}s+=l}return s};SourceMapGenerator.prototype._generateSourcesContent=function SourceMapGenerator_generateSourcesContent(e,r){return e.map((function(e){if(!this._sourcesContents){return null}if(r!=null){e=o.relative(r,e)}var n=o.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,n)?this._sourcesContents[n]:null}),this)};SourceMapGenerator.prototype.toJSON=function SourceMapGenerator_toJSON(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};if(this._file!=null){e.file=this._file}if(this._sourceRoot!=null){e.sourceRoot=this._sourceRoot}if(this._sourcesContents){e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)}return e};SourceMapGenerator.prototype.toString=function SourceMapGenerator_toString(){return JSON.stringify(this.toJSON())};r.h=SourceMapGenerator},351:(e,r,n)=>{var t;var o=n(591).h;var i=n(339);var a=/(\r?\n)/;var u=10;var s="$$$isSourceNode$$$";function SourceNode(e,r,n,t,o){this.children=[];this.sourceContents={};this.line=e==null?null:e;this.column=r==null?null:r;this.source=n==null?null:n;this.name=o==null?null:o;this[s]=true;if(t!=null)this.add(t)}SourceNode.fromStringWithSourceMap=function SourceNode_fromStringWithSourceMap(e,r,n){var t=new SourceNode;var o=e.split(a);var u=0;var shiftNextLine=function(){var e=getNextLine();var r=getNextLine()||"";return e+r;function getNextLine(){return u=0;r--){this.prepend(e[r])}}else if(e[s]||typeof e==="string"){this.children.unshift(e)}else{throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e)}return this};SourceNode.prototype.walk=function SourceNode_walk(e){var r;for(var n=0,t=this.children.length;n0){r=[];for(n=0;n{function getArg(e,r,n){if(r in e){return e[r]}else if(arguments.length===3){return n}else{throw new Error('"'+r+'" is a required argument.')}}r.getArg=getArg;var n=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;var t=/^data:.+\,.+$/;function urlParse(e){var r=e.match(n);if(!r){return null}return{scheme:r[1],auth:r[2],host:r[3],port:r[4],path:r[5]}}r.urlParse=urlParse;function urlGenerate(e){var r="";if(e.scheme){r+=e.scheme+":"}r+="//";if(e.auth){r+=e.auth+"@"}if(e.host){r+=e.host}if(e.port){r+=":"+e.port}if(e.path){r+=e.path}return r}r.urlGenerate=urlGenerate;function normalize(e){var n=e;var t=urlParse(e);if(t){if(!t.path){return e}n=t.path}var o=r.isAbsolute(n);var i=n.split(/\/+/);for(var a,u=0,s=i.length-1;s>=0;s--){a=i[s];if(a==="."){i.splice(s,1)}else if(a===".."){u++}else if(u>0){if(a===""){i.splice(s+1,u);u=0}else{i.splice(s,2);u--}}}n=i.join("/");if(n===""){n=o?"/":"."}if(t){t.path=n;return urlGenerate(t)}return n}r.normalize=normalize;function join(e,r){if(e===""){e="."}if(r===""){r="."}var n=urlParse(r);var o=urlParse(e);if(o){e=o.path||"/"}if(n&&!n.scheme){if(o){n.scheme=o.scheme}return urlGenerate(n)}if(n||r.match(t)){return r}if(o&&!o.host&&!o.path){o.host=r;return urlGenerate(o)}var i=r.charAt(0)==="/"?r:normalize(e.replace(/\/+$/,"")+"/"+r);if(o){o.path=i;return urlGenerate(o)}return i}r.join=join;r.isAbsolute=function(e){return e.charAt(0)==="/"||n.test(e)};function relative(e,r){if(e===""){e="."}e=e.replace(/\/$/,"");var n=0;while(r.indexOf(e+"/")!==0){var t=e.lastIndexOf("/");if(t<0){return r}e=e.slice(0,t);if(e.match(/^([^\/]+:\/)?\/*$/)){return r}++n}return Array(n+1).join("../")+r.substr(e.length+1)}r.relative=relative;var o=function(){var e=Object.create(null);return!("__proto__"in e)}();function identity(e){return e}function toSetString(e){if(isProtoString(e)){return"$"+e}return e}r.toSetString=o?identity:toSetString;function fromSetString(e){if(isProtoString(e)){return e.slice(1)}return e}r.fromSetString=o?identity:fromSetString;function isProtoString(e){if(!e){return false}var r=e.length;if(r<9){return false}if(e.charCodeAt(r-1)!==95||e.charCodeAt(r-2)!==95||e.charCodeAt(r-3)!==111||e.charCodeAt(r-4)!==116||e.charCodeAt(r-5)!==111||e.charCodeAt(r-6)!==114||e.charCodeAt(r-7)!==112||e.charCodeAt(r-8)!==95||e.charCodeAt(r-9)!==95){return false}for(var n=r-10;n>=0;n--){if(e.charCodeAt(n)!==36){return false}}return true}function compareByOriginalPositions(e,r,n){var t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0||n){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0){return t}t=e.generatedLine-r.generatedLine;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByOriginalPositions=compareByOriginalPositions;function compareByGeneratedPositionsDeflated(e,r,n){var t=e.generatedLine-r.generatedLine;if(t!==0){return t}t=e.generatedColumn-r.generatedColumn;if(t!==0||n){return t}t=strcmp(e.source,r.source);if(t!==0){return t}t=e.originalLine-r.originalLine;if(t!==0){return t}t=e.originalColumn-r.originalColumn;if(t!==0){return t}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsDeflated=compareByGeneratedPositionsDeflated;function strcmp(e,r){if(e===r){return 0}if(e===null){return 1}if(r===null){return-1}if(e>r){return 1}return-1}function compareByGeneratedPositionsInflated(e,r){var n=e.generatedLine-r.generatedLine;if(n!==0){return n}n=e.generatedColumn-r.generatedColumn;if(n!==0){return n}n=strcmp(e.source,r.source);if(n!==0){return n}n=e.originalLine-r.originalLine;if(n!==0){return n}n=e.originalColumn-r.originalColumn;if(n!==0){return n}return strcmp(e.name,r.name)}r.compareByGeneratedPositionsInflated=compareByGeneratedPositionsInflated;function parseSourceMapInput(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}r.parseSourceMapInput=parseSourceMapInput;function computeSourceURL(e,r,n){r=r||"";if(e){if(e[e.length-1]!=="/"&&r[0]!=="/"){e+="/"}r=e+r}if(n){var t=urlParse(n);if(!t){throw new Error("sourceMapURL could not be parsed")}if(t.path){var o=t.path.lastIndexOf("/");if(o>=0){t.path=t.path.substring(0,o+1)}}r=join(urlGenerate(t),r)}return normalize(r)}r.computeSourceURL=computeSourceURL},997:(e,r,n)=>{n(591).h;r.SourceMapConsumer=n(952).SourceMapConsumer;n(351)},284:(e,r,n)=>{e=n.nmd(e);var t=n(997).SourceMapConsumer;var o=n(17);var i;try{i=n(147);if(!i.existsSync||!i.readFileSync){i=null}}catch(e){}var a=n(650);function dynamicRequire(e,r){return e.require(r)}var u=false;var s=false;var l=false;var c="auto";var p={};var f={};var g=/^data:application\/json[^,]+base64,/;var h=[];var d=[];function isInBrowser(){if(c==="browser")return true;if(c==="node")return false;return typeof window!=="undefined"&&typeof XMLHttpRequest==="function"&&!(window.require&&window.module&&window.process&&window.process.type==="renderer")}function hasGlobalProcessEventEmitter(){return typeof process==="object"&&process!==null&&typeof process.on==="function"}function globalProcessVersion(){if(typeof process==="object"&&process!==null){return process.version}else{return""}}function globalProcessStderr(){if(typeof process==="object"&&process!==null){return process.stderr}}function globalProcessExit(e){if(typeof process==="object"&&process!==null&&typeof process.exit==="function"){return process.exit(e)}}function handlerExec(e){return function(r){for(var n=0;n"}var n=this.getLineNumber();if(n!=null){r+=":"+n;var t=this.getColumnNumber();if(t){r+=":"+t}}}var o="";var i=this.getFunctionName();var a=true;var u=this.isConstructor();var s=!(this.isToplevel()||u);if(s){var l=this.getTypeName();if(l==="[object Object]"){l="null"}var c=this.getMethodName();if(i){if(l&&i.indexOf(l)!=0){o+=l+"."}o+=i;if(c&&i.indexOf("."+c)!=i.length-c.length-1){o+=" [as "+c+"]"}}else{o+=l+"."+(c||"")}}else if(u){o+="new "+(i||"")}else if(i){o+=i}else{o+=r;a=false}if(a){o+=" ("+r+")"}return o}function cloneCallSite(e){var r={};Object.getOwnPropertyNames(Object.getPrototypeOf(e)).forEach((function(n){r[n]=/^(?:is|get)/.test(n)?function(){return e[n].call(e)}:e[n]}));r.toString=CallSiteToString;return r}function wrapCallSite(e,r){if(r===undefined){r={nextPosition:null,curPosition:null}}if(e.isNative()){r.curPosition=null;return e}var n=e.getFileName()||e.getScriptNameOrSourceURL();if(n){var t=e.getLineNumber();var o=e.getColumnNumber()-1;var i=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;var a=i.test(globalProcessVersion())?0:62;if(t===1&&o>a&&!isInBrowser()&&!e.isEval()){o-=a}var u=mapSourcePosition({source:n,line:t,column:o});r.curPosition=u;e=cloneCallSite(e);var s=e.getFunctionName;e.getFunctionName=function(){if(r.nextPosition==null){return s()}return r.nextPosition.name||s()};e.getFileName=function(){return u.source};e.getLineNumber=function(){return u.line};e.getColumnNumber=function(){return u.column+1};e.getScriptNameOrSourceURL=function(){return u.source};return e}var l=e.isEval()&&e.getEvalOrigin();if(l){l=mapEvalOrigin(l);e=cloneCallSite(e);e.getEvalOrigin=function(){return l};return e}return e}function prepareStackTrace(e,r){if(l){p={};f={}}var n=e.name||"Error";var t=e.message||"";var o=n+": "+t;var i={nextPosition:null,curPosition:null};var a=[];for(var u=r.length-1;u>=0;u--){a.push("\n at "+wrapCallSite(r[u],i));i.nextPosition=i.curPosition}i.curPosition=i.nextPosition=null;return o+a.reverse().join("")}function getErrorSource(e){var r=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(e.stack);if(r){var n=r[1];var t=+r[2];var o=+r[3];var a=p[n];if(!a&&i&&i.existsSync(n)){try{a=i.readFileSync(n,"utf8")}catch(e){a=""}}if(a){var u=a.split(/(?:\r\n|\r|\n)/)[t-1];if(u){return n+":"+t+"\n"+u+"\n"+new Array(o).join(" ")+"^"}}}return null}function printErrorAndExit(e){var r=getErrorSource(e);var n=globalProcessStderr();if(n&&n._handle&&n._handle.setBlocking){n._handle.setBlocking(true)}if(r){console.error();console.error(r)}console.error(e.stack);globalProcessExit(1)}function shimEmitUncaughtException(){var e=process.emit;process.emit=function(r){if(r==="uncaughtException"){var n=arguments[1]&&arguments[1].stack;var t=this.listeners(r).length>0;if(n&&!t){return printErrorAndExit(arguments[1])}}return e.apply(this,arguments)}}var S=h.slice(0);var _=d.slice(0);r.wrapCallSite=wrapCallSite;r.getErrorSource=getErrorSource;r.mapSourcePosition=mapSourcePosition;r.retrieveSourceMap=v;r.install=function(r){r=r||{};if(r.environment){c=r.environment;if(["node","browser","auto"].indexOf(c)===-1){throw new Error("environment "+c+" was unknown. Available options are {auto, browser, node}")}}if(r.retrieveFile){if(r.overrideRetrieveFile){h.length=0}h.unshift(r.retrieveFile)}if(r.retrieveSourceMap){if(r.overrideRetrieveSourceMap){d.length=0}d.unshift(r.retrieveSourceMap)}if(r.hookRequire&&!isInBrowser()){var n=dynamicRequire(e,"module");var t=n.prototype._compile;if(!t.__sourceMapSupport){n.prototype._compile=function(e,r){p[r]=e;f[r]=undefined;return t.call(this,e,r)};n.prototype._compile.__sourceMapSupport=true}}if(!l){l="emptyCacheBetweenOperations"in r?r.emptyCacheBetweenOperations:false}if(!u){u=true;Error.prepareStackTrace=prepareStackTrace}if(!s){var o="handleUncaughtExceptions"in r?r.handleUncaughtExceptions:true;try{var i=dynamicRequire(e,"worker_threads");if(i.isMainThread===false){o=false}}catch(e){}if(o&&hasGlobalProcessEventEmitter()){s=true;shimEmitUncaughtException()}}};r.resetRetrieveHandlers=function(){h.length=0;d.length=0;h=S.slice(0);d=_.slice(0);v=handlerExec(d);m=handlerExec(h)}},147:e=>{"use strict";e.exports=require("fs")},17:e=>{"use strict";e.exports=require("path")}};var r={};function __webpack_require__(n){var t=r[n];if(t!==undefined){return t.exports}var o=r[n]={id:n,loaded:false,exports:{}};var i=true;try{e[n](o,o.exports,__webpack_require__);i=false}finally{if(i)delete r[n]}o.loaded=true;return o.exports}(()=>{__webpack_require__.nmd=e=>{e.paths=[];if(!e.children)e.children=[];return e}})();if(typeof __webpack_require__!=="undefined")__webpack_require__.ab=__dirname+"/";var n={};(()=>{__webpack_require__(284).install()})();module.exports=n})(); -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | clearMocks: true, 3 | moduleFileExtensions: ['js', 'ts'], 4 | testEnvironment: 'node', 5 | testMatch: ['**/*.test.ts'], 6 | testRunner: 'jest-circus/runner', 7 | transform: { 8 | '^.+\\.ts$': 'ts-jest', 9 | }, 10 | verbose: true, 11 | setupFilesAfterEnv: [ 12 | './jest.setup.js', 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | // Backup of the native console object for later re-use 2 | global._console = global.console; 3 | 4 | // Force mute console by returning a mock object that mocks the props we use 5 | global.muteConsole = () => { 6 | return { 7 | debug: jest.fn(), 8 | error: jest.fn(), 9 | info: jest.fn(), 10 | log: jest.fn(), 11 | warn: jest.fn(), 12 | }; 13 | }; 14 | 15 | // Force mute console by returning a mock object that mocks the props we use, except for "log" 16 | global.muteConsoleButLog = () => { 17 | return { 18 | debug: jest.fn(), 19 | error: jest.fn(), 20 | info: jest.fn(), 21 | log: _console.log, 22 | warn: jest.fn(), 23 | }; 24 | }; 25 | 26 | // Restore previously made "console" object 27 | global.unmuteConsole = () => _console; 28 | 29 | // Mock __non_webpack_require__ to use the standard node.js "require" 30 | global['__non_webpack_require__'] = require; 31 | -------------------------------------------------------------------------------- /lib/config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.WORKDIR = exports.BUILD_MAIN_FILENAME = exports.BUILD_DIR = void 0; 4 | const path_1 = require("path"); 5 | /** 6 | * Directory where the compiled version (JS) of the TS code is stored. 7 | * 8 | * XXX Should match the package.json:main value. 9 | */ 10 | exports.BUILD_DIR = 'lib'; 11 | /** 12 | * Name of the Action's entrypoint. 13 | * 14 | * XXX Should match the package.json:main value. 15 | */ 16 | exports.BUILD_MAIN_FILENAME = 'main.js'; 17 | /** 18 | * Artifact directory containing variables artifacts 19 | */ 20 | exports.WORKDIR = (0, path_1.join)(process.cwd(), '_store-variables'); 21 | -------------------------------------------------------------------------------- /lib/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 26 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 | return new (P || (P = Promise))(function (resolve, reject) { 28 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 | }); 33 | }; 34 | var __importDefault = (this && this.__importDefault) || function (mod) { 35 | return (mod && mod.__esModule) ? mod : { "default": mod }; 36 | }; 37 | Object.defineProperty(exports, "__esModule", { value: true }); 38 | const core = __importStar(require("@actions/core")); 39 | const manageArtifacts_1 = __importDefault(require("./manageArtifacts")); 40 | /** 41 | * Runs the GitHub Action. 42 | */ 43 | const run = () => __awaiter(void 0, void 0, void 0, function* () { 44 | if (!core.isDebug()) { 45 | core.info('Debug mode is disabled. Read more at https://github.com/UnlyEd/github-action-store-variable#how-to-enable-debug-logs'); 46 | } 47 | try { 48 | const variables = core.getInput('variables'); 49 | const delimiter = core.getInput('delimiter'); 50 | const failIfNotFound = core.getInput('failIfNotFound') == 'true'; 51 | core.debug(`Received variables: ${variables}`); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true https://github.com/actions/toolkit/blob/master/docs/action-debugging.md#how-to-access-step-debug-logs 52 | core.debug(`Using delimiter: "${delimiter}"`); 53 | core.debug(`Using failIfNotFound: "${failIfNotFound}"`); 54 | yield (0, manageArtifacts_1.default)(variables, delimiter, failIfNotFound); 55 | } 56 | catch (error) { 57 | core.setFailed(error.message); 58 | } 59 | }); 60 | //runConfigChecks(); 61 | run() 62 | .then((actionReturn) => { }) 63 | .catch((error) => { 64 | core.setFailed(error); 65 | }); 66 | -------------------------------------------------------------------------------- /lib/manageArtifacts.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 26 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 | return new (P || (P = Promise))(function (resolve, reject) { 28 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 | }); 33 | }; 34 | var __importDefault = (this && this.__importDefault) || function (mod) { 35 | return (mod && mod.__esModule) ? mod : { "default": mod }; 36 | }; 37 | Object.defineProperty(exports, "__esModule", { value: true }); 38 | /** 39 | * Receive and manage variables 40 | * Options: 41 | * 0: Set value "value" to variable "key" 42 | * 1: Retrieve value from variable "key" 43 | */ 44 | const path_1 = require("path"); 45 | const fs_1 = require("fs"); 46 | const core = __importStar(require("@actions/core")); 47 | const config_1 = require("./config"); 48 | const rimraf_1 = __importDefault(require("rimraf")); 49 | // eslint-disable-next-line @typescript-eslint/no-var-requires 50 | const artifact = require('@actions/artifact'); 51 | // eslint-disable-next-line @typescript-eslint/no-var-requires 52 | const io = require('@actions/io'); 53 | const defineVariableOperation = (variable) => { 54 | try { 55 | const variableContent = { 56 | key: variable.split('=')[0], 57 | value: variable.split('=')[1], 58 | }; 59 | if (typeof variableContent.key !== 'undefined' && typeof variableContent.value !== 'undefined') { 60 | return { 61 | operationToProceed: 0, 62 | detail: variableContent, 63 | }; 64 | } 65 | else if (typeof variableContent.key !== undefined) { 66 | return { 67 | operationToProceed: 1, 68 | detail: variableContent, 69 | }; 70 | } 71 | else { 72 | throw Error(`Both key and value are empty`); 73 | } 74 | } 75 | catch (error) { 76 | // An error will be thrown when the input doesn't have the expected format, or when the operation is unknown 77 | throw Error(`Input type error: ${error}`); 78 | } 79 | }; 80 | const storeArtifact = (variables, failIfNotFound) => __awaiter(void 0, void 0, void 0, function* () { 81 | const client = artifact.create(); 82 | const artifactOptions = { 83 | retentionDays: 1, // Only keep artifacts 1 day to avoid reach limit: https://github.com/actions/toolkit/blob/c861dd8859fe5294289fcada363ce9bc71e9d260/packages/artifact/src/internal/upload-options.ts#L1 84 | }; 85 | const artifactsUploadPromises = []; 86 | rimraf_1.default.sync(config_1.WORKDIR); 87 | (0, fs_1.mkdirSync)(config_1.WORKDIR); 88 | for (const variable of variables) { 89 | const file = (0, path_1.join)(config_1.WORKDIR, `${variable.key}.txt`); 90 | (0, fs_1.writeFileSync)(file, variable.value, { encoding: 'utf8' }); 91 | artifactsUploadPromises.push(client.uploadArtifact(variable.key, [file], process.cwd(), artifactOptions)); 92 | } 93 | try { 94 | const uploadResponses = yield Promise.all(artifactsUploadPromises); 95 | for (const variable of variables) { 96 | core.exportVariable(variable.key, variable.value); 97 | core.debug(`Imported ${variable.key}=${variable.value} and exported it back as ENV var`); 98 | } 99 | } 100 | catch (error) { 101 | const message = `Error while uploading artifact: ${error === null || error === void 0 ? void 0 : error.message}`; 102 | if (failIfNotFound) { 103 | core.setFailed(message); 104 | } 105 | else { 106 | core.warning(message); 107 | } 108 | } 109 | }); 110 | const retrieveArtifact = (variables, failIfNotFound) => __awaiter(void 0, void 0, void 0, function* () { 111 | const client = artifact.create(); 112 | rimraf_1.default.sync(config_1.WORKDIR); 113 | (0, fs_1.mkdirSync)(config_1.WORKDIR); 114 | for (const variable of variables) { 115 | try { 116 | const file = (0, path_1.join)(config_1.WORKDIR, `${variable.key}.txt`); 117 | yield client.downloadArtifact(variable.key); 118 | variable.value = (0, fs_1.readFileSync)(file, { encoding: 'utf8' }).toString(); 119 | core.exportVariable(variable.key, variable.value); 120 | core.debug(`Exported ${variable.key}=${variable.value} as ENV var`); 121 | } 122 | catch (error) { 123 | const message = `Cannot retrieve variable ${variable.key}`; 124 | if (failIfNotFound) { 125 | core.setFailed(message); 126 | } 127 | else { 128 | core.warning(message); 129 | } 130 | } 131 | } 132 | }); 133 | const manageArtifacts = (variables, delimiter, failIfNotFound) => __awaiter(void 0, void 0, void 0, function* () { 134 | const variablesDetail = []; 135 | for (const variable of variables.split(new RegExp(delimiter))) { 136 | try { 137 | variablesDetail.push(defineVariableOperation(variable)); 138 | } 139 | catch (error) { 140 | console.log(error); 141 | } 142 | } 143 | const artifactToStore = variablesDetail 144 | .filter((variable) => variable.operationToProceed === 0) 145 | .map((variable) => variable.detail); 146 | core.debug(`Artifact to store: ${JSON.stringify(artifactToStore)}`); 147 | yield storeArtifact(artifactToStore, failIfNotFound); 148 | const artifactToRetrieve = variablesDetail 149 | .filter((variable) => variable.operationToProceed === 1) 150 | .map((variable) => variable.detail); 151 | core.debug(`Artifact to retrieve: ${JSON.stringify(artifactToStore)}`); 152 | yield retrieveArtifact(artifactToRetrieve, failIfNotFound); 153 | const result = variablesDetail.reduce((variablesObject, variableToExport) => (Object.assign(Object.assign({}, variablesObject), { [variableToExport.detail.key]: variableToExport.detail.value })), {}); 154 | core.debug(`result: ${JSON.stringify(result)}`); 155 | }); 156 | exports.default = manageArtifacts; 157 | -------------------------------------------------------------------------------- /lib/types/variableStatus.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-action-store-variable", 3 | "private": true, 4 | "description": "GitHub Action - Store variables between your jobs", 5 | "homepage": "https://github.com/UnlyEd/github-action-store-variable", 6 | "main": "lib/main.js", 7 | "scripts": { 8 | "start": "yarn build", 9 | "build": "concurrently -p '{name}' -n 'tsc,ncc' -c 'gray.bgWhite,yellow.bgBlue' \"tsc --watch\" \"yarn build:gha-runtime --watch\"", 10 | "build:once": "tsc", 11 | "build:gha-runtime": "ncc build lib/main.js -o github-action-runtime --minify --source-map --license LICENSE --stats-out 'github-action-runtime/stats.json'", 12 | "format": "prettier --write **/*.ts", 13 | "format:preview": "prettier --check **/*.ts", 14 | "lint": "eslint src/**/*.ts", 15 | "bump:major": "git commit --allow-empty -m \"(MAJOR) Fake commit, bumps major version\"", 16 | "bump:minor": "git commit --allow-empty -m \"(MINOR) Fake commit, bumps minor version\"", 17 | "test": "NODE_ENV=test jest --watch", 18 | "test:once": "NODE_ENV=test jest", 19 | "test:coverage": "NODE_ENV=test jest --coverage", 20 | "test:config": "NODE_ENV=test jest --showConfig", 21 | "act:actions:list": "act --version && act --list" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/UnlyEd/github-action-store-variable.git" 26 | }, 27 | "keywords": [ 28 | "github", 29 | "github actions", 30 | "actions" 31 | ], 32 | "author": "UnlyEd", 33 | "license": "MIT", 34 | "dependencies": { 35 | "@actions/artifact": "0.5.0", 36 | "@actions/core": "1.10.0", 37 | "@actions/io": "1.0.2", 38 | "@types/rimraf": "3.0.0", 39 | "dotenv": "16.0.3", 40 | "eslint-plugin-prettier": "4.2.1", 41 | "node-fetch": "2.6.7", 42 | "rimraf": "3.0.2" 43 | }, 44 | "devDependencies": { 45 | "@babel/parser": "7.20.7", 46 | "@types/jest": "29.2.5", 47 | "@types/node": "18.11.18", 48 | "@types/node-fetch": "^2.6.2", 49 | "@typescript-eslint/parser": "5.48.0", 50 | "@vercel/ncc": "0.36.0", 51 | "concurrently": "7.6.0", 52 | "eslint": "8.31.0", 53 | "eslint-plugin-github": "4.6.0", 54 | "eslint-plugin-jest": "27.2.1", 55 | "jest": "29.3.1", 56 | "jest-circus": "29.3.1", 57 | "js-yaml": "4.1.0", 58 | "prettier": "2.8.2", 59 | "ts-jest": "29.0.3", 60 | "typescript": "4.9.4" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | 3 | /** 4 | * Directory where the compiled version (JS) of the TS code is stored. 5 | * 6 | * XXX Should match the package.json:main value. 7 | */ 8 | export const BUILD_DIR = 'lib'; 9 | 10 | /** 11 | * Name of the Action's entrypoint. 12 | * 13 | * XXX Should match the package.json:main value. 14 | */ 15 | export const BUILD_MAIN_FILENAME = 'main.js'; 16 | 17 | /** 18 | * Artifact directory containing variables artifacts 19 | */ 20 | export const WORKDIR = join(process.cwd(), '_store-variables'); 21 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import * as core from '@actions/core'; 2 | import manageArtifacts from './manageArtifacts'; 3 | 4 | /** 5 | * Runs the GitHub Action. 6 | */ 7 | const run = async (): Promise => { 8 | if (!core.isDebug()) { 9 | core.info('Debug mode is disabled. Read more at https://github.com/UnlyEd/github-action-store-variable#how-to-enable-debug-logs'); 10 | } 11 | 12 | try { 13 | const variables: string = core.getInput('variables'); 14 | const delimiter: string = core.getInput('delimiter'); 15 | const failIfNotFound: boolean = core.getInput('failIfNotFound') == 'true'; 16 | core.debug(`Received variables: ${variables}`); // debug is only output if you set the secret `ACTIONS_RUNNER_DEBUG` to true https://github.com/actions/toolkit/blob/master/docs/action-debugging.md#how-to-access-step-debug-logs 17 | core.debug(`Using delimiter: "${delimiter}"`); 18 | core.debug(`Using failIfNotFound: "${failIfNotFound}"`); 19 | 20 | await manageArtifacts(variables, delimiter, failIfNotFound); 21 | } catch (error) { 22 | core.setFailed(error.message); 23 | } 24 | }; 25 | 26 | //runConfigChecks(); 27 | run() 28 | .then((actionReturn) => {}) 29 | .catch((error) => { 30 | core.setFailed(error); 31 | }); 32 | -------------------------------------------------------------------------------- /src/manageArtifacts.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Receive and manage variables 3 | * Options: 4 | * 0: Set value "value" to variable "key" 5 | * 1: Retrieve value from variable "key" 6 | */ 7 | import { join } from 'path'; 8 | import { readFileSync, mkdirSync, writeFileSync } from 'fs'; 9 | import * as core from '@actions/core'; 10 | import { VariableDetail, VariableStatus } from './types/variableStatus'; 11 | import { WORKDIR } from './config'; 12 | import rimraf from 'rimraf'; 13 | import { ArtifactClient, UploadOptions } from '@actions/artifact'; 14 | import { UploadResponse } from '@actions/artifact/lib/internal/upload-response'; 15 | 16 | // eslint-disable-next-line @typescript-eslint/no-var-requires 17 | const artifact = require('@actions/artifact'); 18 | // eslint-disable-next-line @typescript-eslint/no-var-requires 19 | const io = require('@actions/io'); 20 | 21 | const defineVariableOperation = (variable: string): VariableStatus => { 22 | try { 23 | const variableContent: VariableDetail = { 24 | key: variable.split('=')[0], 25 | value: variable.split('=')[1], 26 | }; 27 | if (typeof variableContent.key !== 'undefined' && typeof variableContent.value !== 'undefined') { 28 | return { 29 | operationToProceed: 0, 30 | detail: variableContent, 31 | }; 32 | } else if (typeof variableContent.key !== undefined) { 33 | return { 34 | operationToProceed: 1, 35 | detail: variableContent, 36 | }; 37 | } else { 38 | throw Error(`Both key and value are empty`); 39 | } 40 | } catch (error) { 41 | // An error will be thrown when the input doesn't have the expected format, or when the operation is unknown 42 | throw Error(`Input type error: ${error}`); 43 | } 44 | }; 45 | 46 | const storeArtifact = async (variables: VariableDetail[], failIfNotFound: boolean): Promise => { 47 | const client: ArtifactClient = artifact.create(); 48 | const artifactOptions: UploadOptions = { 49 | retentionDays: 1, // Only keep artifacts 1 day to avoid reach limit: https://github.com/actions/toolkit/blob/c861dd8859fe5294289fcada363ce9bc71e9d260/packages/artifact/src/internal/upload-options.ts#L1 50 | }; 51 | const artifactsUploadPromises: Promise[] = []; 52 | 53 | rimraf.sync(WORKDIR); 54 | mkdirSync(WORKDIR); 55 | 56 | for (const variable of variables) { 57 | const file: string = join(WORKDIR, `${variable.key}.txt`); 58 | 59 | writeFileSync(file, variable.value, { encoding: 'utf8' }); 60 | artifactsUploadPromises.push(client.uploadArtifact(variable.key, [file], process.cwd(), artifactOptions)); 61 | } 62 | try { 63 | const uploadResponses = await Promise.all(artifactsUploadPromises); 64 | for (const variable of variables) { 65 | core.exportVariable(variable.key, variable.value); 66 | core.debug(`Imported ${variable.key}=${variable.value} and exported it back as ENV var`); 67 | } 68 | } catch (error) { 69 | const message = `Error while uploading artifact: ${error?.message}`; 70 | if (failIfNotFound) { 71 | core.setFailed(message); 72 | } else { 73 | core.warning(message); 74 | } 75 | } 76 | }; 77 | 78 | const retrieveArtifact = async (variables: VariableDetail[], failIfNotFound: boolean): Promise => { 79 | const client: ArtifactClient = artifact.create(); 80 | 81 | rimraf.sync(WORKDIR); 82 | mkdirSync(WORKDIR); 83 | for (const variable of variables) { 84 | try { 85 | const file = join(WORKDIR, `${variable.key}.txt`); 86 | await client.downloadArtifact(variable.key); 87 | variable.value = readFileSync(file, { encoding: 'utf8' }).toString(); 88 | core.exportVariable(variable.key, variable.value); 89 | core.debug(`Exported ${variable.key}=${variable.value} as ENV var`); 90 | } catch (error) { 91 | const message = `Cannot retrieve variable ${variable.key}`; 92 | if (failIfNotFound) { 93 | core.setFailed(message); 94 | } else { 95 | core.warning(message); 96 | } 97 | } 98 | } 99 | }; 100 | 101 | const manageArtifacts = async (variables: string, delimiter: string, failIfNotFound: boolean): Promise => { 102 | const variablesDetail: VariableStatus[] = []; 103 | 104 | for (const variable of variables.split(new RegExp(delimiter))) { 105 | try { 106 | variablesDetail.push(defineVariableOperation(variable)); 107 | } catch (error) { 108 | console.log(error); 109 | } 110 | } 111 | 112 | const artifactToStore = variablesDetail 113 | .filter((variable: VariableStatus) => variable.operationToProceed === 0) 114 | .map((variable: VariableStatus) => variable.detail); 115 | core.debug(`Artifact to store: ${JSON.stringify(artifactToStore)}`); 116 | await storeArtifact(artifactToStore, failIfNotFound); 117 | 118 | const artifactToRetrieve = variablesDetail 119 | .filter((variable: VariableStatus) => variable.operationToProceed === 1) 120 | .map((variable: VariableStatus) => variable.detail); 121 | core.debug(`Artifact to retrieve: ${JSON.stringify(artifactToStore)}`); 122 | await retrieveArtifact(artifactToRetrieve, failIfNotFound); 123 | 124 | const result = variablesDetail.reduce( 125 | (variablesObject, variableToExport) => ({ 126 | ...variablesObject, 127 | [variableToExport.detail.key]: variableToExport.detail.value, 128 | }), 129 | {}, 130 | ); 131 | core.debug(`result: ${JSON.stringify(result)}`); 132 | }; 133 | 134 | export default manageArtifacts; 135 | -------------------------------------------------------------------------------- /src/types/variableStatus.ts: -------------------------------------------------------------------------------- 1 | export type VariableStatus = { 2 | operationToProceed: number, 3 | detail: VariableDetail 4 | } 5 | 6 | export type VariableDetail = { 7 | key: string, 8 | value: string 9 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 4 | "target": "es6", 5 | /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | "module": "commonjs", 7 | /* Redirect output structure to the directory. */ 8 | "outDir": "./lib", 9 | /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 10 | "rootDir": "./src", 11 | /* Enable all strict type-checking options. */ 12 | "strict": true, 13 | /* Raise error on expressions and declarations with an implied 'any' type. */ 14 | "noImplicitAny": true, 15 | /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 16 | "esModuleInterop": true, 17 | /* Avoid errors on try/catch */ 18 | "useUnknownInCatchVariables": false 19 | }, 20 | "exclude": [ 21 | "node_modules", 22 | "**/*.test.ts" 23 | ] 24 | } 25 | --------------------------------------------------------------------------------