From 3975af038d1ff5cc3fc5855bae9ea856154430b7 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:14:17 -0500 Subject: [PATCH 01/12] adding new option for default codescanning config --- .../CodeQL/CodeQLInstallation.cs | 18 ++++++++++++++++-- src/CodeQLToolkit.Shared/Utils/QLTConfig.cs | 4 ++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs b/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs index 92cae6f..8cb00c2 100644 --- a/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs +++ b/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs @@ -16,6 +16,9 @@ public class CodeQLInstallation { public string CLIVersion { get; set; } public string StandardLibraryVersion { get; set; } + + public string CodeQLConfiguration { get; set; } + public string CLIBundle { get; set; } public string StandardLibraryIdent { get; set; } public bool EnableCustomCodeQLBundles { get; set; } @@ -45,7 +48,8 @@ public static CodeQLInstallation LoadFromConfig(QLTConfig c) StandardLibraryIdent = config.CodeQLStandardLibraryIdent, StandardLibraryVersion = config.CodeQLStandardLibrary, CustomizationPacks = config.CustomizationPacks, - Base = config.Base + Base = config.Base, + CodeQLConfiguration = config.CodeQLConfiguration }; @@ -292,7 +296,17 @@ private void CustomBundleInstall() if (QuickBundle) { Log.G().LogInformation($"Note: Quick Bundles enabled and pre-compilation will be disabled..."); - bundleArgs = $"--log DEBUG -nc -b {customBundleSource} -o {CustomBundleOutputDirectory} -w {workingDirectory} {packs}"; + bundleArgs = $"-nc {bundleArgs}"; + } + + if(CodeQLConfiguration!=null && CodeQLConfiguration.Length > 0) + { + Log.G().LogInformation($"Note: Attempting to include default code scanning configuration ..."); + + if (File.Exists(Path.Combine(Base, CodeQLConfiguration))) + { + bundleArgs = $"-c \"{Path.Combine(Base, CodeQLConfiguration)}\" {bundleArgs}"; + } } Log.G().LogInformation($"Executing Bundle Tool with Working Directory: `{workingDirectory}`"); diff --git a/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs b/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs index cb0b5dd..13f4af5 100644 --- a/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs +++ b/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs @@ -19,6 +19,8 @@ public class QLTConfig public string CodeQLStandardLibrary { get; set; } public string CodeQLCLIBundle { get; set; } + public string CodeQLConfiguration { get; set; } + public QLTCustomizationPack[] CustomizationPacks { get; set; } public string CodeQLStandardLibraryIdent { @@ -31,6 +33,8 @@ public string CodeQLStandardLibraryIdent { } } + [JsonIgnore] + public string CodeQLConfigurationPath { get { return Path.Combine(Base, CodeQLConfiguration); } } [JsonIgnore] public string Base { get; set; } From b575893f7d0ab722ea3c06ce5e3d35952c46e073 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:19:02 -0500 Subject: [PATCH 02/12] update version --- src/CodeQLToolkit.Core/ver.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CodeQLToolkit.Core/ver.txt b/src/CodeQLToolkit.Core/ver.txt index 927734f..95dfee2 100644 --- a/src/CodeQLToolkit.Core/ver.txt +++ b/src/CodeQLToolkit.Core/ver.txt @@ -1 +1 @@ -0.0.17 \ No newline at end of file +0.0.23 \ No newline at end of file From 862895c3edbf6ecfed62caf27cd251cb87f1dae8 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:42:16 -0500 Subject: [PATCH 03/12] test workflow for bundle integration test --- .../run-bundle-integration-tests-cpp.yml | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 .github/workflows/run-bundle-integration-tests-cpp.yml diff --git a/.github/workflows/run-bundle-integration-tests-cpp.yml b/.github/workflows/run-bundle-integration-tests-cpp.yml new file mode 100644 index 0000000..b19ba40 --- /dev/null +++ b/.github/workflows/run-bundle-integration-tests-cpp.yml @@ -0,0 +1,111 @@ +name: ⚙️ Integration Test Bundle (CPP) + +on: + push: + branches: + - '**' + pull_request: + branches: + - '**' + workflow_dispatch: + +jobs: + integration-test: + name: Run Bundle Integration Test + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install QLT + id: install-qlt + uses: ./.github/actions/install-qlt-local + with: + qlt-version: 'latest' + add-to-path: true + + - name: Validate QLT Installation + shell: bash + run: | + echo -e "Checking QLT Version:" + echo "QLT Home: ${{ steps.install-qlt.outputs.qlt-home }}" + qlt version + + - name: Create Bundle (compiled) + shell: bash + run: | + if ! qlt codeql run install --custom-bundle ; then + echo "Failed to generate bundle." + exit 1 + fi + + # ensure bundle runs + + if ! qlt query run install-packs --use-bundle ; then + echo "Failed to install query packs with tool." + exit 1 + fi + + - name: Validate Bundle Existence + shell: bash + run: | + echo "Checking Bundle Existence" + ls -l ${{ env.QLT_CODEQL_HOME }}/../out/ + + - name: Upload Bundle Used + uses: actions/upload-artifact@v2 + with: + name: codeql-bundle.tar.gz + path: | + ${{ env.QLT_CODEQL_BUNDLE_PATH }} + if-no-files-found: error + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + tools: ${{ env.QLT_CODEQL_BUNDLE_PATH }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + with: + working-directory: integration-tests/${{ matrix.language }}/src/ # Path containing the example application + + - name: Perform CodeQL Analysis + id: analysis + uses: github/codeql-action/analyze@v2 + + - name: Validate SARIF Location + shell: bash + run: | + # validate we have the actual sarif results + echo "Checking SARIF file location at: ${{ steps.analysis.outputs.sarif-output }}" + ls -l ${{ steps.analysis.outputs.sarif-output }} + + - name: Upload SARIF Results + uses: actions/upload-artifact@v2 + with: + name: actual.sarif + path: | + ${{ steps.analysis.outputs.sarif-output }}/*.sarif + if-no-files-found: error + + - name: Validate SARIF Existence + shell: bash + run: | + ls -l ${{ steps.analysis.outputs.sarif-output }}/*.sarif + + - name: Validate SARIF Results + shell: bash + run: | + # Compare the expected vs the actual + qlt bundle run validate-integration-tests --expected integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif \ No newline at end of file From ae83855331922508622f768e61015b4416902e17 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:46:13 -0500 Subject: [PATCH 04/12] moved stuff --- .github/workflows/run-bundle-integration-tests-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-bundle-integration-tests-cpp.yml b/.github/workflows/run-bundle-integration-tests-cpp.yml index b19ba40..ddf9e6d 100644 --- a/.github/workflows/run-bundle-integration-tests-cpp.yml +++ b/.github/workflows/run-bundle-integration-tests-cpp.yml @@ -43,14 +43,14 @@ jobs: - name: Create Bundle (compiled) shell: bash run: | - if ! qlt codeql run install --custom-bundle ; then + if ! qlt codeql run install --custom-bundle --base example/ ; then echo "Failed to generate bundle." exit 1 fi # ensure bundle runs - if ! qlt query run install-packs --use-bundle ; then + if ! qlt query run install-packs --use-bundle --base example/ ; then echo "Failed to install query packs with tool." exit 1 fi From f3536d6612236affa5ba4534ea25ec956429162c Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:46:49 -0500 Subject: [PATCH 05/12] moved stuff --- .../integration-tests}/cpp/expected.sarif | 0 {integration-tests => example/integration-tests}/cpp/src/Makefile | 0 {integration-tests => example/integration-tests}/cpp/src/main.c | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {integration-tests => example/integration-tests}/cpp/expected.sarif (100%) rename {integration-tests => example/integration-tests}/cpp/src/Makefile (100%) rename {integration-tests => example/integration-tests}/cpp/src/main.c (100%) diff --git a/integration-tests/cpp/expected.sarif b/example/integration-tests/cpp/expected.sarif similarity index 100% rename from integration-tests/cpp/expected.sarif rename to example/integration-tests/cpp/expected.sarif diff --git a/integration-tests/cpp/src/Makefile b/example/integration-tests/cpp/src/Makefile similarity index 100% rename from integration-tests/cpp/src/Makefile rename to example/integration-tests/cpp/src/Makefile diff --git a/integration-tests/cpp/src/main.c b/example/integration-tests/cpp/src/main.c similarity index 100% rename from integration-tests/cpp/src/main.c rename to example/integration-tests/cpp/src/main.c From cf42769a35a23e3f56ffd0b1b4285984e08fe4a6 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 12:47:47 -0500 Subject: [PATCH 06/12] fix other workflow --- .../workflows/internal-pr-bundle-integration-test-cpp.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/internal-pr-bundle-integration-test-cpp.yml b/.github/workflows/internal-pr-bundle-integration-test-cpp.yml index e23c736..db691f1 100644 --- a/.github/workflows/internal-pr-bundle-integration-test-cpp.yml +++ b/.github/workflows/internal-pr-bundle-integration-test-cpp.yml @@ -66,13 +66,12 @@ jobs: with: languages: ${{ matrix.language }} queries: security-extended - source-root: integration-tests/cpp/src/ # Path containing the example application tools: ${{ env.QLT_CODEQL_BUNDLE_PATH }} - name: Autobuild uses: github/codeql-action/autobuild@v2 with: - working-directory: integration-tests/cpp/src/ # Path containing the example application + working-directory: example/integration-tests/cpp/src/ # Path containing the example application - name: Perform CodeQL Analysis id: analysis @@ -105,4 +104,4 @@ jobs: shell: bash run: | # Compare the expected vs the actual - qlt bundle run validate-integration-tests --expected integration-tests/cpp/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/cpp.sarif \ No newline at end of file + qlt bundle run validate-integration-tests --expected example/integration-tests/cpp/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/cpp.sarif \ No newline at end of file From db32a3aaeaeec3d1285a09cd07f4b0c1523600d6 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 13:47:34 -0500 Subject: [PATCH 07/12] improvements to JSON structure --- example/qlt.conf.json | 7 ++++--- .../CodeQL/Commands/Targets/InstallCommand.cs | 5 +++-- .../Targets/InstallQueryPacksCommandTarget.cs | 4 ++-- .../CodeQL/CodeQLInstallation.cs | 12 ++++++------ src/CodeQLToolkit.Shared/Utils/QLTConfig.cs | 12 +++++++----- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/example/qlt.conf.json b/example/qlt.conf.json index 0071334..9beeefd 100644 --- a/example/qlt.conf.json +++ b/example/qlt.conf.json @@ -4,14 +4,15 @@ "CodeQLCLIBundle": "codeql-bundle-v2.15.5", "EnableCustomCodeQLBundles": true, "CodeQLStandardLibraryIdent": "codeql-cli_v2.15.5", - "CustomizationPacks" : [ + "CodeQLPackConfiguration" : [ { "Name": "qlt/cpp-customizations", - "Export" : true + "Bundle" : true }, { "Name": "qlt2/stuff2-tests", - "Export" : false + "Bundle" : false, + "ReferencesBundle" : true } ] } \ No newline at end of file diff --git a/src/CodeQLToolkit.Features/CodeQL/Commands/Targets/InstallCommand.cs b/src/CodeQLToolkit.Features/CodeQL/Commands/Targets/InstallCommand.cs index 8de989a..d90ddcc 100644 --- a/src/CodeQLToolkit.Features/CodeQL/Commands/Targets/InstallCommand.cs +++ b/src/CodeQLToolkit.Features/CodeQL/Commands/Targets/InstallCommand.cs @@ -27,9 +27,10 @@ public override void Run() if (Packs!=null && Packs.Length > 0) { Log.G().LogInformation($"Overriding Packs on the command line. The following Packs will be packaged:"); - installation.CustomizationPacks = Packs.Select(p => new QLTCustomizationPack() + installation.CodeQLPackConfiguration = Packs.Select(p => new CodeQLPackConfiguration() { - Name = p + Name = p, + Bundle = true }).ToArray(); } else diff --git a/src/CodeQLToolkit.Features/Query/Commands/Targets/InstallQueryPacksCommandTarget.cs b/src/CodeQLToolkit.Features/Query/Commands/Targets/InstallQueryPacksCommandTarget.cs index f9aa111..b38d2bc 100644 --- a/src/CodeQLToolkit.Features/Query/Commands/Targets/InstallQueryPacksCommandTarget.cs +++ b/src/CodeQLToolkit.Features/Query/Commands/Targets/InstallQueryPacksCommandTarget.cs @@ -41,7 +41,7 @@ public override void Run() Log.G().LogInformation("In bundle mode so filtering bundled packs..."); - foreach (var pack in config.CustomizationPacks) + foreach (var pack in config.CodeQLPackConfiguration) { Log.G().LogInformation($"Pack {pack.Name} will NOT installed because it is part of the bundle..."); } @@ -49,7 +49,7 @@ public override void Run() files = files.Where(f => // all things that are part of the customization pack must be excluded. // if it is exported is not relevant here. - !config.CustomizationPacks.Any(p => CodeQLPackReader.read(f).Name == p.Name) + !config.CodeQLPackConfiguration.Any(p => CodeQLPackReader.read(f).Name == p.Name && (p.Bundle==true || p.ReferencesBundle==true)) ).ToArray(); Log.G().LogInformation($"Got {files.Length} packs after filtering..."); diff --git a/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs b/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs index 8cb00c2..01c443c 100644 --- a/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs +++ b/src/CodeQLToolkit.Shared/CodeQL/CodeQLInstallation.cs @@ -22,7 +22,7 @@ public class CodeQLInstallation public string CLIBundle { get; set; } public string StandardLibraryIdent { get; set; } public bool EnableCustomCodeQLBundles { get; set; } - public QLTCustomizationPack[] CustomizationPacks { get; set; } + public CodeQLPackConfiguration[] CodeQLPackConfiguration { get; set; } public bool QuickBundle { get; set; } public string Base { get; set; } @@ -47,7 +47,7 @@ public static CodeQLInstallation LoadFromConfig(QLTConfig c) CLIBundle = config.CodeQLCLIBundle, StandardLibraryIdent = config.CodeQLStandardLibraryIdent, StandardLibraryVersion = config.CodeQLStandardLibrary, - CustomizationPacks = config.CustomizationPacks, + CodeQLPackConfiguration = config.CodeQLPackConfiguration, Base = config.Base, CodeQLConfiguration = config.CodeQLConfiguration }; @@ -57,9 +57,9 @@ public static CodeQLInstallation LoadFromConfig(QLTConfig c) public void LogPacksToBeBuilt() { - if(CustomizationPacks != null) + if(CodeQLPackConfiguration != null) { - foreach(var p in CustomizationPacks) + foreach(var p in CodeQLPackConfiguration) { Log.G().LogInformation($"Pack: {p}"); } @@ -278,14 +278,14 @@ private void CustomBundleInstall() var workingDirectory = Path.GetFullPath(Base); - if(CustomizationPacks == null || CustomizationPacks.Length == 0) + if(CodeQLPackConfiguration == null || CodeQLPackConfiguration.Length == 0) { throw new Exception("No packs are set to be exported. Please add at least one pack to export in your `qlt.conf.json` file under the property `ExportedCustomizationPacks`."); } Log.G().LogInformation($"Building custom bundle. This may take a while..."); - var packsToExport = CustomizationPacks.Where(p => p.Export == true).Select(p => p.Name).ToArray(); + var packsToExport = CodeQLPackConfiguration.Where(p => p.Bundle == true).Select(p => p.Name).ToArray(); var packs = string.Join(" ", packsToExport); // next, we run the bundling tool. diff --git a/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs b/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs index 13f4af5..c9663d4 100644 --- a/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs +++ b/src/CodeQLToolkit.Shared/Utils/QLTConfig.cs @@ -7,21 +7,23 @@ namespace CodeQLToolkit.Shared.Utils { - public class QLTCustomizationPack + public class CodeQLPackConfiguration { public string Name { get; set; } - public bool Export { get; set; } - } + public bool Bundle { get; set; } + public bool Publish { get; set;} + public bool ReferencesBundle { get; set; } + + } public class QLTConfig { public string CodeQLCLI { get; set; } public string CodeQLStandardLibrary { get; set; } public string CodeQLCLIBundle { get; set; } - public string CodeQLConfiguration { get; set; } - public QLTCustomizationPack[] CustomizationPacks { get; set; } + public CodeQLPackConfiguration[] CodeQLPackConfiguration { get; set; } public string CodeQLStandardLibraryIdent { get { From 4e8b342587f669d0bfc0d482e7e06d80b6abaf18 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 14:00:22 -0500 Subject: [PATCH 08/12] need to save this file --- .github/workflows/run-bundle-integration-tests-cpp.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-bundle-integration-tests-cpp.yml b/.github/workflows/run-bundle-integration-tests-cpp.yml index ddf9e6d..11e60f8 100644 --- a/.github/workflows/run-bundle-integration-tests-cpp.yml +++ b/.github/workflows/run-bundle-integration-tests-cpp.yml @@ -78,7 +78,7 @@ jobs: - name: Autobuild uses: github/codeql-action/autobuild@v2 with: - working-directory: integration-tests/${{ matrix.language }}/src/ # Path containing the example application + working-directory: example/integration-tests/${{ matrix.language }}/src/ # Path containing the example application - name: Perform CodeQL Analysis id: analysis @@ -108,4 +108,4 @@ jobs: shell: bash run: | # Compare the expected vs the actual - qlt bundle run validate-integration-tests --expected integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif \ No newline at end of file + qlt bundle run validate-integration-tests --expected example/integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif \ No newline at end of file From cf8c6bd45a7af6191b51c522937c4e7e678707fa Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 14:46:32 -0500 Subject: [PATCH 09/12] adding scaffolding --- .../internal-validate-workflow-files.yml | 9 + .../Lifecycle/BundleLifecycleFeature.cs | 35 +++- .../Targets/Actions/InitLifecycleTarget.cs | 49 ++++++ .../run-bundle-integration-tests.liquid | 161 ++++++++++++++++++ .../Targets/Actions/InitLifecycleTarget.cs | 3 +- 5 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs create mode 100644 src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid diff --git a/.github/workflows/internal-validate-workflow-files.yml b/.github/workflows/internal-validate-workflow-files.yml index 8cfbfad..46ee9d1 100644 --- a/.github/workflows/internal-validate-workflow-files.yml +++ b/.github/workflows/internal-validate-workflow-files.yml @@ -47,6 +47,15 @@ jobs: exit 1 fi + - name: Generate Workflow Files (Bundle Feature) + shell: bash + run: | + if ! qlt bundle init --use-runner ubuntu-latest --language cpp --automation-type actions --development --overwrite-existing ; then + echo "Failed to generate bundle workflow files." + exit 1 + fi + + - name: Check Git Clean Status shell: bash run: | diff --git a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs index 9e12242..75e5558 100644 --- a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs +++ b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs @@ -6,6 +6,7 @@ using System.CommandLine; using System.Reflection; using CodeQLToolkit.Features.Bundle.Lifecycle.Targets; +using CodeQLToolkit.Features.Test.Lifecycle; namespace CodeQLToolkit.Features.Bundle.Lifecycle { @@ -32,7 +33,18 @@ public override LanguageType[] SupportedLangauges public void Register(Command parentCommand) { - //Log.G().LogInformation("Registering lifecycle submodule."); + Log.G().LogInformation("Registering lifecycle submodule."); + + var initCommand = new Command("init", "Initialize bundle creation and integration testing features."); + var overwriteExistingOption = new Option("--overwrite-existing", () => false, "Overwrite exiting files (if they exist)."); + var useRunnerOption = new Option("--use-runner", () => "ubuntu-latest", "The runner(s) to use. Should be a comma-seperated list of actions runners."); + var languageOption = new Option("--language", $"The language to generate automation for.") { IsRequired = true }.FromAmong(SupportedLangauges.Select(x => x.ToOptionString()).ToArray()); + + initCommand.AddOption(overwriteExistingOption); + initCommand.AddOption(useRunnerOption); + initCommand.AddOption(languageOption); + + parentCommand.Add(initCommand); var setCommand = new Command("set", "Functions pertaining to setting variables related to custom CodeQL bundles."); //parentCommand.Add(setCommand); @@ -90,6 +102,27 @@ public void Register(Command parentCommand) } + initCommand.SetHandler((devMode, basePath, automationType, overwriteExisting, useRunner, language) => + { + Log.G().LogInformation("Executing init command..."); + + // + // dispatch at runtime to the correct automation type + // + var featureTarget = AutomationFeatureFinder.FindTargetForAutomationType(AutomationTypeHelper.AutomationTypeFromString(automationType)); + + // setup common params + featureTarget.FeatureName = FeatureName; + featureTarget.Base = basePath; + featureTarget.OverwriteExisting = overwriteExisting; + featureTarget.UseRunner = useRunner; + featureTarget.Language = language; + featureTarget.DevMode = devMode; + featureTarget.Run(); + + }, Globals.Development, Globals.BasePathOption, Globals.AutomationTypeOption, overwriteExistingOption, useRunnerOption, languageOption); + + } public int Run() diff --git a/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs b/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs new file mode 100644 index 0000000..f175c64 --- /dev/null +++ b/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeQLToolkit.Features.Bundle.Lifecycle.Targets.Actions +{ + public class InitLifecycleTarget : BaseLifecycleTarget + { + + public InitLifecycleTarget() + { + AutomationType = AutomationType.ACTIONS; + } + + public override void Run() + { + Log.G().LogInformation("Running init command..."); + + // temporarily disable the language resolution + var tmpLanguage = Language; + Language = null; + + WriteTemplateIfOverwriteOrNotExists("install-qlt", Path.Combine(Base, ".github", "actions", "install-qlt", "action.yml"), "install-qlt action"); + WriteTemplateIfOverwriteOrNotExists("run-bundle-integration-tests", Path.Combine(Base, ".github", "workflows", $"run-bundle-integration-tests-{tmpLanguage}.yml"), $"Run CodeQL Unit Tests ({Language})", new + { + useRunner = UseRunner, + language = tmpLanguage, + devMode = DevMode, + }); + + Language = tmpLanguage; + + var message = @"------------------------------------------ +Your repository now has the Bundle Creation and Integration Test Runner installed in `.github/workflows/`. Additionally, +QLT has installed necessary actions for keeping your version of QLT and CodeQL current in `.github/actions/install-qlt`. + +Note that for integration testing to work, you MUST create a directory `integration-test` in the root of your repository. Please +consult the QLT documentation for details on how to structure this directory. + +In addition to using QLT to generate your files you can also directly edit this file to fine tune its settings. + +(Hint: If you'd like to regenerate your files, you can use the `--overwrite-existing` option to overwrite the files that are in place now.)"; + + Log.G().LogInformation(message); + } + } +} diff --git a/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid new file mode 100644 index 0000000..ca9821e --- /dev/null +++ b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid @@ -0,0 +1,161 @@ +name: ⚙️ Integration Test Bundle ({{language}}) + +on: + push: + branches: + - '**' + pull_request: + branches: + - '**' + workflow_dispatch: + +jobs: + integration-test: + name: Run Bundle Integration Test + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + +{% if dev_mode %} + - name: Install QLT + id: install-qlt + uses: ./.github/actions/install-qlt-local + with: + qlt-version: 'latest' + add-to-path: true +{% else %} + - name: Install QLT + id: install-qlt + uses: ./.github/actions/install-qlt + with: + qlt-version: 'latest' + add-to-path: true +{% endif %} +{% raw %} + - name: Validate QLT Installation + shell: bash + run: | + echo -e "Checking QLT Version:" + echo "QLT Home: ${{ steps.install-qlt.outputs.qlt-home }}" + qlt version +{% endraw %} +{% if dev_mode %} + - name: Create Bundle (compiled) + shell: bash + run: | + if ! qlt codeql run install --custom-bundle --base example/ ; then + echo "Failed to generate bundle." + exit 1 + fi + + # ensure bundle runs + + if ! qlt query run install-packs --use-bundle --base example/ ; then + echo "Failed to install query packs with tool." + exit 1 + fi +{% else %} + - name: Create Bundle (compiled) + shell: bash + run: | + if ! qlt codeql run install --custom-bundle ; then + echo "Failed to generate bundle." + exit 1 + fi + + # ensure bundle runs + + if ! qlt query run install-packs --use-bundle ; then + echo "Failed to install query packs with tool." + exit 1 + fi +{% endif %} +{% raw %} + - name: Validate Bundle Existence + shell: bash + run: | + echo "Checking Bundle Existence" + ls -l ${{ env.QLT_CODEQL_HOME }}/../out/ + + - name: Upload Bundle Used + uses: actions/upload-artifact@v2 + with: + name: codeql-bundle.tar.gz + path: | + ${{ env.QLT_CODEQL_BUNDLE_PATH }} + if-no-files-found: error + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + tools: ${{ env.QLT_CODEQL_BUNDLE_PATH }} +{% endraw %} +{% if dev_mode %} +{% raw %} + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + with: + working-directory: example/integration-tests/${{ matrix.language }}/src/ # Path containing the example application +{% endraw %} +{% else %} +{% raw %} + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + with: + working-directory: integration-tests/${{ matrix.language }}/src/ # Path containing the example application +{% endraw %} +{% endif %} +{% raw %} + - name: Perform CodeQL Analysis + id: analysis + uses: github/codeql-action/analyze@v2 + + - name: Validate SARIF Location + shell: bash + run: | + # validate we have the actual sarif results + echo "Checking SARIF file location at: ${{ steps.analysis.outputs.sarif-output }}" + ls -l ${{ steps.analysis.outputs.sarif-output }} + + - name: Upload SARIF Results + uses: actions/upload-artifact@v2 + with: + name: actual.sarif + path: | + ${{ steps.analysis.outputs.sarif-output }}/*.sarif + if-no-files-found: error + + - name: Validate SARIF Existence + shell: bash + run: | + ls -l ${{ steps.analysis.outputs.sarif-output }}/*.sarif +{% endraw %} + +{% if dev_mode %} +{% raw %} + - name: Validate SARIF Results + shell: bash + run: | + # Compare the expected vs the actual + qlt bundle run validate-integration-tests --expected example/integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif +{% endraw %} +{% else %} +{% raw %} + - name: Validate SARIF Results + shell: bash + run: | + # Compare the expected vs the actual + qlt bundle run validate-integration-tests --expected integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif +{% endraw %} +{% else %} \ No newline at end of file diff --git a/src/CodeQLToolkit.Features/Test/Lifecycle/Targets/Actions/InitLifecycleTarget.cs b/src/CodeQLToolkit.Features/Test/Lifecycle/Targets/Actions/InitLifecycleTarget.cs index e430196..be693c4 100644 --- a/src/CodeQLToolkit.Features/Test/Lifecycle/Targets/Actions/InitLifecycleTarget.cs +++ b/src/CodeQLToolkit.Features/Test/Lifecycle/Targets/Actions/InitLifecycleTarget.cs @@ -45,8 +45,7 @@ public override void Run() var message = @"------------------------------------------ Your repository now has the CodeQL Unit Test Runner installed in `.github/workflows/`. Additionally, -QLT has installed necessary actions for keeping your version of QLT and CodeQL current in `.github/actions/install-qlt` and -`.github/actions/install-codeql`. +QLT has installed necessary actions for keeping your version of QLT and CodeQL current in `.github/actions/install-qlt`. Note that, by default, your runner will use 4 threads and defaults to the `ubuntu-latest` runner. From 2220b3954a9f1367390405e511b8131ab6940482 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 14:59:13 -0500 Subject: [PATCH 10/12] templates fixes --- .../Properties/launchSettings.json | 2 +- .../Bundle/Lifecycle/BaseLifecycleTarget.cs | 5 -- .../Lifecycle/BundleLifecycleFeature.cs | 7 +- .../Targets/Actions/InitLifecycleTarget.cs | 1 + .../CodeQLToolkit.Features.csproj | 7 +- .../Bundle/Actions/install-qlt.liquid | 82 +++++++++++++++++++ 6 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 src/CodeQLToolkit.Features/Templates/Bundle/Actions/install-qlt.liquid diff --git a/src/CodeQLToolkit.Core/Properties/launchSettings.json b/src/CodeQLToolkit.Core/Properties/launchSettings.json index 58a6cf3..9be4b41 100644 --- a/src/CodeQLToolkit.Core/Properties/launchSettings.json +++ b/src/CodeQLToolkit.Core/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "CodeQLToolkit.Core": { "commandName": "Project", - "commandLineArgs": "--base C:\\Projects\\codeql-development-lifecycle-toolkit\\example bundle set enable-custom-bundles" + "commandLineArgs": "bundle init --use-runner ubuntu-latest --language cpp --automation-type actions --development --overwrite-existing" } } } \ No newline at end of file diff --git a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BaseLifecycleTarget.cs b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BaseLifecycleTarget.cs index 04b4b17..b5e8f44 100644 --- a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BaseLifecycleTarget.cs +++ b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BaseLifecycleTarget.cs @@ -8,12 +8,7 @@ namespace CodeQLToolkit.Features.Bundle.Lifecycle { abstract public class BaseLifecycleTarget : ILifecycleTarget { - public int NumThreads { get; set; } public string UseRunner { get; set; } - public string ExtraArgs { get; set; } - - - } } diff --git a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs index 75e5558..e8234cb 100644 --- a/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs +++ b/src/CodeQLToolkit.Features/Bundle/Lifecycle/BundleLifecycleFeature.cs @@ -1,12 +1,7 @@ -using CodeQLToolkit.Features.CodeQL.Lifecycle.Targets; -using CodeQLToolkit.Features.CodeQL.Lifecycle; -using CodeQLToolkit.Features.Test.Lifecycle.Targets; -using CodeQLToolkit.Features.Test.Lifecycle.Targets.Actions; +using CodeQLToolkit.Features.CodeQL.Lifecycle; using CodeQLToolkit.Shared.Utils; using System.CommandLine; -using System.Reflection; using CodeQLToolkit.Features.Bundle.Lifecycle.Targets; -using CodeQLToolkit.Features.Test.Lifecycle; namespace CodeQLToolkit.Features.Bundle.Lifecycle { diff --git a/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs b/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs index f175c64..969c4d0 100644 --- a/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs +++ b/src/CodeQLToolkit.Features/Bundle/Lifecycle/Targets/Actions/InitLifecycleTarget.cs @@ -6,6 +6,7 @@ namespace CodeQLToolkit.Features.Bundle.Lifecycle.Targets.Actions { + [AutomationType(AutomationType.ACTIONS)] public class InitLifecycleTarget : BaseLifecycleTarget { diff --git a/src/CodeQLToolkit.Features/CodeQLToolkit.Features.csproj b/src/CodeQLToolkit.Features/CodeQLToolkit.Features.csproj index df18b6d..ed75ed1 100644 --- a/src/CodeQLToolkit.Features/CodeQLToolkit.Features.csproj +++ b/src/CodeQLToolkit.Features/CodeQLToolkit.Features.csproj @@ -11,7 +11,6 @@ - @@ -22,6 +21,12 @@ + + Always + + + Always + Always diff --git a/src/CodeQLToolkit.Features/Templates/Bundle/Actions/install-qlt.liquid b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/install-qlt.liquid new file mode 100644 index 0000000..cb53a5c --- /dev/null +++ b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/install-qlt.liquid @@ -0,0 +1,82 @@ +name: Fetch and Install QLT +description: | + Fetches and installs QLT. +inputs: + qlt-version: + description: | + The version of QLT to be downloaded. + required: false + default: 'latest' + + add-to-path: + description: | + Add QLT to the system path + required: false + default: 'true' + +outputs: + qlt-home: + description: 'The directory containing the QLT installation' + value: ${{ steps.install-qlt.outputs.qlt-home }} + +runs: + using: composite + steps: + - name: Install QLT + id: install-qlt + env: + RUNNER_OS: ${{ runner.os }} + RUNNER_TEMP: ${{ runner.temp }} + ADD_TO_PATH: ${{ inputs.add-to-path }} + QLT_VERSION: ${{ inputs.qlt-version }} + QLT_HOME: ${{ inputs.qlt-home }} + GITHUB_TOKEN: ${{ github.token }} + + shell: bash + run: | + echo -e "\e[0;32m[QLT]\e[0m Determining QLT release for $RUNNER_OS" + case $RUNNER_OS in + "Linux") + RELEASE_PATTERN="qlt-linux-x86_64.zip" + ;; + *) + echo "::error::Unsupported runner operating system $RUNNER_OS" + exit 1 + ;; + esac + echo -e "\e[0;32m[QLT]\e[0m Selected $RELEASE_PATTERN" + + if [ "$QLT_HOME" == "" ] + then + echo -e "\e[0;32m[QLT]\e[0m Creating temporary QLT home" + QLT_HOME=$(mktemp -d -p $RUNNER_TEMP qlt-home-XXXXXXXXXX) + else + echo -e "\e[0;32m[QLT]\e[0m Creating CodeQL home at $QLT_HOME" + mkdir -p $QLT_HOME + fi + + echo -e "\e[0;32m[QLT]\e[0m Changing directory to $QLT_HOME" + pushd $QLT_HOME + + echo -e "\e[0;32m[QLT]\e[0m Downloading QLT version $QLT_VERSION" + if [ "$QLT_VERSION" == "latest" ] + then + # download the actual bundle + gh release download -R advanced-security/codeql-development-toolkit --pattern "$RELEASE_PATTERN" + else + gh release download "$QLT_VERSION" -R advanced-security/codeql-development-toolkit --pattern "$RELEASE_PATTERN" + fi + echo -e "\e[0;32m[QLT]\e[0m Unpacking QLT" + unzip $RELEASE_PATTERN + + if [ "$ADD_TO_PATH" == "true" ] + then + echo -e "\e[0;32m[QLT]\e[0m Adding QLT '$(pwd)/qlt' to system path" + echo "$(pwd)" >> $GITHUB_PATH + fi + + echo -e "\e[0;32m[QLT]\e[0m Setting output parameter qlt-home to $(pwd)" + echo "qlt-home=$(pwd)" >> $GITHUB_OUTPUT + + popd + echo -e "\e[0;32m[QLT]\e[0m Done." From b66af5f73097d0fc9b928b6e612c8c0d16b4e744 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 15:04:27 -0500 Subject: [PATCH 11/12] fix template --- .../Bundle/Actions/run-bundle-integration-tests.liquid | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid index ca9821e..780cf2d 100644 --- a/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid +++ b/src/CodeQLToolkit.Features/Templates/Bundle/Actions/run-bundle-integration-tests.liquid @@ -158,4 +158,4 @@ jobs: # Compare the expected vs the actual qlt bundle run validate-integration-tests --expected integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif {% endraw %} -{% else %} \ No newline at end of file +{% endif %} \ No newline at end of file From 4367b9a12ccccaeead75851f2c771ba4462722d8 Mon Sep 17 00:00:00 2001 From: "John L. Singleton" Date: Thu, 7 Mar 2024 15:05:33 -0500 Subject: [PATCH 12/12] fix --- .../run-bundle-integration-tests-cpp.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-bundle-integration-tests-cpp.yml b/.github/workflows/run-bundle-integration-tests-cpp.yml index 11e60f8..f1c66ab 100644 --- a/.github/workflows/run-bundle-integration-tests-cpp.yml +++ b/.github/workflows/run-bundle-integration-tests-cpp.yml @@ -1,4 +1,4 @@ -name: ⚙️ Integration Test Bundle (CPP) +name: ⚙️ Integration Test Bundle (cpp) on: push: @@ -26,6 +26,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Install QLT id: install-qlt uses: ./.github/actions/install-qlt-local @@ -33,6 +34,7 @@ jobs: qlt-version: 'latest' add-to-path: true + - name: Validate QLT Installation shell: bash run: | @@ -40,6 +42,7 @@ jobs: echo "QLT Home: ${{ steps.install-qlt.outputs.qlt-home }}" qlt version + - name: Create Bundle (compiled) shell: bash run: | @@ -55,6 +58,7 @@ jobs: exit 1 fi + - name: Validate Bundle Existence shell: bash run: | @@ -75,11 +79,15 @@ jobs: languages: ${{ matrix.language }} tools: ${{ env.QLT_CODEQL_BUNDLE_PATH }} + + - name: Autobuild uses: github/codeql-action/autobuild@v2 with: working-directory: example/integration-tests/${{ matrix.language }}/src/ # Path containing the example application + + - name: Perform CodeQL Analysis id: analysis uses: github/codeql-action/analyze@v2 @@ -104,8 +112,12 @@ jobs: run: | ls -l ${{ steps.analysis.outputs.sarif-output }}/*.sarif + + + - name: Validate SARIF Results shell: bash run: | # Compare the expected vs the actual - qlt bundle run validate-integration-tests --expected example/integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif \ No newline at end of file + qlt bundle run validate-integration-tests --expected example/integration-tests/${{ matrix.language }}/expected.sarif --actual ${{ steps.analysis.outputs.sarif-output }}/${{ matrix.language }}.sarif +