diff --git a/.github/workflows/on-push-verification.yml b/.github/workflows/on-push-verification.yml index 4cd4c83..28c142b 100644 --- a/.github/workflows/on-push-verification.yml +++ b/.github/workflows/on-push-verification.yml @@ -1,14 +1,14 @@ # sample-workflow-windows-latest # docs are in the repo -name: OSSAR on-push-verification windows-latest +name: .NET Analyzers on-push-verification windows-latest on: push jobs: sample: - name: Open Source Static Analysis Runner + name: .NET Analyzers runner - # OSSAR runs on windows-latest. + # .NET Analyzers runs on windows-latest. # ubuntu-latest and macos-latest supporting coming soon runs-on: windows-latest @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v2 # Ensure a compatible version of dotnet is installed. - # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. + # The [Microsoft Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. # Remote agents already have a compatible version of dotnet installed and this step may be skipped. # For local agents, ensure dotnet version 3.1.201 or later is installed by including this action: @@ -26,13 +26,9 @@ jobs: # with: # dotnet-version: '3.1.x' - # Run open source static analysis tools - - name: Run OSSAR + # Run .NET Analyzers + - name: Run .NET Analyzers uses: ./ - id: ossar - - # Upload results to the Security tab - - name: Upload results to Security tab - uses: github/codeql-action/upload-sarif@v1 + id: dotnet-analyzers with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} + projects: sample\ClassLibrary1.sln diff --git a/.github/workflows/sample-workflow-ubuntu-latest.yml b/.github/workflows/sample-workflow-ubuntu-latest.yml index d4dd5ca..a64d4b9 100644 --- a/.github/workflows/sample-workflow-ubuntu-latest.yml +++ b/.github/workflows/sample-workflow-ubuntu-latest.yml @@ -1,17 +1,17 @@ # sample-workflow-ubuntu-latest # docs are in the repo -name: OSSAR ubuntu-latest +name: .NET Analyzers ubuntu-latest on: push: branches: - - master + - main jobs: sample: - name: Open Source Static Analysis Runner + name: .NET Analyzers runner - # OSSAR runs on windows-latest. + # .NET Analyzers runs on windows-latest. # ubuntu-latest and macos-latest supporting coming soon runs-on: ubuntu-latest @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v2 # Ensure a compatible version of dotnet is installed. - # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. + # The [Microsoft Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. # GitHub hosted runners already have a compatible version of dotnet installed and this step may be skipped. # For self-hosted runners, ensure dotnet version 3.1.201 or later is installed by including this action: @@ -30,12 +30,6 @@ jobs: # dotnet-version: '3.1.x' # Run open source static analysis tools - - name: Run OSSAR - uses: github/ossar-action@v1 - id: ossar - - # Upload results to the Security tab - - name: Upload results to Security tab - uses: github/codeql-action/upload-sarif@v1 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} + - name: Run .NET Analyzers + uses: github/dotnet-analyzers-action@v1 + id: dotnet-analyzers diff --git a/.github/workflows/sample-workflow-windows-latest.yml b/.github/workflows/sample-workflow-windows-latest.yml index 8034f2e..c59ee16 100644 --- a/.github/workflows/sample-workflow-windows-latest.yml +++ b/.github/workflows/sample-workflow-windows-latest.yml @@ -1,17 +1,17 @@ # sample-workflow-windows-latest # docs are in the repo -name: OSSAR windows-latest +name: .NET Analyzers windows-latest on: push: branches: - - master + - main jobs: sample: - name: Open Source Static Analysis Runner + name: .NET Analyzers runner - # OSSAR runs on windows-latest. + # .NET Analyzers runs on windows-latest. # ubuntu-latest and macos-latest supporting coming soon runs-on: windows-latest @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@v2 # Ensure a compatible version of dotnet is installed. - # The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. + # The [Microsoft Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. # A version greater than or equal to v3.1.201 of dotnet must be installed on the agent in order to run this action. # GitHub hosted runners already have a compatible version of dotnet installed and this step may be skipped. # For self-hosted runners, ensure dotnet version 3.1.201 or later is installed by including this action: @@ -29,13 +29,7 @@ jobs: # with: # dotnet-version: '3.1.x' - # Run open source static analysis tools - - name: Run OSSAR - uses: github/ossar-action@v1 - id: ossar - - # Upload results to the Security tab - - name: Upload results to Security tab - uses: github/codeql-action/upload-sarif@v1 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} + # Run .NET Analyzers + - name: Run .NET Analyzers + uses: github/dotnet-analyzers-action@v1 + id: dotnet-analyzers diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d42395..78773ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ ## Contributing -[fork]: https://github.com/github/ossar-action/fork -[pr]: https://github.com/github/ossar-action/compare +[fork]: https://github.com/github/dotnet-analyzers-action/fork +[pr]: https://github.com/github/dotnet-analyzers-action/compare [code-of-conduct]: CODE_OF_CONDUCT.md Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. diff --git a/README.md b/README.md index af692f4..a94f1dd 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,20 @@ -# github/ossar-action +# github/dotnet-analyzers-action -![OSSAR windows-latest](https://github.com/github/ossar-action/workflows/OSSAR%20windows-latest/badge.svg) -![OSSAR ubuntu-latest](https://github.com/github/ossar-action/workflows/OSSAR%20ubuntu-latest/badge.svg) +![.NET Analyzers windows-latest](https://github.com/github/dotnet-analyzers-action/workflows/.NET%20Analyzers%20windows-latest/badge.svg) +![.NET Analyzers ubuntu-latest](https://github.com/github/dotnet-analyzers-action/workflows/.NET%20Analyzers%20ubuntu-latest/badge.svg) -Run open source security static analysis tools without the added complexity with OSSAR (Open Source Static Analysis Runner). +Run [.NET code quality and code style analyzers](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/overview) that ship with the .NET SDK. # Limitations -The OSSAR action is currently in beta and runs on the `windows-latest` queue, as well as Windows self hosted agents. `ubuntu-latest` support coming soon. +The .NET Analyzers action is currently in beta and runs on the `windows-latest` queue, as well as Windows self hosted agents. `ubuntu-latest` support coming soon. # Overview -This action runs the [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) for security analysis by: +This action runs the [Code Analysis CLI](https://aka.ms/mscadocs) for .NET code quality and code style analysis by: -* Installing the Microsoft Security Code Analysis CLI -* Installing the latest policy or referencing the local `policy/github.gdnpolicy` file -* Installing the latest open source tools -* Automatic or user-provided configuration of static analysis tools -* Execution of a full suite of static analysis tools +* Installing the Code Analysis CLI +* Execution of [.NET code quality and code style analyzers](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/overview) that ship with the .NET SDK * Normalized processing of results into the SARIF format * Exports a single SARIF file which can be uploaded via the `github/codeql-action/upload-sarif` action @@ -39,21 +36,17 @@ See [action.yml](action.yml) ## Basic -Run OSSAR with the default policy and recommended tools. +Run [.NET code quality and code style analyzers](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/overview) that ship with the .NET SDK. ```yaml steps: - uses: actions/checkout@v2 -- name: Run OSSAR - uses: github/ossar-action@v1 - id: ossar -- name: Upload results to Security tab - uses: github/codeql-action/upload-sarif@v1 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} +- name: Run .NET code quality and code style analyzers + uses: github/dotnet-analyzers-action@v1 + id: dotnet-analyzers ``` -**Note:** The [Microsoft Security Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. A version greater than or equal to v3.1.201 of dotnet must be installed on the runner in order to run this action. GitHub hosted runners already have a compatible version of dotnet installed. To ensure a compatible version of dotnet is installed on a self-hosted runner, please configure the [actions/setup-dotnet](https://github.com/actions/setup-dotnet) action. +**Note:** The [Microsoft Code Analysis CLI](https://aka.ms/mscadocs) is built with dotnet v3.1.201. A version greater than or equal to v3.1.201 of dotnet must be installed on the runner in order to run this action. GitHub hosted runners already have a compatible version of dotnet installed. To ensure a compatible version of dotnet is installed on a self-hosted runner, please configure the [actions/setup-dotnet](https://github.com/actions/setup-dotnet) action. ``` - uses: actions/setup-dotnet@v1 @@ -61,24 +54,13 @@ steps: dotnet-version: '3.1.x' ``` -## Upload Results to the Security tab - -To upload results to the Security tab of your repo, run the `github/codeql-action/upload-sarif` action immediately after running OSSAR. OSSAR sets the action output variable `sarifFile` to the path of a single SARIF file that can be uploaded to this API. - -```yaml -- name: Upload results to Security tab - uses: github/codeql-action/upload-sarif@v1 - with: - sarif_file: ${{ steps.ossar.outputs.sarifFile }} -``` - # More Information -Please see the [wiki tab](https://github.com/github/ossar-action/wiki) for more information and the [Frequently Asked Questions (FAQ)](https://github.com/github/ossar-action/wiki/FAQ) page. +Please see the [wiki tab](https://github.com/github/dotnet-analyzers-action/wiki) for more information and the [Frequently Asked Questions (FAQ)](https://github.com/github/dotnet-analyzers-action/wiki/FAQ) page. # Report Issues -Please [file a GitHub issue](https://github.com/github/ossar-action/issues/new) in this repo. To help us investigate the issue, please include a description of the problem, a link to your workflow run (if public), and/or logs from the OSSAR's action output. +Please [file a GitHub issue](https://github.com/github/dotnet-analyzers-action/issues/new) in this repo. To help us investigate the issue, please include a description of the problem, a link to your workflow run (if public), and/or logs from the .NET Analyzers's action output. # License diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 2e8bed0..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,39 +0,0 @@ - - -If you discover a security issue in this repo, please submit it through the [GitHub Security Bug Bounty](https://hackerone.com/github) - -Thanks for helping make GitHub Actions safe for everyone. - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [many more](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [definition](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center at [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://technet.microsoft.com/en-us/security/dn606155). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - \ No newline at end of file diff --git a/action.yml b/action.yml index a91353d..a451aef 100644 --- a/action.yml +++ b/action.yml @@ -1,17 +1,61 @@ -name: 'ossar-action' -description: 'Run open source security static analysis tools without the added complexity with OSSAR (Open Source Static Analysis Runner)' +name: 'dotnet-analyzers-action' +description: 'Run .NET code quality and code style analyzers shipping with .NET SDK' author: 'GitHub' -branding: - icon: 'shield' - color: 'black' inputs: - config: - description: A file path to a .gdnconfig file. - policy: - description: The name of the well known policy to use. If empty, defaults to the policy/github.gdnpolicy file in the action repo. + projects: + description: 'Semi-colon separated list of projects or solutions to analyze' + required: true + analysis-level: # AnalysisLevel: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Default analysis level for all rules' + required: false + default: 'latest-minimum' + style: # AnalysisLevelStyle: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for code style rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/' + required: false + default: 'latest-minimum' + design: # AnalysisLevelDesign: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for sesign rules: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/design-warnings' + required: false + default: 'latest-minimum' + documentation: # AnalysisLevelDocumentation: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for documentation rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/documentation-warnings' + required: false + default: 'latest-minimum' + globalization: # AnalysisLevelGlobalization: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for globalization rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/globalization-warnings' + required: false + default: 'latest-minimum' + interoperability: # AnalysisLevelInteroperability: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for portability and interoperability rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/interoperability-warnings' + required: false + default: 'latest-minimum' + maintainability: # AnalysisLevelMaintainability: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for maintainability rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/maintainability-warnings' + required: false + default: 'latest-minimum' + naming: # AnalysisLevelNaming: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for naming rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/naming-warnings' + required: false + default: 'latest-minimum' + performance: # AnalysisLevelPerformance: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for performance rules: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/performance-warnings' + required: false + default: 'latest-minimum' + reliability: # AnalysisLevelReliability: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for reliability rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/reliability-warnings' + required: false + default: 'latest-minimum' + security: # AnalysisLevelSecurity: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for security rules https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/security-warnings' + required: false + default: 'latest-minimum' + usage: # AnalysisLevelPerformance: https://docs.microsoft.com/dotnet/core/project-sdk/msbuild-props#analysislevel + description: 'Overridden analysis level for usage rules: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/usage-warnings' + required: false + default: 'latest-minimum' outputs: sarifFile: - description: A file path to a SARIF results file. + description: A file path to a SARIF file with analysis results. runs: using: 'node12' main: 'lib/action.js' \ No newline at end of file diff --git a/build.proj b/build.proj index b37725a..43aa763 100644 --- a/build.proj +++ b/build.proj @@ -9,7 +9,7 @@ false - 3.8 + 4.1 tsconfig.json $(MSBuildProjectDirectory)/$(TypeScriptConfigFileName) false diff --git a/lib/action.js b/lib/action.js index a380203..416d5c4 100644 --- a/lib/action.js +++ b/lib/action.js @@ -1,35 +1,144 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const core = __importStar(require("@actions/core")); const msca_toolkit_1 = require("./msca-toolkit/msca-toolkit"); const path = __importStar(require("path")); +const fs = __importStar(require("fs")); let action = new msca_toolkit_1.MscaAction(); -let args = []; -let config = core.getInput('config'); -if (!action.isNullOrWhiteSpace(config)) { - args.push('-c'); - args.push(config); -} -let policy = core.getInput('policy'); -if (action.isNullOrWhiteSpace(policy)) { - // Use the local policy file - const actionDirectory = path.resolve(__dirname); - core.debug(`actionDirectory = ${actionDirectory}`); - const policyFilePath = path.resolve(path.join(actionDirectory, '../', 'policy', 'github.gdnpolicy')); - core.debug(`policyFilePath = ${policyFilePath}`); - args.push('--policy-file-path'); - args.push(policyFilePath); -} -else { - // Use the defined policy - args.push('-p'); - args.push(policy); +let analysisArgs = ""; +let analysisLevel = core.getInput('analysis-level'); +if (!action.isNullOrWhiteSpace(analysisLevel)) { + analysisArgs += `/p:AnalysisLevel=${analysisLevel} `; +} +let style = core.getInput('style'); +if (!action.isNullOrWhiteSpace(style)) { + analysisArgs += `/p:AnalysisLevelStyle=${style} `; +} +let design = core.getInput('design'); +if (!action.isNullOrWhiteSpace(design)) { + analysisArgs += `/p:AnalysisLevelDesign=${design} `; +} +let documentation = core.getInput('documentation'); +if (!action.isNullOrWhiteSpace(documentation)) { + analysisArgs += `/p:AnalysisLevelDocumentation=${documentation} `; +} +let globalization = core.getInput('globalization'); +if (!action.isNullOrWhiteSpace(globalization)) { + analysisArgs += `/p:AnalysisLevelGlobalization=${globalization} `; +} +let interoperability = core.getInput('interoperability'); +if (!action.isNullOrWhiteSpace(interoperability)) { + analysisArgs += `/p:AnalysisLevelInteroperability=${interoperability} `; +} +let maintainability = core.getInput('maintainability'); +if (!action.isNullOrWhiteSpace(maintainability)) { + analysisArgs += `/p:AnalysisLevelMaintainability=${maintainability} `; +} +let naming = core.getInput('naming'); +if (!action.isNullOrWhiteSpace(naming)) { + analysisArgs += `/p:AnalysisLevelNaming=${naming} `; +} +let performance = core.getInput('performance'); +if (!action.isNullOrWhiteSpace(performance)) { + analysisArgs += `/p:AnalysisLevelPerformance=${performance} `; } +let reliability = core.getInput('reliability'); +if (!action.isNullOrWhiteSpace(reliability)) { + analysisArgs += `/p:AnalysisLevelReliability=${reliability} `; +} +let security = core.getInput('security'); +if (!action.isNullOrWhiteSpace(security)) { + analysisArgs += `/p:AnalysisLevelSecurity=${security} `; +} +let usage = core.getInput('usage'); +if (!action.isNullOrWhiteSpace(usage)) { + analysisArgs += `/p:AnalysisLevelUsage=${usage} `; +} +let projects = core.getInput('projects'); +if (action.isNullOrWhiteSpace(projects)) { + core.setFailed("'projects' must be non-empty"); +} +var buildCommandLines = ""; +var first = true; +projects.split(";").forEach(function (project) { + if (!first) { + buildCommandLines += " ; "; + first = false; + } + if (!path.isAbsolute(project)) { + project = `$(Folders.SourceRepo)\\${project}`; + } + buildCommandLines += `msbuild.exe ${analysisArgs}${project}`; +}); +var configContent = { + "fileVersion": "1.7.0.3", + "tools": [ + { + "fileVersion": "1.7.0.3", + "tool": { + "name": "RoslynAnalyzers", + "version": "1.7.0.3" + }, + "arguments": { + "CopyLogsOnly": false, + "SourcesDirectory": "$(Folders.SourceRepo)", + "MSBuildVersion": "16.0", + "CodeAnalysisAssemblyVersion": "3.8.0", + "SetupCommandlines": "\\\"$(VisualStudioInstallDirectory)\\Common7\\Tools\\VsMSBuildCmd.bat\\\"", + "BuildArchitecture": "amd64", + "BuildCommandlines": buildCommandLines, + "NetAnalyzersRootDirectory": "$(Packages.Microsoft.CodeAnalysis.NetAnalyzers)", + "CSharpCodeStyleAnalyzersRootDirectory": "$(Packages.Microsoft.CodeAnalysis.CSharp.CodeStyle)", + "FxCopAnalyzersRootDirectory": "", + "RulesetPath": "", + "SdlRulesetVersion": "", + "LoggerLevel": "Standard" + }, + "outputExtension": "sarif", + "successfulExitCodes": [ + 0 + ] + } + ] +}; +const actionDirectory = path.resolve(__dirname); +core.debug(`actionDirectory = ${actionDirectory}`); +let data = JSON.stringify(configContent); +let gdnConfigFilePath = path.join(actionDirectory, '../', 'roslynanalyzers.gdnconfig'); +core.debug(`gdnConfigFilePath = ${gdnConfigFilePath}`); +try { + fs.writeFileSync(gdnConfigFilePath, data); + data = fs.readFileSync(gdnConfigFilePath, "utf8"); + core.info(data); +} +catch (err) { + throw Error(err); +} +let args = []; +args.push('-c'); +args.push(gdnConfigFilePath); +// Use the local policy file +const policyFilePath = path.resolve(path.join(actionDirectory, '../', 'policy', 'github.gdnpolicy')); +core.debug(`policyFilePath = ${policyFilePath}`); +args.push('--policy-file-path'); +args.push(policyFilePath); action.run(args); diff --git a/lib/msca-toolkit/msca-installer.js b/lib/msca-toolkit/msca-installer.js index cb17b34..c3a53fe 100644 --- a/lib/msca-toolkit/msca-installer.js +++ b/lib/msca-toolkit/msca-installer.js @@ -1,4 +1,23 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -8,14 +27,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; Object.defineProperty(exports, "__esModule", { value: true }); +exports.MscaInstaller = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const process = __importStar(require("process")); diff --git a/lib/msca-toolkit/msca-toolkit.js b/lib/msca-toolkit/msca-toolkit.js index 3122f92..e3137b8 100644 --- a/lib/msca-toolkit/msca-toolkit.js +++ b/lib/msca-toolkit/msca-toolkit.js @@ -1,4 +1,23 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -8,14 +27,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result["default"] = mod; - return result; -}; Object.defineProperty(exports, "__esModule", { value: true }); +exports.MscaAction = void 0; const path = __importStar(require("path")); const process = __importStar(require("process")); const core = __importStar(require("@actions/core")); diff --git a/package-lock.json b/package-lock.json index d5f6ac8..5bc2712 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "ossar-action", + "name": "dotnet-analyzers-action", "version": "1.1.0", "lockfileVersion": 1, "requires": true, diff --git a/package.json b/package.json index d6b70c0..c01bf07 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "ossar-action", + "name": "dotnet-analyzers-action", "version": "1.1.0", - "description": "Node dependencies for the OSSAR Action.", + "description": "Node dependencies for the .NET Analyzers Action.", "scripts": { "test": "mocha" }, diff --git a/sample/ClassLibrary1.sln b/sample/ClassLibrary1.sln new file mode 100644 index 0000000..52ed0ef --- /dev/null +++ b/sample/ClassLibrary1.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30911.218 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{D93DCE72-417F-4F71-8BC5-03CDB1932B9D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D93DCE72-417F-4F71-8BC5-03CDB1932B9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D93DCE72-417F-4F71-8BC5-03CDB1932B9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D93DCE72-417F-4F71-8BC5-03CDB1932B9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D93DCE72-417F-4F71-8BC5-03CDB1932B9D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {F67E648A-4693-4494-8C38-B2735AC8DADE} + EndGlobalSection +EndGlobal diff --git a/sample/ClassLibrary1/Class1.cs b/sample/ClassLibrary1/Class1.cs new file mode 100644 index 0000000..f490603 --- /dev/null +++ b/sample/ClassLibrary1/Class1.cs @@ -0,0 +1,22 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace ClassLibrary1 +{ + public class Class1 + { + public void M() + { + Console.WriteLine("Hello World!"); + + Console.WriteLine("Console App"); + MD5 md5 = MD5.Create(); + + string contents = "Super secure data."; + byte[] contentBytes = UTF8Encoding.UTF8.GetBytes(contents); + + byte[] hash = md5.ComputeHash(contentBytes); + } + } +} \ No newline at end of file diff --git a/sample/ClassLibrary1/ClassLibrary1.csproj b/sample/ClassLibrary1/ClassLibrary1.csproj new file mode 100644 index 0000000..cb63190 --- /dev/null +++ b/sample/ClassLibrary1/ClassLibrary1.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp3.1 + + + diff --git a/sample/insecure.js b/sample/insecure.js deleted file mode 100644 index 2172dfe..0000000 --- a/sample/insecure.js +++ /dev/null @@ -1,2 +0,0 @@ -let injection = "Hello, security vulnerabilities!"; -eval(`console.log(\"${injection}\");`); \ No newline at end of file diff --git a/sample/insecure.py b/sample/insecure.py deleted file mode 100644 index d43c0b3..0000000 --- a/sample/insecure.py +++ /dev/null @@ -1,24 +0,0 @@ -import hashlib -print("I am very insecure. Bandit thinks so too.") -#B110 -xs=[1,2,3,4,5,6,7,8] -try: - print(xs[7]) - print(xs[8]) -except: pass - -ys=[1, 2, None, None] -for y in ys: - try: - print(str(y+3)) #TypeErrors ahead - except: continue #not how to handle them - -#some imports -import telnetlib -import ftplib - -#B303 and B324 -s = b"I am a string" -print("MD5: " +hashlib.md5(s).hexdigest()) -print("SHA1: " +hashlib.sha1(s).hexdigest()) -print("SHA256: " +hashlib.sha256(s).hexdigest()) diff --git a/src/action.ts b/src/action.ts index 3952203..8fe1a4c 100644 --- a/src/action.ts +++ b/src/action.ts @@ -1,32 +1,156 @@ import * as core from '@actions/core'; import { MscaAction } from './msca-toolkit/msca-toolkit'; import * as path from 'path'; +import * as fs from 'fs'; +import * as os from 'os'; let action = new MscaAction(); -let args: string[] = []; +let analysisArgs = "" + +let analysisLevel = core.getInput('analysis-level'); +if (!action.isNullOrWhiteSpace(analysisLevel)) { + analysisArgs += `/p:AnalysisLevel=${analysisLevel} `; +} + +let style = core.getInput('style'); +if (!action.isNullOrWhiteSpace(style)) { + analysisArgs += `/p:AnalysisLevelStyle=${style} `; +} + +let design = core.getInput('design'); +if (!action.isNullOrWhiteSpace(design)) { + analysisArgs += `/p:AnalysisLevelDesign=${design} `; +} + +let documentation = core.getInput('documentation'); +if (!action.isNullOrWhiteSpace(documentation)) { + analysisArgs += `/p:AnalysisLevelDocumentation=${documentation} `; +} + +let globalization = core.getInput('globalization'); +if (!action.isNullOrWhiteSpace(globalization)) { + analysisArgs += `/p:AnalysisLevelGlobalization=${globalization} `; +} + +let interoperability = core.getInput('interoperability'); +if (!action.isNullOrWhiteSpace(interoperability)) { + analysisArgs += `/p:AnalysisLevelInteroperability=${interoperability} `; +} + +let maintainability = core.getInput('maintainability'); +if (!action.isNullOrWhiteSpace(maintainability)) { + analysisArgs += `/p:AnalysisLevelMaintainability=${maintainability} `; +} + +let naming = core.getInput('naming'); +if (!action.isNullOrWhiteSpace(naming)) { + analysisArgs += `/p:AnalysisLevelNaming=${naming} `; +} + +let performance = core.getInput('performance'); +if (!action.isNullOrWhiteSpace(performance)) { + analysisArgs += `/p:AnalysisLevelPerformance=${performance} `; +} + +let reliability = core.getInput('reliability'); +if (!action.isNullOrWhiteSpace(reliability)) { + analysisArgs += `/p:AnalysisLevelReliability=${reliability} `; +} + +let security = core.getInput('security'); +if (!action.isNullOrWhiteSpace(security)) { + analysisArgs += `/p:AnalysisLevelSecurity=${security} `; +} -let config = core.getInput('config'); -if (!action.isNullOrWhiteSpace(config)) { - args.push('-c'); - args.push(config); +let usage = core.getInput('usage'); +if (!action.isNullOrWhiteSpace(usage)) { + analysisArgs += `/p:AnalysisLevelUsage=${usage} `; } -let policy = core.getInput('policy'); -if (action.isNullOrWhiteSpace(policy)) { - // Use the local policy file - const actionDirectory = path.resolve(__dirname); - core.debug(`actionDirectory = ${actionDirectory}`); +let projects = core.getInput('projects'); +if (action.isNullOrWhiteSpace(projects)) { + core.setFailed("'projects' must be non-empty"); +} + +var buildCommandLines:string = ""; +var first = true; +projects.split(";").forEach(function (project) { + if (!first) + { + buildCommandLines += " ; "; + first = false; + } + + if (!path.isAbsolute(project)) + { + project = `$(Folders.SourceRepo)\\${project}`; + + } - const policyFilePath = path.resolve(path.join(actionDirectory, '../', 'policy', 'github.gdnpolicy')); - core.debug(`policyFilePath = ${policyFilePath}`); + buildCommandLines +=`msbuild.exe ${analysisArgs}${project}`; +}); - args.push('--policy-file-path'); - args.push(policyFilePath); -} else { - // Use the defined policy - args.push('-p'); - args.push(policy); +var configContent = { + "fileVersion": "1.7.0.3", + "tools": [ + { + "fileVersion": "1.7.0.3", + "tool": { + "name": "RoslynAnalyzers", + "version": "1.7.0.3" + }, + "arguments": { + "CopyLogsOnly": false, + "SourcesDirectory": "$(Folders.SourceRepo)", + "MSBuildVersion": "16.0", + "CodeAnalysisAssemblyVersion": "3.8.0", + "SetupCommandlines": "\\\"$(VisualStudioInstallDirectory)\\Common7\\Tools\\VsMSBuildCmd.bat\\\"", + "BuildArchitecture": "amd64", + "BuildCommandlines": buildCommandLines, + "NetAnalyzersRootDirectory": "$(Packages.Microsoft.CodeAnalysis.NetAnalyzers)", + "CSharpCodeStyleAnalyzersRootDirectory": "$(Packages.Microsoft.CodeAnalysis.CSharp.CodeStyle)", + "FxCopAnalyzersRootDirectory": "", + "RulesetPath": "", + "SdlRulesetVersion": "", + "LoggerLevel": "Standard" + }, + "outputExtension": "sarif", + "successfulExitCodes": [ + 0 + ] + } + ] +}; + +const actionDirectory = path.resolve(__dirname); +core.debug(`actionDirectory = ${actionDirectory}`); + +let data = JSON.stringify(configContent); + +let gdnConfigFilePath = path.join(actionDirectory, '../', 'roslynanalyzers.gdnconfig'); +core.debug(`gdnConfigFilePath = ${gdnConfigFilePath}`); + +try +{ + fs.writeFileSync(gdnConfigFilePath, data); + data = fs.readFileSync(gdnConfigFilePath, "utf8"); + core.info(data); +} +catch(err) +{ + throw Error(err); } -action.run(args); \ No newline at end of file +let args: string[] = []; +args.push('-c'); +args.push(gdnConfigFilePath); + +// Use the local policy file +const policyFilePath = path.resolve(path.join(actionDirectory, '../', 'policy', 'github.gdnpolicy')); +core.debug(`policyFilePath = ${policyFilePath}`); + +args.push('--policy-file-path'); +args.push(policyFilePath); + +action.run(args);