mirror of
https://github.com/gradle/wrapper-validation-action.git
synced 2025-04-22 23:29:19 +08:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f9c9c575b8 | ||
|
88425854a3 | ||
|
9ba54b687b | ||
|
26ffd686ec | ||
|
216d1ad2b3 | ||
|
5188e9b552 | ||
|
460a3ca55f | ||
|
b5418f5a58 | ||
|
6613b81c19 | ||
|
35bb224882 | ||
|
ea90fd0c75 | ||
|
b231772637 | ||
|
ad66d65d25 | ||
|
34f4d9f0dc | ||
|
4a956f6d02 | ||
|
63d15e7a1e |
@ -1,3 +0,0 @@
|
|||||||
dist/
|
|
||||||
lib/
|
|
||||||
node_modules/
|
|
@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["jest", "@typescript-eslint"],
|
|
||||||
"extends": ["plugin:github/recommended"],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 9,
|
|
||||||
"sourceType": "module",
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"eslint-comments/no-use": "off",
|
|
||||||
"import/no-namespace": "off",
|
|
||||||
"i18n-text/no-en": "off",
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"sort-imports": "off",
|
|
||||||
"@typescript-eslint/no-unused-vars": "error",
|
|
||||||
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
|
|
||||||
"@typescript-eslint/no-require-imports": "error",
|
|
||||||
"@typescript-eslint/array-type": "error",
|
|
||||||
"@typescript-eslint/await-thenable": "error",
|
|
||||||
"camelcase": "off",
|
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
|
|
||||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
|
||||||
"@typescript-eslint/no-array-constructor": "error",
|
|
||||||
"@typescript-eslint/no-empty-interface": "error",
|
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
|
||||||
"@typescript-eslint/no-extraneous-class": "error",
|
|
||||||
"@typescript-eslint/no-for-in-array": "error",
|
|
||||||
"@typescript-eslint/no-inferrable-types": "error",
|
|
||||||
"@typescript-eslint/no-misused-new": "error",
|
|
||||||
"@typescript-eslint/no-namespace": "error",
|
|
||||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
|
||||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
|
||||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
|
||||||
"@typescript-eslint/no-useless-constructor": "error",
|
|
||||||
"@typescript-eslint/no-var-requires": "error",
|
|
||||||
"@typescript-eslint/prefer-for-of": "warn",
|
|
||||||
"@typescript-eslint/prefer-function-type": "warn",
|
|
||||||
"@typescript-eslint/prefer-includes": "error",
|
|
||||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
|
||||||
"@typescript-eslint/promise-function-async": "error",
|
|
||||||
"@typescript-eslint/require-array-sort-compare": "error",
|
|
||||||
"@typescript-eslint/restrict-plus-operands": "error",
|
|
||||||
"semi": "off",
|
|
||||||
"@typescript-eslint/semi": ["error", "never"],
|
|
||||||
"@typescript-eslint/type-annotation-spacing": "error",
|
|
||||||
"@typescript-eslint/unbound-method": "error"
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es6": true,
|
|
||||||
"jest/globals": true
|
|
||||||
}
|
|
||||||
}
|
|
11
.github/dependabot.yml
vendored
11
.github/dependabot.yml
vendored
@ -8,14 +8,3 @@ updates:
|
|||||||
github-actions:
|
github-actions:
|
||||||
patterns:
|
patterns:
|
||||||
- "*"
|
- "*"
|
||||||
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
ignore:
|
|
||||||
- dependency-name: "@types/node"
|
|
||||||
groups:
|
|
||||||
npm-dependencies:
|
|
||||||
patterns:
|
|
||||||
- "*"
|
|
||||||
|
51
.github/workflows/check-dist.yml
vendored
51
.github/workflows/check-dist.yml
vendored
@ -1,51 +0,0 @@
|
|||||||
# `dist/index.js` is a special file in Actions.
|
|
||||||
# When you reference an action with `uses:` in a workflow,
|
|
||||||
# `index.js` is the code that will run.
|
|
||||||
# For our project, we generate this file through a build process from other source files.
|
|
||||||
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
|
||||||
name: Check dist directory
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- releases/**
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-dist:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
npm -v
|
|
||||||
node -v
|
|
||||||
npm clean-install
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: Compare the expected and actual dist/ directories
|
|
||||||
run: |
|
|
||||||
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
|
||||||
echo "Detected uncommitted changes after build. See status below:"
|
|
||||||
git diff
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
id: diff
|
|
||||||
|
|
||||||
# If index.js was different than expected, upload the expected version as an artifact
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
|
||||||
with:
|
|
||||||
name: dist
|
|
||||||
path: dist/
|
|
42
.github/workflows/ci.yml
vendored
42
.github/workflows/ci.yml
vendored
@ -7,22 +7,6 @@ on: # rebuild any PRs and main branch changes
|
|||||||
- 'releases/*'
|
- 'releases/*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build: # make sure build/ci work properly
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: npm
|
|
||||||
- name: Build and test
|
|
||||||
run: |
|
|
||||||
npm -v
|
|
||||||
node -v
|
|
||||||
npm clean-install
|
|
||||||
npm run all
|
|
||||||
|
|
||||||
|
|
||||||
# Integration test for successful validation of wrappers
|
# Integration test for successful validation of wrappers
|
||||||
test-validation-success:
|
test-validation-success:
|
||||||
@ -31,19 +15,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
|
|
||||||
- name: Build action (pull request)
|
|
||||||
# Pull requests are not expected to update `dist/index.js` themselves; therefore build `dist/index.js`
|
|
||||||
# here before running integration test
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
run: |
|
|
||||||
npm clean-install
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: Run wrapper-validation-action
|
- name: Run wrapper-validation-action
|
||||||
id: action-test
|
id: action-test
|
||||||
uses: ./
|
uses: ./
|
||||||
@ -71,19 +42,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
|
|
||||||
- name: Build action (pull request)
|
|
||||||
# Pull requests are not expected to update `dist/index.js` themselves; therefore build `dist/index.js`
|
|
||||||
# here before running integration test
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
run: |
|
|
||||||
npm clean-install
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
- name: Run wrapper-validation-action
|
- name: Run wrapper-validation-action
|
||||||
id: action-test
|
id: action-test
|
||||||
uses: ./
|
uses: ./
|
||||||
|
56
.github/workflows/codeql-analysis.yml
vendored
56
.github/workflows/codeql-analysis.yml
vendored
@ -1,56 +0,0 @@
|
|||||||
name: "CodeQL"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
pull_request:
|
|
||||||
# The branches below must be a subset of the branches above
|
|
||||||
branches: [ main ]
|
|
||||||
schedule:
|
|
||||||
- cron: '24 4 * * 6'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
analyze:
|
|
||||||
name: Analyze
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
language: [ 'javascript' ]
|
|
||||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
|
||||||
# Learn more:
|
|
||||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v3
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
||||||
# By default, queries listed here will override any specified in a config file.
|
|
||||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
||||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
|
||||||
- name: Autobuild
|
|
||||||
uses: github/codeql-action/autobuild@v3
|
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
|
||||||
# 📚 https://git.io/JvXDl
|
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
|
||||||
# and modify them (or add more) to build your code if your project
|
|
||||||
# uses a compiled language
|
|
||||||
|
|
||||||
#- run: |
|
|
||||||
# make bootstrap
|
|
||||||
# make release
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
|
||||||
uses: github/codeql-action/analyze@v3
|
|
92
.github/workflows/update-checksums-file.js
vendored
92
.github/workflows/update-checksums-file.js
vendored
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Updates the `wrapper-checksums.json` file
|
|
||||||
*
|
|
||||||
* This is intended to be executed by the GitHub workflow, but can also be run
|
|
||||||
* manually.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
const httpm = require('typed-rest-client/HttpClient')
|
|
||||||
|
|
||||||
const path = require('path')
|
|
||||||
const fs = require('fs')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<void>}
|
|
||||||
*/
|
|
||||||
async function main() {
|
|
||||||
const httpc = new httpm.HttpClient(
|
|
||||||
'gradle/wrapper-validation-action/update-checksums-workflow',
|
|
||||||
undefined,
|
|
||||||
{allowRetries: true, maxRetries: 3}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} url
|
|
||||||
* @returns {Promise<string>}
|
|
||||||
*/
|
|
||||||
async function httpGetText(url) {
|
|
||||||
const response = await httpc.get(url)
|
|
||||||
return await response.readBody()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} ApiVersionEntry
|
|
||||||
* @property {string} version - version name
|
|
||||||
* @property {string=} wrapperChecksumUrl - wrapper checksum URL; not present for old versions
|
|
||||||
* @property {boolean} snapshot - whether this is a snapshot version
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {Promise<ApiVersionEntry[]>}
|
|
||||||
*/
|
|
||||||
async function httpGetVersions() {
|
|
||||||
return JSON.parse(
|
|
||||||
await httpGetText('https://services.gradle.org/versions/all')
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const versions = (await httpGetVersions())
|
|
||||||
// Only include versions with checksum
|
|
||||||
.filter(e => e.wrapperChecksumUrl !== undefined)
|
|
||||||
// Ignore snapshots; they are changing frequently so no point in including them in checksums file
|
|
||||||
.filter(e => !e.snapshot)
|
|
||||||
console.info(`Got ${versions.length} relevant Gradle versions`)
|
|
||||||
|
|
||||||
// Note: For simplicity don't sort the entries but keep the order from the API; this also has the
|
|
||||||
// advantage that the latest versions come first, so compared to appending versions at the end
|
|
||||||
// this will not cause redundant Git diff due to trailing `,` being forbidden by JSON
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} FileVersionEntry
|
|
||||||
* @property {string} version
|
|
||||||
* @property {string} checksum
|
|
||||||
*/
|
|
||||||
/** @type {FileVersionEntry[]} */
|
|
||||||
const fileVersions = []
|
|
||||||
for (const entry of versions) {
|
|
||||||
/** @type {string} */
|
|
||||||
// @ts-ignore
|
|
||||||
const checksumUrl = entry.wrapperChecksumUrl
|
|
||||||
const checksum = await httpGetText(checksumUrl)
|
|
||||||
fileVersions.push({version: entry.version, checksum})
|
|
||||||
}
|
|
||||||
|
|
||||||
const jsonPath = path.resolve(
|
|
||||||
__dirname,
|
|
||||||
'..',
|
|
||||||
'..',
|
|
||||||
'src',
|
|
||||||
'wrapper-checksums.json'
|
|
||||||
)
|
|
||||||
console.info(`Writing checksums file to ${jsonPath}`)
|
|
||||||
// Write pretty-printed JSON (and add trailing line break)
|
|
||||||
fs.writeFileSync(jsonPath, JSON.stringify(fileVersions, null, 2) + '\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
// Manually set error exit code, otherwise error is logged but script exits successfully
|
|
||||||
process.exitCode = 1
|
|
||||||
})
|
|
49
.github/workflows/update-checksums-file.yml
vendored
49
.github/workflows/update-checksums-file.yml
vendored
@ -1,49 +0,0 @@
|
|||||||
name: 'Update Wrapper checksums file'
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# Run weekly (at arbitrary time)
|
|
||||||
- cron: '24 5 * * 6'
|
|
||||||
# Support running workflow manually
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update-checksums:
|
|
||||||
name: Update checksums
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
cache: npm
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
npm install typed-rest-client@1.8.11 --no-save
|
|
||||||
|
|
||||||
- name: Update checksums file
|
|
||||||
run: node ./.github/workflows/update-checksums-file.js
|
|
||||||
|
|
||||||
# If there are no changes, this action will not create a pull request
|
|
||||||
- name: Create or update pull request
|
|
||||||
uses: peter-evans/create-pull-request@v6
|
|
||||||
with:
|
|
||||||
branch: bot/wrapper-checksums-update
|
|
||||||
commit-message: Update known wrapper checksums
|
|
||||||
title: Update known wrapper checksums
|
|
||||||
# Note: Unfortunately this action cannot trigger the regular workflows for the PR automatically, see
|
|
||||||
# https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#triggering-further-workflow-runs
|
|
||||||
# Therefore suggest below to close and then reopen the PR
|
|
||||||
body: |
|
|
||||||
Automatically generated pull request to update the known wrapper checksums.
|
|
||||||
|
|
||||||
In case of conflicts, manually run the workflow from the [Actions tab](https://github.com/gradle/wrapper-validation-action/actions/workflows/update-checksums-file.yml), the changes will then be force-pushed onto this pull request branch.
|
|
||||||
Do not manually update the pull request branch; those changes might get overwritten.
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> GitHub workflows have not been executed for this pull request yet. Before merging, close and then directly reopen this pull request to trigger the workflows.
|
|
102
.gitignore
vendored
102
.gitignore
vendored
@ -1,102 +0,0 @@
|
|||||||
# Dependency directory
|
|
||||||
node_modules
|
|
||||||
|
|
||||||
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
|
||||||
typings/
|
|
||||||
|
|
||||||
# TypeScript cache
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
.env.test
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
|
|
||||||
# next.js build output
|
|
||||||
.next
|
|
||||||
|
|
||||||
# nuxt.js build output
|
|
||||||
.nuxt
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# OS metadata
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
|
|
||||||
# Ignore built ts files
|
|
||||||
__tests__/runner/*
|
|
||||||
lib/**/*
|
|
||||||
|
|
||||||
.idea/
|
|
||||||
*.iml
|
|
@ -1,3 +0,0 @@
|
|||||||
dist/
|
|
||||||
lib/
|
|
||||||
node_modules/
|
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 80,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": false,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"bracketSpacing": false,
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"parser": "typescript",
|
|
||||||
"endOfLine": "auto"
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
# Configuration file for asdf version manager
|
|
||||||
nodejs 20.10.0
|
|
@ -1,12 +0,0 @@
|
|||||||
## Project Goals
|
|
||||||
|
|
||||||
We aim to keep the scope of this project limited so that it is easy for maintainers to apply and forget about.
|
|
||||||
|
|
||||||
### Goals
|
|
||||||
|
|
||||||
To verify that all the gradle-wrapper.jar(s) in a given GitHub repository or pull request against that repo is an official Gradle Wrapper release.
|
|
||||||
|
|
||||||
### Non-Goals
|
|
||||||
|
|
||||||
It is not the goal of this action to verify that the gradle-wrapper.jar matches a specific version of Gradle,
|
|
||||||
nor that the version declared in the build.gradle or gradle-wrapper.properties file matches.
|
|
109
README.md
109
README.md
@ -1,6 +1,18 @@
|
|||||||
<p align="center">
|
> [!IMPORTANT]
|
||||||
<a href="https://github.com/gradle/wrapper-validation-action/actions"><img alt="gradle/wrapper-validation-action status" src="https://github.com/gradle/wrapper-validation-action/workflows/ci/badge.svg"></a>
|
> As of `v3` this action has been superceded by `gradle/actions/wrapper-validation`.
|
||||||
</p>
|
> Any workflow that uses `gradle/wrapper-validation-action@v3` will transparently delegate to `gradle/actions/wrapper-validation@v3`.
|
||||||
|
>
|
||||||
|
> Users are encouraged to update their workflows, replacing:
|
||||||
|
> ```
|
||||||
|
> uses: gradle/wrapper-validation-action@v3
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> with
|
||||||
|
> ```
|
||||||
|
> uses: gradle/actions/wrapper-validation@v3
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> See the [wrapper-validation documentation](https://github.com/gradle/actions/tree/main/wrapper-validation) for up-to-date documentation for `gradle/actions/wrapper-validation`.
|
||||||
|
|
||||||
# Gradle Wrapper Validation Action
|
# Gradle Wrapper Validation Action
|
||||||
|
|
||||||
@ -8,56 +20,8 @@ This action validates the checksums of _all_ [Gradle Wrapper](https://docs.gradl
|
|||||||
|
|
||||||
The action should be run in the root of the repository, as it will recursively search for any files named `gradle-wrapper.jar`.
|
The action should be run in the root of the repository, as it will recursively search for any files named `gradle-wrapper.jar`.
|
||||||
|
|
||||||
## The Gradle Wrapper Problem in Open Source
|
### Example workflow
|
||||||
|
|
||||||
The `gradle-wrapper.jar` is a binary blob of executable code that is checked into nearly
|
|
||||||
[2.8 Million GitHub Repositories](https://github.com/search?l=&q=filename%3Agradle-wrapper.jar&type=Code).
|
|
||||||
|
|
||||||
Searching across GitHub you can find many pull requests (PRs) with helpful titles like 'Update to Gradle xxx'.
|
|
||||||
Many of these PRs are contributed by individuals outside of the organization maintaining the project.
|
|
||||||
|
|
||||||
Many maintainers are incredibly grateful for these kinds of contributions as it takes an item off of their backlog.
|
|
||||||
We assume that most maintainers do not consider the security implications of accepting the Gradle Wrapper binary from external contributors.
|
|
||||||
There is a certain amount of blind trust open source maintainers have.
|
|
||||||
Further compounding the issue is that maintainers are most often greeted in these PRs with a diff to the `gradle-wrapper.jar` that looks like this.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
A fairly simple social engineering supply chain attack against open source would be contribute a helpful “Updated to Gradle xxx” PR that contains malicious code hidden inside this binary JAR.
|
|
||||||
A malicious `gradle-wrapper.jar` could execute, download, or install arbitrary code while otherwise behaving like a completely normal `gradle-wrapper.jar`.
|
|
||||||
|
|
||||||
## Solution
|
|
||||||
|
|
||||||
We have created a simple GitHub Action that can be applied to any GitHub repository.
|
|
||||||
This GitHub Action will do one simple task:
|
|
||||||
verify that any and all `gradle-wrapper.jar` files in the repository match the SHA-256 checksums of any of our official releases.
|
|
||||||
|
|
||||||
If any are found that do not match the SHA-256 checksums of our official releases, the action will fail.
|
|
||||||
|
|
||||||
Additionally, the action will find and SHA-256 hash all
|
|
||||||
[homoglyph](https://en.wikipedia.org/wiki/Homoglyph)
|
|
||||||
variants of files named `gradle-wrapper.jar`,
|
|
||||||
for example a file named `gradlе-wrapper.jar` (which uses a Cyrillic `е` instead of `e`).
|
|
||||||
The goal is to prevent homoglyph attacks which may be very difficult to spot in a GitHub diff.
|
|
||||||
We created an example [Homoglyph attack PR here](https://github.com/JLLeitschuh/playframework/pull/1/files).
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
### Add to an existing Workflow
|
|
||||||
|
|
||||||
Simply add this action to your workflow **after** having checked out your source tree and **before** running any Gradle build:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
uses: gradle/wrapper-validation-action@v2
|
|
||||||
```
|
|
||||||
|
|
||||||
This action step should precede any step using `gradle/gradle-build-action` or `gradle/actions/setup-gradle`.
|
|
||||||
|
|
||||||
### Add a new dedicated Workflow
|
|
||||||
|
|
||||||
Here's a sample complete workflow you can add to your repositories:
|
|
||||||
|
|
||||||
**`.github/workflows/gradle-wrapper-validation.yml`**
|
|
||||||
```yaml
|
```yaml
|
||||||
name: "Validate Gradle Wrapper"
|
name: "Validate Gradle Wrapper"
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
@ -68,43 +32,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: gradle/wrapper-validation-action@v2
|
- uses: gradle/wrapper-validation-action@v3
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing to an external GitHub Repository
|
As of `v3`, the `gradle/wrapper-validation-action` action delegates to `gradle/actions/wrapper-validation` with the same version.
|
||||||
|
Configuration and usage of these actions is identical for releases with the same version number.
|
||||||
|
|
||||||
Since [GitHub Actions](https://github.com/features/actions)
|
See the [full wrapper-validation documentation](https://github.com/gradle/actions/tree/main/wrapper-validation) for more details.
|
||||||
are completely free for open source projects and are automatically enabled on almost all projects,
|
|
||||||
adding this check to a project's build is as simple as contributing a PR.
|
|
||||||
Enabling the check requires no overhead on behalf of the project maintainer beyond merging the action.
|
|
||||||
|
|
||||||
You can add this action to your favorite Gradle based project without checking out their source locally via the
|
|
||||||
GitHub Web UI thanks to the 'Create new file' button.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Simply add a new file named `.github/workflows/gradle-wrapper-validation.yml` with the contents mentioned above.
|
|
||||||
|
|
||||||
We recommend the message commit contents of:
|
|
||||||
- Title: `Official Gradle Wrapper Validation Action`
|
|
||||||
- Body (at minimum): `See: https://github.com/gradle/wrapper-validation-action`
|
|
||||||
|
|
||||||
From there, you can easily follow the rest of the prompts to create a Pull Request against the project.
|
|
||||||
|
|
||||||
## Reporting Failures
|
|
||||||
|
|
||||||
If this GitHub action fails because a `gradle-wrapper.jar` doesn't match one of our published SHA-256 checksums,
|
|
||||||
we highly recommend that you reach out to us at [security@gradle.com](mailto:security@gradle.com).
|
|
||||||
|
|
||||||
**Note:** `gradle-wrapper.jar` generated by Gradle 3.3 to 4.0 are not verifiable because those files were dynamically generated by Gradle in a non-reproducible way. It's not possible to verify the `gradle-wrapper.jar` for those versions are legitimate using a hash comparison. You should try to determine if the `gradle-wrapper.jar` was generated by one of these versions before running the build.
|
|
||||||
|
|
||||||
If the Gradle version in `gradle-wrapper.properties` is out of this range, you may need to regenerate the `gradle-wrapper.jar` by running `./gradlew wrapper`. If you need to use a version of Gradle between 3.3 and 4.0, you can use a newer version of Gradle to generate the `gradle-wrapper.jar`.
|
|
||||||
|
|
||||||
If you're curious and want to explore what the differences are between the `gradle-wrapper.jar` in your possession
|
|
||||||
and one of our valid release, you can compare them using this online utility: [diffoscope](https://try.diffoscope.org/).
|
|
||||||
Regardless of what you find, we still kindly request that you reach out to us and let us know.
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
To learn more about verifying the Gradle Wrapper JAR locally, see our
|
|
||||||
[guide on the topic](https://docs.gradle.org/current/userguide/gradle_wrapper.html#wrapper_checksum_verification).
|
|
||||||
|
14
RELEASING.md
14
RELEASING.md
@ -1,14 +0,0 @@
|
|||||||
# Release
|
|
||||||
|
|
||||||
* starting on `main`
|
|
||||||
* `npm install`
|
|
||||||
* `npm run all`
|
|
||||||
* Commit and push any changes to the `dist` directory. Wait for CI.
|
|
||||||
* `git tag v1.0.x && git push --tags` with the actual version number
|
|
||||||
* `git tag -f -a v1 && git push -f --tags`
|
|
||||||
* go to https://github.com/gradle/wrapper-validation-action/releases
|
|
||||||
* edit and publish the now drafted `v1` release
|
|
||||||
* create a new release from the new full version number `v1.0.x`, list the fixed issues and publish the release
|
|
||||||
* go to https://github.com/marketplace/actions/gradle-wrapper-validation
|
|
||||||
* verify that it displays the latest README
|
|
||||||
* verify that the version dropdown displays the new version
|
|
@ -1,55 +0,0 @@
|
|||||||
import * as checksums from '../src/checksums'
|
|
||||||
import nock from 'nock'
|
|
||||||
import {afterEach, describe, expect, test, jest} from '@jest/globals'
|
|
||||||
|
|
||||||
jest.setTimeout(30000)
|
|
||||||
|
|
||||||
test('has loaded hardcoded wrapper jars checksums', async () => {
|
|
||||||
// Sanity check that generated checksums file is not empty and was properly imported
|
|
||||||
expect(checksums.KNOWN_VALID_CHECKSUMS.size).toBeGreaterThan(10)
|
|
||||||
// Verify that checksums of arbitrary versions are contained
|
|
||||||
expect(
|
|
||||||
checksums.KNOWN_VALID_CHECKSUMS.get(
|
|
||||||
'660ab018b8e319e9ae779fdb1b7ac47d0321bde953bf0eb4545f14952cfdcaa3'
|
|
||||||
)
|
|
||||||
).toEqual(new Set(['4.10.3']))
|
|
||||||
expect(
|
|
||||||
checksums.KNOWN_VALID_CHECKSUMS.get(
|
|
||||||
'28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e'
|
|
||||||
)
|
|
||||||
).toEqual(new Set(['6.0-rc-1', '6.0-rc-2', '6.0-rc-3', '6.0', '6.0.1']))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('fetches wrapper jars checksums', async () => {
|
|
||||||
const validChecksums = await checksums.fetchValidChecksums(false)
|
|
||||||
expect(validChecksums.size).toBeGreaterThan(10)
|
|
||||||
// Verify that checksum of arbitrary version is contained
|
|
||||||
expect(
|
|
||||||
validChecksums.has(
|
|
||||||
// Checksum for version 6.0
|
|
||||||
'28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e'
|
|
||||||
)
|
|
||||||
).toBe(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('retry', () => {
|
|
||||||
afterEach(() => {
|
|
||||||
nock.cleanAll()
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('for /versions/all API', () => {
|
|
||||||
test('retry three times', async () => {
|
|
||||||
nock('https://services.gradle.org', {allowUnmocked: true})
|
|
||||||
.get('/versions/all')
|
|
||||||
.times(3)
|
|
||||||
.replyWithError({
|
|
||||||
message: 'connect ECONNREFUSED 104.18.191.9:443',
|
|
||||||
code: 'ECONNREFUSED'
|
|
||||||
})
|
|
||||||
|
|
||||||
const validChecksums = await checksums.fetchValidChecksums(false)
|
|
||||||
expect(validChecksums.size).toBeGreaterThan(10)
|
|
||||||
nock.isDone()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,12 +0,0 @@
|
|||||||
import * as path from 'path'
|
|
||||||
import * as find from '../src/find'
|
|
||||||
import {expect, test} from '@jest/globals'
|
|
||||||
|
|
||||||
test('finds test data wrapper jars', async () => {
|
|
||||||
const repoRoot = path.resolve('.')
|
|
||||||
const wrapperJars = await find.findWrapperJars(repoRoot)
|
|
||||||
expect(wrapperJars.length).toBe(3)
|
|
||||||
expect(wrapperJars).toContain('__tests__/data/valid/gradle-wrapper.jar')
|
|
||||||
expect(wrapperJars).toContain('__tests__/data/invalid/gradle-wrapper.jar')
|
|
||||||
expect(wrapperJars).toContain('__tests__/data/invalid/gradlе-wrapper.jar') // homoglyph
|
|
||||||
})
|
|
@ -1,12 +0,0 @@
|
|||||||
import * as path from 'path'
|
|
||||||
import * as hash from '../src/hash'
|
|
||||||
import {expect, test} from '@jest/globals'
|
|
||||||
|
|
||||||
test('can sha256 files', async () => {
|
|
||||||
const sha = await hash.sha256File(
|
|
||||||
path.resolve('__tests__/data/invalid/gradle-wrapper.jar')
|
|
||||||
)
|
|
||||||
expect(sha).toEqual(
|
|
||||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
||||||
)
|
|
||||||
})
|
|
@ -1,98 +0,0 @@
|
|||||||
import * as path from 'path'
|
|
||||||
import * as validate from '../src/validate'
|
|
||||||
import {expect, test, jest} from '@jest/globals'
|
|
||||||
|
|
||||||
jest.setTimeout(30000)
|
|
||||||
|
|
||||||
const baseDir = path.resolve('.')
|
|
||||||
|
|
||||||
test('succeeds if all found wrapper jars are valid', async () => {
|
|
||||||
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [
|
|
||||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
||||||
])
|
|
||||||
|
|
||||||
expect(result.isValid()).toBe(true)
|
|
||||||
// Only hardcoded and explicitly allowed checksums should have been used
|
|
||||||
expect(result.fetchedChecksums).toBe(false)
|
|
||||||
|
|
||||||
expect(result.toDisplayString()).toBe(
|
|
||||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
|
||||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('succeeds if all found wrapper jars are valid (and checksums are fetched from Gradle API)', async () => {
|
|
||||||
const knownValidChecksums = new Map<string, Set<string>>()
|
|
||||||
const result = await validate.findInvalidWrapperJars(
|
|
||||||
baseDir,
|
|
||||||
1,
|
|
||||||
false,
|
|
||||||
['e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'],
|
|
||||||
knownValidChecksums
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(result.isValid()).toBe(true)
|
|
||||||
// Should have fetched checksums because no known checksums were provided
|
|
||||||
expect(result.fetchedChecksums).toBe(true)
|
|
||||||
|
|
||||||
expect(result.toDisplayString()).toBe(
|
|
||||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
|
||||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('fails if invalid wrapper jars are found', async () => {
|
|
||||||
const result = await validate.findInvalidWrapperJars(baseDir, 3, false, [])
|
|
||||||
|
|
||||||
expect(result.isValid()).toBe(false)
|
|
||||||
|
|
||||||
expect(result.valid).toEqual([
|
|
||||||
new validate.WrapperJar(
|
|
||||||
'__tests__/data/valid/gradle-wrapper.jar',
|
|
||||||
'3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce'
|
|
||||||
)
|
|
||||||
])
|
|
||||||
|
|
||||||
expect(result.invalid).toEqual([
|
|
||||||
new validate.WrapperJar(
|
|
||||||
'__tests__/data/invalid/gradle-wrapper.jar',
|
|
||||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
||||||
),
|
|
||||||
new validate.WrapperJar(
|
|
||||||
'__tests__/data/invalid/gradlе-wrapper.jar', // homoglyph
|
|
||||||
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
|
|
||||||
)
|
|
||||||
])
|
|
||||||
|
|
||||||
expect(result.toDisplayString()).toBe(
|
|
||||||
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
|
||||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
|
||||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('fails if not enough wrapper jars are found', async () => {
|
|
||||||
const result = await validate.findInvalidWrapperJars(baseDir, 4, false, [])
|
|
||||||
|
|
||||||
expect(result.isValid()).toBe(false)
|
|
||||||
|
|
||||||
expect(result.errors).toEqual([
|
|
||||||
'Expected to find at least 4 Gradle Wrapper JARs but got only 3'
|
|
||||||
])
|
|
||||||
|
|
||||||
expect(result.toDisplayString()).toBe(
|
|
||||||
'✗ Found unknown Gradle Wrapper JAR files:\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradle-wrapper.jar\n' +
|
|
||||||
' e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 __tests__/data/invalid/gradlе-wrapper.jar\n' + // homoglyph
|
|
||||||
'✗ Other validation errors:\n' +
|
|
||||||
' Expected to find at least 4 Gradle Wrapper JARs but got only 3\n' +
|
|
||||||
'✓ Found known Gradle Wrapper JAR files:\n' +
|
|
||||||
' 3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce __tests__/data/valid/gradle-wrapper.jar'
|
|
||||||
)
|
|
||||||
})
|
|
14
action.yml
14
action.yml
@ -19,10 +19,20 @@ inputs:
|
|||||||
outputs:
|
outputs:
|
||||||
failed-wrapper:
|
failed-wrapper:
|
||||||
description: 'The path of the Gradle Wrapper(s) JAR that failed validation. Path is a platform-dependent relative path to git repository root. Multiple paths are separated by a | character.'
|
description: 'The path of the Gradle Wrapper(s) JAR that failed validation. Path is a platform-dependent relative path to git repository root. Multiple paths are separated by a | character.'
|
||||||
|
value: ${{ steps.wrapper-validation.outputs.failed-wrapper }}
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: 'node20'
|
using: "composite"
|
||||||
main: 'dist/index.js'
|
steps:
|
||||||
|
- name: Wrapper Validation
|
||||||
|
id: wrapper-validation
|
||||||
|
uses: gradle/actions/wrapper-validation@v3.5.0
|
||||||
|
with:
|
||||||
|
min-wrapper-count: ${{ inputs.min-wrapper-count }}
|
||||||
|
allow-snapshots: ${{ inputs.allow-snapshots }}
|
||||||
|
allow-checksums: ${{ inputs.allow-checksums }}
|
||||||
|
env:
|
||||||
|
GRADLE_ACTION_ID: gradle/wrapper-validation-action
|
||||||
|
|
||||||
branding:
|
branding:
|
||||||
icon: 'shield'
|
icon: 'shield'
|
||||||
|
30091
dist/index.js
vendored
30091
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,8 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
clearMocks: true,
|
|
||||||
moduleFileExtensions: ['js', 'ts', 'json'],
|
|
||||||
testMatch: ['**/*.test.ts'],
|
|
||||||
preset: 'ts-jest',
|
|
||||||
verbose: true,
|
|
||||||
setupFilesAfterEnv: ['./jest.setup.js']
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
jest.setTimeout(10000) // in milliseconds
|
|
6794
package-lock.json
generated
6794
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "wrapper-validation-action",
|
|
||||||
"version": "0.0.0",
|
|
||||||
"private": true,
|
|
||||||
"description": "Gradle Wrapper Validation Action",
|
|
||||||
"main": "src/main.ts",
|
|
||||||
"scripts": {
|
|
||||||
"format": "prettier --write **/*.ts",
|
|
||||||
"format-check": "prettier --check **/*.ts",
|
|
||||||
"lint": "eslint src/**/*.ts",
|
|
||||||
"check": "npm run format && npm run lint",
|
|
||||||
"compile": "ncc build",
|
|
||||||
"test": "jest",
|
|
||||||
"build": "npm run check && npm run compile",
|
|
||||||
"all": "npm run build && npm test"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/gradle/wrapper-validation-action.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"actions",
|
|
||||||
"node",
|
|
||||||
"setup"
|
|
||||||
],
|
|
||||||
"author": "Gradle Inc.",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@actions/core": "1.10.1",
|
|
||||||
"typed-rest-client": "1.8.11",
|
|
||||||
"unhomoglyph": "1.0.6"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "16.18.38",
|
|
||||||
"@typescript-eslint/parser": "6.20.0",
|
|
||||||
"@vercel/ncc": "0.38.1",
|
|
||||||
"eslint": "8.56.0",
|
|
||||||
"eslint-plugin-github": "4.10.1",
|
|
||||||
"eslint-plugin-jest": "27.6.3",
|
|
||||||
"eslint-plugin-prettier": "5.1.3",
|
|
||||||
"glob-parent": "6.0.2",
|
|
||||||
"jest": "29.7.0",
|
|
||||||
"js-yaml": "4.1.0",
|
|
||||||
"nock": "13.5.1",
|
|
||||||
"prettier": "3.2.5",
|
|
||||||
"ts-jest": "29.1.2",
|
|
||||||
"typescript": "5.3.3"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
import * as httpm from 'typed-rest-client/HttpClient'
|
|
||||||
|
|
||||||
import fileWrapperChecksums from './wrapper-checksums.json'
|
|
||||||
|
|
||||||
const httpc = new httpm.HttpClient(
|
|
||||||
'gradle/wrapper-validation-action',
|
|
||||||
undefined,
|
|
||||||
{allowRetries: true, maxRetries: 3}
|
|
||||||
)
|
|
||||||
|
|
||||||
function getKnownValidChecksums(): Map<string, Set<string>> {
|
|
||||||
const versionsMap = new Map<string, Set<string>>()
|
|
||||||
for (const entry of fileWrapperChecksums) {
|
|
||||||
const checksum = entry.checksum
|
|
||||||
|
|
||||||
let versionNames = versionsMap.get(checksum)
|
|
||||||
if (versionNames === undefined) {
|
|
||||||
versionNames = new Set()
|
|
||||||
versionsMap.set(checksum, versionNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
versionNames.add(entry.version)
|
|
||||||
}
|
|
||||||
|
|
||||||
return versionsMap
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Known checksums from previously published Wrapper versions.
|
|
||||||
*
|
|
||||||
* Maps from the checksum to the names of the Gradle versions whose wrapper has this checksum.
|
|
||||||
*/
|
|
||||||
export const KNOWN_VALID_CHECKSUMS = getKnownValidChecksums()
|
|
||||||
|
|
||||||
export async function fetchValidChecksums(
|
|
||||||
allowSnapshots: boolean
|
|
||||||
): Promise<Set<string>> {
|
|
||||||
const all = await httpGetJsonArray('https://services.gradle.org/versions/all')
|
|
||||||
const withChecksum = all.filter(
|
|
||||||
entry =>
|
|
||||||
typeof entry === 'object' &&
|
|
||||||
entry != null &&
|
|
||||||
entry.hasOwnProperty('wrapperChecksumUrl')
|
|
||||||
)
|
|
||||||
const allowed = withChecksum.filter(
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(entry: any) => allowSnapshots || !entry.snapshot
|
|
||||||
)
|
|
||||||
const checksumUrls = allowed.map(
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(entry: any) => entry.wrapperChecksumUrl as string
|
|
||||||
)
|
|
||||||
const checksums = await Promise.all(
|
|
||||||
checksumUrls.map(async (url: string) => httpGetText(url))
|
|
||||||
)
|
|
||||||
return new Set(checksums)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function httpGetJsonArray(url: string): Promise<unknown[]> {
|
|
||||||
return JSON.parse(await httpGetText(url))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function httpGetText(url: string): Promise<string> {
|
|
||||||
const response = await httpc.get(url)
|
|
||||||
return await response.readBody()
|
|
||||||
}
|
|
27
src/find.ts
27
src/find.ts
@ -1,27 +0,0 @@
|
|||||||
import * as util from 'util'
|
|
||||||
import * as path from 'path'
|
|
||||||
import * as fs from 'fs'
|
|
||||||
import unhomoglyph from 'unhomoglyph'
|
|
||||||
|
|
||||||
const readdir = util.promisify(fs.readdir)
|
|
||||||
|
|
||||||
export async function findWrapperJars(baseDir: string): Promise<string[]> {
|
|
||||||
const files = await recursivelyListFiles(baseDir)
|
|
||||||
return files
|
|
||||||
.filter(file => unhomoglyph(file).endsWith('gradle-wrapper.jar'))
|
|
||||||
.map(wrapperJar => path.relative(baseDir, wrapperJar))
|
|
||||||
.sort((a, b) => a.localeCompare(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
async function recursivelyListFiles(baseDir: string): Promise<string[]> {
|
|
||||||
const childrenNames = await readdir(baseDir)
|
|
||||||
const childrenPaths = await Promise.all(
|
|
||||||
childrenNames.map(async childName => {
|
|
||||||
const childPath = path.resolve(baseDir, childName)
|
|
||||||
return fs.lstatSync(childPath).isDirectory()
|
|
||||||
? recursivelyListFiles(childPath)
|
|
||||||
: new Promise(resolve => resolve([childPath]))
|
|
||||||
})
|
|
||||||
)
|
|
||||||
return Array.prototype.concat(...childrenPaths)
|
|
||||||
}
|
|
18
src/hash.ts
18
src/hash.ts
@ -1,18 +0,0 @@
|
|||||||
import * as crypto from 'crypto'
|
|
||||||
import * as fs from 'fs'
|
|
||||||
|
|
||||||
export async function sha256File(path: string): Promise<string> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const hash = crypto.createHash('sha256')
|
|
||||||
const stream = fs.createReadStream(path)
|
|
||||||
stream.on('data', data => hash.update(data))
|
|
||||||
stream.on('end', () => {
|
|
||||||
stream.destroy()
|
|
||||||
resolve(hash.digest('hex'))
|
|
||||||
})
|
|
||||||
stream.on('error', error => {
|
|
||||||
stream.destroy()
|
|
||||||
reject(error)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
41
src/main.ts
41
src/main.ts
@ -1,41 +0,0 @@
|
|||||||
import * as path from 'path'
|
|
||||||
import * as core from '@actions/core'
|
|
||||||
|
|
||||||
import * as validate from './validate'
|
|
||||||
|
|
||||||
export async function run(): Promise<void> {
|
|
||||||
try {
|
|
||||||
const result = await validate.findInvalidWrapperJars(
|
|
||||||
path.resolve('.'),
|
|
||||||
+core.getInput('min-wrapper-count'),
|
|
||||||
core.getInput('allow-snapshots') === 'true',
|
|
||||||
core.getInput('allow-checksums').split(',')
|
|
||||||
)
|
|
||||||
if (result.isValid()) {
|
|
||||||
core.info(result.toDisplayString())
|
|
||||||
} else {
|
|
||||||
core.setFailed(
|
|
||||||
`Gradle Wrapper Validation Failed!\n See https://github.com/gradle/wrapper-validation-action#reporting-failures\n${result.toDisplayString()}`
|
|
||||||
)
|
|
||||||
if (result.invalid.length > 0) {
|
|
||||||
core.setOutput(
|
|
||||||
'failed-wrapper',
|
|
||||||
`${result.invalid.map(w => w.path).join('|')}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof AggregateError) {
|
|
||||||
core.setFailed(`Multiple errors returned`)
|
|
||||||
for (const err of error.errors) {
|
|
||||||
core.error(`Error ${error.errors.indexOf(err)}: ${err.message}`)
|
|
||||||
}
|
|
||||||
} else if (error instanceof Error) {
|
|
||||||
core.setFailed(error.message)
|
|
||||||
} else {
|
|
||||||
core.setFailed(`Unknown object was thrown: ${error}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run()
|
|
105
src/validate.ts
105
src/validate.ts
@ -1,105 +0,0 @@
|
|||||||
import * as find from './find'
|
|
||||||
import * as checksums from './checksums'
|
|
||||||
import * as hash from './hash'
|
|
||||||
|
|
||||||
export async function findInvalidWrapperJars(
|
|
||||||
gitRepoRoot: string,
|
|
||||||
minWrapperCount: number,
|
|
||||||
allowSnapshots: boolean,
|
|
||||||
allowedChecksums: string[],
|
|
||||||
knownValidChecksums: Map<
|
|
||||||
string,
|
|
||||||
Set<string>
|
|
||||||
> = checksums.KNOWN_VALID_CHECKSUMS
|
|
||||||
): Promise<ValidationResult> {
|
|
||||||
const wrapperJars = await find.findWrapperJars(gitRepoRoot)
|
|
||||||
const result = new ValidationResult([], [])
|
|
||||||
if (wrapperJars.length < minWrapperCount) {
|
|
||||||
result.errors.push(
|
|
||||||
`Expected to find at least ${minWrapperCount} Gradle Wrapper JARs but got only ${wrapperJars.length}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (wrapperJars.length > 0) {
|
|
||||||
const notYetValidatedWrappers = []
|
|
||||||
for (const wrapperJar of wrapperJars) {
|
|
||||||
const sha = await hash.sha256File(wrapperJar)
|
|
||||||
if (allowedChecksums.includes(sha) || knownValidChecksums.has(sha)) {
|
|
||||||
result.valid.push(new WrapperJar(wrapperJar, sha))
|
|
||||||
} else {
|
|
||||||
notYetValidatedWrappers.push(new WrapperJar(wrapperJar, sha))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise fall back to fetching checksums from Gradle API and compare against them
|
|
||||||
if (notYetValidatedWrappers.length > 0) {
|
|
||||||
result.fetchedChecksums = true
|
|
||||||
const fetchedValidChecksums =
|
|
||||||
await checksums.fetchValidChecksums(allowSnapshots)
|
|
||||||
|
|
||||||
for (const wrapperJar of notYetValidatedWrappers) {
|
|
||||||
if (!fetchedValidChecksums.has(wrapperJar.checksum)) {
|
|
||||||
result.invalid.push(wrapperJar)
|
|
||||||
} else {
|
|
||||||
result.valid.push(wrapperJar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ValidationResult {
|
|
||||||
valid: WrapperJar[]
|
|
||||||
invalid: WrapperJar[]
|
|
||||||
fetchedChecksums = false
|
|
||||||
errors: string[] = []
|
|
||||||
|
|
||||||
constructor(valid: WrapperJar[], invalid: WrapperJar[]) {
|
|
||||||
this.valid = valid
|
|
||||||
this.invalid = invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
isValid(): boolean {
|
|
||||||
return this.invalid.length === 0 && this.errors.length === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
toDisplayString(): string {
|
|
||||||
let displayString = ''
|
|
||||||
if (this.invalid.length > 0) {
|
|
||||||
displayString += `✗ Found unknown Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(
|
|
||||||
this.invalid
|
|
||||||
)}`
|
|
||||||
}
|
|
||||||
if (this.errors.length > 0) {
|
|
||||||
if (displayString.length > 0) displayString += '\n'
|
|
||||||
displayString += `✗ Other validation errors:\n ${this.errors.join(
|
|
||||||
`\n `
|
|
||||||
)}`
|
|
||||||
}
|
|
||||||
if (this.valid.length > 0) {
|
|
||||||
if (displayString.length > 0) displayString += '\n'
|
|
||||||
displayString += `✓ Found known Gradle Wrapper JAR files:\n${ValidationResult.toDisplayList(
|
|
||||||
this.valid
|
|
||||||
)}`
|
|
||||||
}
|
|
||||||
return displayString
|
|
||||||
}
|
|
||||||
|
|
||||||
private static toDisplayList(wrapperJars: WrapperJar[]): string {
|
|
||||||
return ` ${wrapperJars.map(wj => wj.toDisplayString()).join(`\n `)}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WrapperJar {
|
|
||||||
path: string
|
|
||||||
checksum: string
|
|
||||||
|
|
||||||
constructor(path: string, checksum: string) {
|
|
||||||
this.path = path
|
|
||||||
this.checksum = checksum
|
|
||||||
}
|
|
||||||
|
|
||||||
toDisplayString(): string {
|
|
||||||
return `${this.checksum} ${this.path}`
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,994 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"version": "7.6.4",
|
|
||||||
"checksum": "14dfa961b6704bb3decdea06502781edaa796a82e6da41cd2e1962b14fbe21a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6-rc-4",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6-rc-3",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6-rc-2",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6-rc-1",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.6-milestone-1",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.5",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.5-rc-4",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.5-rc-3",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.5-rc-2",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.5-rc-1",
|
|
||||||
"checksum": "d3b261c2820e9e3d8d639ed084900f11f4a86050a8f83342ade7b6bc9b0d2bdd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.4",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6.3",
|
|
||||||
"checksum": "14dfa961b6704bb3decdea06502781edaa796a82e6da41cd2e1962b14fbe21a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.4-rc-3",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.4-rc-2",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.4-rc-1",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.3",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.3-rc-4",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.3-rc-3",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.3-rc-2",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.3-rc-1",
|
|
||||||
"checksum": "0336f591bc0ec9aa0c9988929b93ecc916b3c1d52aed202c7381db144aa0ef15"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2.1",
|
|
||||||
"checksum": "a8451eeda314d0568b5340498b36edf147a8f0d692c5ff58082d477abe9146e4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2",
|
|
||||||
"checksum": "a8451eeda314d0568b5340498b36edf147a8f0d692c5ff58082d477abe9146e4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6.2",
|
|
||||||
"checksum": "14dfa961b6704bb3decdea06502781edaa796a82e6da41cd2e1962b14fbe21a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2-rc-3",
|
|
||||||
"checksum": "a8451eeda314d0568b5340498b36edf147a8f0d692c5ff58082d477abe9146e4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2-rc-2",
|
|
||||||
"checksum": "5c9a1a6f50b4f8c0264b1ac69013bef9f8363733275fafa56c70c84be3276bb8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2-rc-1",
|
|
||||||
"checksum": "55e949185c26ba3ddcd2c6a4217d043bfa0ce3cc002bbbb52b709a181a513e81"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.2-milestone-1",
|
|
||||||
"checksum": "55e949185c26ba3ddcd2c6a4217d043bfa0ce3cc002bbbb52b709a181a513e81"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1.1",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1-rc-4",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1-rc-3",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1-rc-2",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.1-rc-1",
|
|
||||||
"checksum": "ed2c26eba7cfb93cc2b7785d05e534f07b5b48b5e7fc941921cd098628abca58"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0.2",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6.1",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9.4",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0.1",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-rc-5",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-rc-4",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-rc-3",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-rc-2",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-rc-1",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-6",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-5",
|
|
||||||
"checksum": "91941f522fbfd4431cf57e445fc3d5200c85f957bda2de5251353cf11174f4b5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-4",
|
|
||||||
"checksum": "577b2de036000db2e0f04f2ec842a4f1e648c8b6f9c87f29a8d896acb1732538"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6-rc-4",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6-rc-3",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6-rc-2",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-3",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6-rc-1",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9.3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-2",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "8.0-milestone-1",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.6-milestone-1",
|
|
||||||
"checksum": "c5a643cf80162e665cc228f7b16f343fef868e47d3a4836f62e18b7e17ac018a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5.1",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5-rc-5",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5-rc-4",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5-rc-3",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5-rc-2",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.5-rc-1",
|
|
||||||
"checksum": "91a239400bb638f36a1795d8fdf7939d532cdc7d794d1119b7261aac158b1e60"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.4.2",
|
|
||||||
"checksum": "575098db54a998ff1c6770b352c3b16766c09848bee7555dab09afc34e8cf590"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.4.1",
|
|
||||||
"checksum": "575098db54a998ff1c6770b352c3b16766c09848bee7555dab09afc34e8cf590"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.4",
|
|
||||||
"checksum": "575098db54a998ff1c6770b352c3b16766c09848bee7555dab09afc34e8cf590"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.4-rc-2",
|
|
||||||
"checksum": "575098db54a998ff1c6770b352c3b16766c09848bee7555dab09afc34e8cf590"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.4-rc-1",
|
|
||||||
"checksum": "575098db54a998ff1c6770b352c3b16766c09848bee7555dab09afc34e8cf590"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3.3",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3.3-rc-1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9.2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3.2",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3.1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3-rc-5",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3-rc-4",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3-rc-3",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3-rc-2",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.3-rc-1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9.1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.2",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.2-rc-3",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.2-rc-2",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.2-rc-1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.1.1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.1-rc-2",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.1-rc-1",
|
|
||||||
"checksum": "33ad4583fd7ee156f533778736fa1b4940bd83b433934d1cc4e9f608e99a6a89"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0.2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0.1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9-rc-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.9-rc-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0-rc-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0-rc-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0-milestone-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0-milestone-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8.3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8.2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "7.0-milestone-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8.1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-rc-5",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-rc-4",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-rc-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-rc-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7.1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-milestone-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-milestone-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.8-milestone-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7-rc-5",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7-rc-4",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7-rc-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7-rc-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.7-rc-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6.1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-6",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-5",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-4",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-rc-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-milestone-3",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.5.1",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-milestone-2",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.6-milestone-1",
|
|
||||||
"checksum": "e996d452d2645e70c01c11143ca2d3742734a28da2bf61f25c82bdc288c9e637"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.5",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.5-rc-1",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4.1",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.5-milestone-2",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.5-milestone-1",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4-rc-4",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4-rc-3",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4-rc-2",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.4-rc-1",
|
|
||||||
"checksum": "70239e6ca1f0d5e3b2808ef6d82390cf9ad58d3a3a0d271677a51d1b89475857"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.3",
|
|
||||||
"checksum": "1cef53de8dc192036e7b0cc47584449b0cf570a00d560bfaa6c9eabe06e1fc06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.3-rc-4",
|
|
||||||
"checksum": "1cef53de8dc192036e7b0cc47584449b0cf570a00d560bfaa6c9eabe06e1fc06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.3-rc-3",
|
|
||||||
"checksum": "1cef53de8dc192036e7b0cc47584449b0cf570a00d560bfaa6c9eabe06e1fc06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.3-rc-2",
|
|
||||||
"checksum": "1cef53de8dc192036e7b0cc47584449b0cf570a00d560bfaa6c9eabe06e1fc06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.3-rc-1",
|
|
||||||
"checksum": "1cef53de8dc192036e7b0cc47584449b0cf570a00d560bfaa6c9eabe06e1fc06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2.2",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2.1",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2-rc-3",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2-rc-2",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.2-rc-1",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1.1",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-rc-3",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-rc-2",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-rc-1",
|
|
||||||
"checksum": "96f793a18e056c23ffeec67c1f3bb8eccff5a4a407fc9ceac183527e7eedf4b6"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-milestone-3",
|
|
||||||
"checksum": "3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-milestone-2",
|
|
||||||
"checksum": "3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.1-milestone-1",
|
|
||||||
"checksum": "3888c76faa032ea8394b8a54e04ce2227ab1f4be64f65d450f8509fe112d38ce"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.0.1",
|
|
||||||
"checksum": "28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.0",
|
|
||||||
"checksum": "28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.0-rc-3",
|
|
||||||
"checksum": "28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6.4",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.0-rc-2",
|
|
||||||
"checksum": "28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "6.0-rc-1",
|
|
||||||
"checksum": "28b330c20a9a73881dfe9702df78d4d78bf72368e8906c70080ab6932462fe9e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6.3",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6.2",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6.1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6-rc-2",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.6-rc-1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5.1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5-rc-4",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5-rc-3",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5-rc-2",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.5-rc-1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.4.1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.4",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.4-rc-1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.3.1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.3",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.3-rc-3",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.3-rc-2",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.3-rc-1",
|
|
||||||
"checksum": "3dc39ad650d40f6c029bd8ff605c6d95865d657dbfdeacdb079db0ddfffedf9f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.2.1",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.2",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.2-rc-1",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1.1",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1-rc-3",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1-rc-2",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1-rc-1",
|
|
||||||
"checksum": "76b12da7f4a7cdd025e5996811a2e49bf5df0fb62d72554ab555c0e434b63aae"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.10.3",
|
|
||||||
"checksum": "660ab018b8e319e9ae779fdb1b7ac47d0321bde953bf0eb4545f14952cfdcaa3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.1-milestone-1",
|
|
||||||
"checksum": "8ff6bee43c55efc0cce9e1147860a76fc970398fbef587e64b6e7a5a7e0291df"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "5.0",
|
|
||||||
"checksum": "f1a597a1f2b23089deec11d5b924d074f9e4ed810f2093be7021ded01c8073ad"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.10.2",
|
|
||||||
"checksum": "ad63ba21fb91e490e0f6fd0ca7d4049241f0f68a454b0b3075c041c4554e611c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.10.1",
|
|
||||||
"checksum": "d8a69ca8efe271d8de080c42a2ea4b08fc9e85c41aa2d163255c70d9da239db0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.10",
|
|
||||||
"checksum": "778e7f46bd67eaea2de5bcbdbb40878c6614656014ba59a72ce8648eaf43a925"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.9",
|
|
||||||
"checksum": "e55e7e47a79e04c26363805b31e2f40b7a9cc89ea12113be7de750a3b2cede85"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.8.1",
|
|
||||||
"checksum": "080e30657661539701b66827b96eb0043191e0a7a73090e8a57bd6735e5af5c5"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.8",
|
|
||||||
"checksum": "4160d5a6d8d6efc6af336582bbbba8194e4d7a742835f7b0fd3964cbd419c994"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.7",
|
|
||||||
"checksum": "7d6fe0a055f133226409de2457fb0e887d1f6b096f36c8d5fd76fb7a9357cd45"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.6",
|
|
||||||
"checksum": "381dff8aa434499aa93bc25572b049c8c586a67faff2c02f375e4f23e17e49de"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.5.1",
|
|
||||||
"checksum": "3bf04e39ed259ff0a1217a875199a11775855d2a29207b98318ac79178249de8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.5",
|
|
||||||
"checksum": "d283a04caee0e97b666b09e50ab394834934bee6225c2e9cd4650afdeac43828"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.4.1",
|
|
||||||
"checksum": "4e318d74d06aa7b998091345c397a3c7c4b291b59da31e6f9c772a596711acac"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.4",
|
|
||||||
"checksum": "88b5b31f390a268ab3773df580d83fd1e388f49c2b685f78a16600577bd72fe2"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.3.1",
|
|
||||||
"checksum": "383f4efa709b52632a520708e8a07353961970941ab3867ab8ac182132ce1c54"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.3",
|
|
||||||
"checksum": "ba496e7e0e03ffa432eaf715bb1466fac2ffc8491a71e7164a5438c48c79d8ea"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.2.1",
|
|
||||||
"checksum": "c536e519e65a4bb787e071c6a90d23bd219c9d409a2123db649d3684acbf3ae7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.2",
|
|
||||||
"checksum": "53aa048fef3c06a8442c6a44df5edd2e8c791ee883e42ded6189c7eed112095d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "4.1",
|
|
||||||
"checksum": "f4d953f31fbf6c38a8c330d19171c8ba6e0d1ff59d4d5c5c2d3ed821c9f3d5a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "3.2.1",
|
|
||||||
"checksum": "020ef0245a07b33ca48b12f59415e7e5083cf701ef02690464a8cc2ab3984608"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "3.2",
|
|
||||||
"checksum": "d2d3abae74e89cc4200f48d4a08a7e5960363c33ee62272ef5ffbb39f4c7f83e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "3.1",
|
|
||||||
"checksum": "0f49043be582d7a39b671f924c66bd9337b92fa88ff5951225acc60560053067"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "3.0",
|
|
||||||
"checksum": "42d7a2f636983aa09d21dfeb6e90d21d7a8dad905351390643ce60cc82c8f8a9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.14.1",
|
|
||||||
"checksum": "8e47da0b2656354d059609cae9d44b196d4f9b14512e688ffee4e0eb7e723ae9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.14",
|
|
||||||
"checksum": "b5ca811c057b3eb4164c78f4155d667c6092ff98ba91a4c90d29e127426f37a7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.13",
|
|
||||||
"checksum": "0c3c576e28b44eddcab6b8b4854f484363dfbcd047657d41654e839835da2c53"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.12",
|
|
||||||
"checksum": "4894520b03c007bf38e983bf933320c483a9790010d997029fa8985dc6128559"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.11",
|
|
||||||
"checksum": "0bc7b16a0a3fa52af674de44d1fea48abc4dee3431f3d4829cd9ea329836e596"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.10",
|
|
||||||
"checksum": "16caeaf66d57a0d1d2087fef6a97efa62de8da69afa5b908f40db35afc4342da"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.9",
|
|
||||||
"checksum": "b92386e36a96da6be89e91f71087d1394a26c0450231ba0b22e28ee1ee8fa14b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.8",
|
|
||||||
"checksum": "198159fcd7d29533c0d37423d66c44729982d5280c9e2c7c5f4b7bc6a9317f6b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.7",
|
|
||||||
"checksum": "d7e1975ccf2dc079d4f0b1010febdad466506d1565c5aa8017c88ebc5e471604"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.6",
|
|
||||||
"checksum": "695089a2b306f55f0bd63140fbcc5ead8c383819018188ce484cd5a055bec6e4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.5",
|
|
||||||
"checksum": "718d7b25ea60b357fc4cb2212ce10b3f03dfd0e6fe5f23f565b15553ec46bb7e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.4",
|
|
||||||
"checksum": "98420079ffe3e24b1013180d9b9bc2e2ee6a9d867ee232004b75a961d9c18e27"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.3",
|
|
||||||
"checksum": "b18a1114ebe81fb7502d40ad9a4f86cef82fff244a865ad45533b4d5e7ff0cc8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.2.1",
|
|
||||||
"checksum": "5f73d431fd1c5dcc2cf11555b8e486c43249c1099f678ccc6088b05be600a2e1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.2",
|
|
||||||
"checksum": "fa9b4294d47cf8db7039cb9b2435de3dd1accb0d3d67926705775a0579dfa397"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.1",
|
|
||||||
"checksum": "5e27c39c2336c25748f279d8b105162d14b1a39eb7839d0b658432282d0ce79f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "2.0",
|
|
||||||
"checksum": "80a33ca14e3bca3116bc8749550397f739f126190c82bb6399fdc8d10f49661f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.12",
|
|
||||||
"checksum": "dea5ceba47b58df0b7f69a65b24357527c1927ccc72b6d4ed90658d39e461b29"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.11",
|
|
||||||
"checksum": "a14b54dd3790f5ce1dc08ebbf4b5bcc05f76c4554b43accb84696c970f29aba0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.10",
|
|
||||||
"checksum": "6a6c15e222a0458aa33985b87f67954f4222410b43b1e26866197d0a77d93cbc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.9",
|
|
||||||
"checksum": "134337ea7c13221f9d1a1c14288a5cf8af9f6060167b903b724b115cf5a0cf73"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.8",
|
|
||||||
"checksum": "13f23a24252ddca0a0fabef212e3c854f5895b081c09d015c91587a5df9bf9f7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.7",
|
|
||||||
"checksum": "7af529cc3331d38b3d8f8344ddd9b2d3744542b55b68318abd8bb1a6f3812a1c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.6",
|
|
||||||
"checksum": "66dbcc9f0bc33789ea0bdb4d49c8ea037047bda5647ef696c47bdca65f785159"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.5",
|
|
||||||
"checksum": "9598ffdf7ee26949d8b861ece267c70c802f21f7fc52596693834792d155195a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.4",
|
|
||||||
"checksum": "c95985b7b5684e133c5d45044fd90faaf6c8f7cd2493d61a11c2b8c5b71ef514"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.3",
|
|
||||||
"checksum": "95513eccca99e1ae1aeadc4f69cabd0e7fb64821d3f26c46a489df844c8a7353"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.2",
|
|
||||||
"checksum": "5c91fa893665f3051eae14578fac2df14e737423387e75ffbeccd35f335a3d8b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.1",
|
|
||||||
"checksum": "22c56a9780daeee00e5bf31621f991b68e73eff6fe8afca628a1fe2c50c6038e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "1.0",
|
|
||||||
"checksum": "87e50531ca7aab675f5bb65755ef78328afd64cf0877e37ad876047a8a014055"
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2021", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
|
||||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
|
||||||
"outDir": "./lib", /* Redirect output structure to the directory. */
|
|
||||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
|
||||||
"strict": true, /* Enable all strict type-checking options. */
|
|
||||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
|
||||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
|
||||||
"resolveJsonModule": true, /* Enable importing JSON files as module; used for importing wrapper checksums JSON */
|
|
||||||
},
|
|
||||||
"exclude": ["node_modules", "**/*.test.ts"]
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user