Initial commit
This commit is contained in:
Коммит
4c80175f7c
|
@ -0,0 +1,9 @@
|
|||
# Microsoft Open Source Code of Conduct
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
|
||||
Resources:
|
||||
|
||||
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
|
||||
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
|
||||
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
|
@ -0,0 +1,103 @@
|
|||
# msvc-code-analysis-action
|
||||
|
||||
This action enables code analysis to run while building a project with the Microsoft Visual C++ Compiler. The analysis
|
||||
will produce SARIF results that can be uploaded to the GitHub Code Scanning Alerts experience.
|
||||
|
||||
## Usage
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
Include a workflow `.yml` file using an [example](#example) below as a template. Run the `msvc-code-analysis-action`
|
||||
before re-building your project using the appropriate operation mode detailed below.
|
||||
|
||||
### Inputs
|
||||
- `mode` (**default:** General) operation mode given different environments and build systems:
|
||||
- **General:** enable Code Analysis for any build system. The MSVC compiler with the desired host and target
|
||||
architecture must be available on the PATH.
|
||||
- **MSBuild:** enable MSBuild Code Analysis experience. This is the preferred method if using MSBuild projects as it
|
||||
can use Code Analysis settings as configured in Visual Studio.
|
||||
- `results` (**default:** ${{ github.workspace }}) root directory containing all SARIF files produced in build.
|
||||
This is commonly the root directory of the project (i.e. MSBuild) or build folder (i.e. CMake).
|
||||
- `ruleset` (**default:** NativeRecommendedRules.ruleset) ruleset file used to determine what checks are run. This can
|
||||
reference a ruleset that ship with Visual Studio or a custom file in the project.
|
||||
- `cleanSarif` (**default:** true) SARIF files will under `results` directory are considered stale and will be deleted.
|
||||
- `args` optional parameters to pass to every instance of the compiler.
|
||||
|
||||
### Examples
|
||||
|
||||
#### CMake
|
||||
|
||||
```yml
|
||||
# Use VCPKG to make MSVC discoverable on the PATH
|
||||
- name: Add MSVC to the PATH
|
||||
uses: lukka/run-vcpkg@v7
|
||||
with:
|
||||
setupOnly: true
|
||||
|
||||
# Configure MSVC to run code analysis during build
|
||||
- name: Initialize MSVC Code Analysis
|
||||
uses: microsoft/msvc-code-analysis-action
|
||||
with:
|
||||
# Path to directory that will contain produced sarif files
|
||||
results: build
|
||||
# Ruleset file that will determine what checks will be run
|
||||
ruleset: NativeRecommendRules.ruleset
|
||||
|
||||
# Rebuild the project using any MSVC compatible build system
|
||||
- name: Build Project
|
||||
run: cmake -G Ninja -B build --clean-first
|
||||
|
||||
# Upload all SARIF files generated in the build directory tree
|
||||
- name: Upload SARIF files
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
sarif_file: build
|
||||
```
|
||||
|
||||
#### MSBuild
|
||||
|
||||
```yml
|
||||
# Make MSBuild discoverable on the PATH
|
||||
- name: Add MSBuild to PATH
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
|
||||
# Configure MSVC to run code analysis during build
|
||||
- name: Initialize MSVC Code Analysis
|
||||
uses: microsoft/msvc-code-analysis-action@v1
|
||||
with:
|
||||
# Root of MSBuild Solution containing all project directories
|
||||
result: ${{ github.workspace }}
|
||||
|
||||
# Rebuild the project using MSBuild
|
||||
- name: Build Project
|
||||
run: msbuild Project.sln /p:Configuration=Release /p:Platform=x64 /t:rebuild
|
||||
|
||||
# Upload all SARIF files generated in the build directory tree
|
||||
- name: Upload SARIF files
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
# Root of MSBuild Solution containing all project directories
|
||||
sarif_file: ${{ github.workspace }}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## Trademarks
|
||||
|
||||
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
|
||||
trademarks or logos is subject to and must follow
|
||||
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
||||
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
||||
Any use of third-party trademarks or logos are subject to those third-party's policies.
|
|
@ -0,0 +1,41 @@
|
|||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
|
||||
|
||||
## 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 [our GitHub organizations](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), 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 (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [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://www.microsoft.com/en-us/msrc/pgp-key-msrc).
|
||||
|
||||
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.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
|
||||
|
||||
## 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).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
|
@ -0,0 +1,25 @@
|
|||
# TODO: The maintainer of this repo has not yet edited this file
|
||||
|
||||
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
|
||||
|
||||
- **No CSS support:** Fill out this template with information about how to file issues and get help.
|
||||
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
|
||||
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
|
||||
|
||||
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
|
||||
|
||||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
||||
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
|
||||
issues before filing new issues to avoid duplicates. For new issues, file your bug or
|
||||
feature request as a new Issue.
|
||||
|
||||
For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
|
||||
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
|
||||
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
|
||||
|
||||
## Microsoft Support Policy
|
||||
|
||||
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
|
|
@ -0,0 +1,22 @@
|
|||
name: 'MSVC Code Analysis Action'
|
||||
description: 'Setup MSVC to produce Code Analysis SARIF files for use in github/codeql-action/upload-sarif@v1'
|
||||
inputs:
|
||||
mode:
|
||||
description: 'Operation mode given different environments and build systems.'
|
||||
default: 'General'
|
||||
results:
|
||||
description: 'root directory containing all SARIF files produced in build.'
|
||||
default: '${{ github.workspace }}'
|
||||
ruleset:
|
||||
description: 'Ruleset file to use during analysis.'
|
||||
default: 'NativeRecommendedRules.ruleset'
|
||||
cleanSarif:
|
||||
description: 'SARIF files will under `results` directory are considered stale and will be deleted.'
|
||||
default: 'True'
|
||||
args:
|
||||
description: 'Optional parameters to pass to every instance of the compiler.'
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'index.js'
|
|
@ -0,0 +1,233 @@
|
|||
const core = require('@actions/core');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
|
||||
const RelativeRulesetPath = '..\\..\\..\\..\\..\\..\\..\\Team Tools\\Static Analysis Tools\\Rule Sets';
|
||||
const DefaultRulesetName = 'NativeRecommendedRules.ruleset';
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
|
||||
// Add Quoted command-line argument for MSVC that handles spaces and trailing backslashes.
|
||||
function addArg(clArgs, arg) {
|
||||
// find number of consecutive trailing backslashes
|
||||
var i = 0;
|
||||
while (i < arg.length && arg[arg.length - 1 - i] == '\\') {
|
||||
i++;
|
||||
}
|
||||
|
||||
// escape all trailing backslashes
|
||||
if (i > 0) {
|
||||
arg += new Array(i + 1).join('\\');
|
||||
}
|
||||
|
||||
clArgs.push('"' + arg + '"');
|
||||
}
|
||||
|
||||
// Find executable relative to the CWD or the system PATH
|
||||
function findExecutableOnPath(executable) {
|
||||
var paths = process.cwd() + ';' + process.env.PATH;
|
||||
for (const pathDir of paths.split(';')) {
|
||||
const executablePath = path.join(pathDir, executable);
|
||||
if (fs.existsSync(executablePath)) {
|
||||
return executablePath;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(executable + ' is not accessible on the PATH');
|
||||
}
|
||||
|
||||
// Ensure results directory for SARIF files exists and delete stale files if needed.
|
||||
function prepareResultsDir() {
|
||||
var outputDir = core.getInput('results');
|
||||
if (outputDir == '') {
|
||||
throw new Error('`results` must exist and contain all intermediate build directories.');
|
||||
}
|
||||
|
||||
// make relative path relative to the repo root
|
||||
if (!path.isAbsolute(outputDir)) {
|
||||
outputDir = path.join(process.env.GITHUB_WORKSPACE, outputDir);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
throw new Error('`results` must exist and contain all intermediate build directories.');
|
||||
}
|
||||
|
||||
var cleanSarif = core.getInput('cleanSarif');
|
||||
switch (cleanSarif.toLowerCase()) {
|
||||
case 'true':
|
||||
{
|
||||
// delete existing Sarif files that are consider stale
|
||||
files = fs.readdirSync(outputDir, { withFileTypes: true });
|
||||
files.forEach(file => {
|
||||
if (file.isFile() && path.extname(file.name).toLowerCase() == '.sarif') {
|
||||
fs.unlinkSync(path.join(outputDir, file.name));
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'false':
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported value for \'cleanSarif\'. Must be either \'True\' or \'False\'');
|
||||
}
|
||||
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
// EspXEngine.dll only exists in host/target bin for MSVC Visual Studio release.
|
||||
function findEspXEngine(clPath) {
|
||||
const clDir = path.dirname(clPath);
|
||||
|
||||
// check if we already have the correct host/target pair
|
||||
var dllPath = path.join(clDir, 'EspXEngine.dll');
|
||||
if (fs.existsSync(dllPath)) {
|
||||
return dllPath;
|
||||
}
|
||||
|
||||
var targetName = '';
|
||||
var hostDir = path.dirname(clDir);
|
||||
switch (path.basename(hostDir)) {
|
||||
case 'HostX86':
|
||||
targetName = 'x86';
|
||||
break;
|
||||
case 'HostX64':
|
||||
targetName = 'x64';
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown MSVC toolset layout');
|
||||
}
|
||||
|
||||
dllPath = path.join(hostDir, targetName, 'EspXEngine.dll');
|
||||
if (fs.existsSync(dllPath)) {
|
||||
return dllPath;
|
||||
}
|
||||
|
||||
throw new Error('Unable to find EspXEngine.dll');
|
||||
}
|
||||
|
||||
// Find official ruleset directory using the known path of MSVC compiler in Visual Studio.
|
||||
function findRulesetDirectory(clPath) {
|
||||
const rulesetDirectory = path.normalize(path.join(path.dirname(clPath), RelativeRulesetPath));
|
||||
return fs.existsSync(rulesetDirectory) ? rulesetDirectory : undefined;
|
||||
}
|
||||
|
||||
function findRuleset(rulesetDirectory) {
|
||||
var rulesetPath = core.getInput('ruleset');
|
||||
if (rulesetPath == '') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (path.isAbsolute(rulesetPath)) {
|
||||
return fs.existsSync(rulesetPath) ? rulesetPath : undefined;
|
||||
}
|
||||
|
||||
// search for a path relative to the project directory
|
||||
const repoRulesetPath = path.join(process.env.GITHUB_WORKSPACE, rulesetPath);
|
||||
if (fs.existsSync(repoRulesetPath)) {
|
||||
return repoRulesetPath;
|
||||
}
|
||||
|
||||
// search official ruleset directory that ships inside of Visual Studio
|
||||
if (rulesetDirectory != undefined) {
|
||||
const officialRulesetPath = path.join(rulesetDirectory, rulesetPath);
|
||||
if (fs.existsSync(officialRulesetPath)) {
|
||||
return officialRulesetPath;
|
||||
}
|
||||
} else {
|
||||
core.warning('Unable to find official rulesets shipped with Visual Studio');
|
||||
}
|
||||
|
||||
throw new Error('Unable to fine ruleset specified: ' + rulesetPath);
|
||||
}
|
||||
|
||||
//
|
||||
// Build 'mode' functions
|
||||
//
|
||||
|
||||
// Configuration if (mode == General).
|
||||
function configureGeneralProject() {
|
||||
const clArgs = ["/analyze:quiet", "/analyze:log:format:sarif"];
|
||||
|
||||
// fine cl.exe on the corresponding EspXEngine.dll
|
||||
const clPath = findExecutableOnPath('cl.exe');
|
||||
const espXEngine = findEspXEngine(clPath);
|
||||
addArg(clArgs, util.format('/analyze:plugin%s', espXEngine));
|
||||
|
||||
// find ruleset directory that ships inside of Visual Studio
|
||||
const rulesetDirectory = findRulesetDirectory(clPath);
|
||||
|
||||
// find ruleset if specified
|
||||
const rulesetPath = findRuleset(rulesetDirectory);
|
||||
if (rulesetPath != undefined) {
|
||||
addArg(clArgs, util.format('/analyze:ruleset%s', rulesetPath));
|
||||
|
||||
// add ruleset directories incase user includes any official rulesets
|
||||
if (rulesetDirectory != undefined) {
|
||||
addArg(clArgs, util.format('/analyze:rulesetdirectory%s', rulesetDirectory));
|
||||
}
|
||||
}
|
||||
|
||||
// add additional command-line arguments to MSVC if specified
|
||||
const additionalArgs = core.getInput('args');
|
||||
if (additionalArgs != '') {
|
||||
clArgs.push(additionalArgs);
|
||||
}
|
||||
|
||||
// add analysis arguments to _CL_ env variable
|
||||
core.exportVariable('_CL_', clArgs.join(' '));
|
||||
|
||||
// enable compatibility mode as GitHub does not support some sarif options
|
||||
core.exportVariable('CAEmitSarifLog', '1');
|
||||
}
|
||||
|
||||
// Configuration if (mode == MSBuild).
|
||||
function configureMSBuildProject() {
|
||||
|
||||
// ensure ruleset is empty or not modified from default
|
||||
var rulesetPath = core.getInput('ruleset');
|
||||
if (rulesetPath != '' || rulesetPath != DefaultRulesetName) {
|
||||
throw new Error(
|
||||
'Custom ruleset not support in MSBuild mode. Configure ruleset in project or use /p:CodeAnalysisRuleset=XXX');
|
||||
}
|
||||
|
||||
// add additional command-line arguments to MSVC if specified
|
||||
const additionalArgs = core.getInput('args');
|
||||
if (additionalArgs != '') {
|
||||
core.exportVariable('_CL_', additionalArgs);
|
||||
}
|
||||
|
||||
// force Code Analysis to run
|
||||
core.exportVariable('RunCodeAnalysis', 'true');
|
||||
|
||||
// extra redundancy in case the user has RunCodeAnalysis manually configured in project
|
||||
core.exportVariable('RunCodeAnalysisOnce', 'true');
|
||||
|
||||
// force generation of Sarif output that us only used in the IDE experience
|
||||
core.exportVariable('VCCodeAnalysisUX', 'true');
|
||||
}
|
||||
|
||||
//
|
||||
// Main
|
||||
//
|
||||
|
||||
try {
|
||||
const mode = core.getInput('mode');
|
||||
switch (mode.toLowerCase()) {
|
||||
case 'general':
|
||||
configureGeneralProject()
|
||||
break;
|
||||
case 'msbuild':
|
||||
configureMSBuildProject()
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown operation mode: ' + mode);
|
||||
}
|
||||
|
||||
prepareResultsDir();
|
||||
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
Загрузка…
Ссылка в новой задаче