diff --git a/.github/workflows/build-vsix.yml b/.github/workflows/build-vsix.yml new file mode 100644 index 0000000..04f3f60 --- /dev/null +++ b/.github/workflows/build-vsix.yml @@ -0,0 +1,62 @@ +name: Build VSIX + +on: + workflow_call: + inputs: + ref: + required: true + type: string + +jobs: + build: + runs-on: windows-latest + + env: + # jfrog cli version can be changed here + JFROG_CLI_VERSION: '2.67.0' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + + - name: Setup MSBuild + uses: microsoft/setup-msbuild@v1 + with: + vs-version: 'latest' + + # caching NuGet packages for optimizing the build process + - name: Cache NuGet packages + uses: actions/cache@v3 + with: + path: ~/.nuget/packages + key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }} + restore-keys: nuget-${{ runner.os }}- + + - name: Restore dependencies + run: | + dotnet restore + nuget restore + + - name: Download JFrog CLI executable + run: | + .\scripts\DownloadJfrogCli.ps1 + shell: pwsh + + # build the vsix project using multi-core compilation and parallel builds + - name: Build VSIX Project + run: msbuild JFrogVSExtension.sln /p:Configuration=Release /p:Platform="Any CPU" /p:BuildInParallel=true /m + + # Upload vsix and unit test as artifacts for other workflows usage + - name: Upload vsix artifacts + uses: actions/upload-artifact@v3 + with: + name: vsix-artifacts + path: "JFrogVSExtension/bin/Release/" + + - name: Upload tests artifacts + uses: actions/upload-artifact@v3 + with: + name: tests-artifacts + path: "UnitTestJfrogVSExtension/bin/Release/" \ No newline at end of file diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index e36268d..0675cd2 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -18,8 +18,8 @@ jobs: - name: "CLA Assistant" if: ${{ steps.sign-or-recheck.outputs.match != '' || github.event_name == 'pull_request_target' }} - # Alpha Release - uses: cla-assistant/github-action@v2.1.1-beta + + uses: cla-assistant/github-action@v2.6.0 env: # Generated and maintained by github GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b4a9f9c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,73 @@ +name: Release + +on: + release: + types: [published] + +jobs: + + pre-build: + name: Update version in source code + runs-on: windows-latest + env: + NEW_VERSION: '${{ github.ref_name }}' + MANIFEST_FILE_PATH: "JfrogVSExtension/source.extension.vsixmanifest" + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.target_commitish }} + + - name: Update VSIX Version in manifest file + run: .\scripts\UpdateVsixVersion.ps1 + shell: pwsh + + - name: Commit and push changes + run: | + git config --local user.name "${{ github.actor }}" + git config --local user.email "${{ github.actor }}@users.noreply.github.com" + git add . + git commit -m "Updated VSIX version to ${{ env.NEW_VERSION }}" + git push + + call-build-workflow: + # build and package the vsix project + uses: ./.github/workflows/build-vsix.yml + with: + ref: ${{ github.event.release.target_commitish }} + needs: pre-build + + release: + runs-on: windows-latest + needs: call-build-workflow + steps: + # download build workflow artifacts + - name: Download VSIX artifacts + uses: actions/download-artifact@v3 + with: + name: vsix-artifacts + path: ./JFrogVSExtension/bin/Release + + - name: Upload VSIX and attach it to the Release page + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./JFrogVSExtension/bin/Release/JFrogVSExtension.vsix + asset_name: JFrogVSExtension.vsix + asset_content_type: application/octet-stream + + # upload the vsix and manifest files to Visual Studio Marketplace using VsixPublisher + - name: Publish to Visual Studio Marketplace + env: + # vsix publisher executable is already installed in the github windows runner at the following path + VSIX_PUBLISHER_PATH: "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VSSDK/VisualStudioIntegration/Tools/Bin/VsixPublisher.exe" + VSIX_PATH: "./JFrogVSExtension/bin/Release/JFrogVSExtension.vsix" + PUBLISH_MANIFEST_PATH: "./JFrogVSExtension/PublishManifest.json" + run: | + $Env:VSIX_PUBLISHER_PATH publish ` + -payload $Env:VSIX_PATH ` + -publishManifest $Env:PUBLISH_MANIFEST_PATH ` + -personalAccessToken ${{ secrets.VS_MARKETPLACE_PAT }} \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a2782b4..a3c561f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,44 +1,39 @@ -name: Run Tests +name: Build and Run Tests on: push: pull_request: - type: [ labeled ] + type: [ labeled ] jobs: - build: + call-build-workflow: + uses: ./.github/workflows/build-vsix.yml + with: + ref: ${{ github.event.pull_request.head.sha }} + + test: runs-on: windows-latest + needs: call-build-workflow steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} - - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1 + # download build workflow artifacts + - name: Download VSIX artifact + uses: actions/download-artifact@v3 with: - vs-version: 'latest' + name: vsix-artifacts + path: ./JFrogVSExtension/bin/Release - - name: Cache NuGet packages # optimizing the build process - uses: actions/cache@v3 + - name: Download Unit Test artifacts + uses: actions/download-artifact@v3 with: - path: ~/.nuget/packages - key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }} - restore-keys: nuget-${{ runner.os }}- - - - name: Restore dependencies - run: | - dotnet restore - nuget restore - - - name: Download JFrog CLI executable - env: - JFROG_CLI_VERSION: '2.67.0' # jfrog cli version can be changed here - run: .\JFrogVSExtension\Resources\DownloadJfrogCli.ps1 - shell: pwsh - - - name: Build VSIX Project # build the vsix project using multi-core compilation and parallel builds - run: msbuild JFrogVSExtension.sln /p:Configuration=Release /p:Platform="Any CPU" /p:BuildInParallel=true /m + name: tests-artifacts + path: ./UnitTestJfrogVSExtension/bin/Release - - name: Run MSTest Project # run tests in release mode with logs presentation + # run tests in release mode with logs presentation + - name: Run MSTest Project run: dotnet test --no-build --configuration Release --logger "console;verbosity=detailed" ./UnitTestJfrogVSExtension/bin/Release/UnitTestJfrogVSExtension.dll - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..77c7be2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +# Contribution Guide + +## Guidelines +- If the existing tests do not already cover your changes, please add tests. + +## Building the Sources + +To build the plugin sources, please follow these steps: +1. Clone the code from git. +2. Download the [JFrog CLI executable](https://jfrog.com/getcli/) for Windows and place it under **$PROJECT_LOCATION\JFrogVSExtension\Resources**. +3. Open Visual Studio. +4. Open *Tools* --> *Get Tools and Features* + +![alt](docs/images/getTools.png) + +5. Select the *workloads* tab and scroll to the bottom for the *Other Toolsets* section. Install *Visual Studio extension development*. Read more about Visual Studio SDK [here](https://docs.microsoft.com/en-us/visualstudio/extensibility/installing-the-visual-studio-sdk?view=vs-2017). + +![alt](docs/images/extension.png) + +6. Once the installation is completed, re-open Visual Studio. +7. Click on *File* --> *Open* --> *Project/Solution* and navigate to the project root dir and select the sln file. +8. To build the project, click on *Build* tab --> *Build Solution*. The VSIX file will be created in the following location: **$PROJECT_LOCATION\bin\Release\JFrog.VSExtension.vsix** +9. If the build fails, please refer to the *Troublshooting Issues* section. + +![alt](docs/images/build.png) + +10. If you'd like to help us develop and enhance the extension, this step is for you. + To build and run the plugin following your code changes, click on *Debug* --> *Start Debugging*. + +![alt](docs/images/debug.png) + +## Run the tests +After build has finished successfuly, you can run the tests using: +1. Visual Studio Test Explorer - click on *Test* -> *Run All Tests*. +2. Command line interface - navigate to the tests folder /UnitTestJfrogVSExtension/bin/{Release/Debug} and then run the following command: +```bash +dotnet test .\UnitTestJfrogVSExtension.dll +``` + +## Troublshooting Issues +When openning the project in Visual Studio for the first time, the following error may appear : *"Fody.WeavingTask" task was not given a value for the required parameter "SolutionDir"*. + +To fix this,close the solution and open it again. More information can be found [here](https://stackoverflow.com/questions/50225374/xamarinissues-with-fody-weavingtask-and-solutiondir) diff --git a/JFrogVSExtension/PublishManifest.json b/JFrogVSExtension/PublishManifest.json new file mode 100644 index 0000000..97534c6 --- /dev/null +++ b/JFrogVSExtension/PublishManifest.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json.schemastore.org/vsix-publish", + "categories": [ "build", "coding" ], // The categories of the extension. Between 1 and 3 categories are required. + "identity": { + "internalName": "JFrog V2" // If not specified, we try to generate the name from the display name of the extension in the vsixmanifest file. + // Required if the display name is not the actual name of the extension. + }, + "overview": "../README.md", // Path to the "readme" file that gets uploaded to the Marketplace. Required. + "priceCategory": "free", // Either "free", "trial", or "paid". Defaults to "free". + "publisher": "JFrog", // The name of the publisher. Required. + "private": false, // Specifies whether or not the extension should be public when uploaded. Defaults to false. + "qna": true, // Specifies whether or not the extension should have a Q&A section. Defaults to true. + "repo": "https://github.com/jfrog/jfrog-visual-studio-extension" // Not required. +} \ No newline at end of file diff --git a/JFrogVSExtension/source.extension.vsixmanifest b/JFrogVSExtension/source.extension.vsixmanifest index b4c5038..835aea8 100644 --- a/JFrogVSExtension/source.extension.vsixmanifest +++ b/JFrogVSExtension/source.extension.vsixmanifest @@ -1,25 +1,25 @@  - - - JFrog V2 - Visual Studio extension to integrate with JFrog Xray for scanning solution components. - Resources\Icon.png - Resources\PreviewImage.png - - - - amd64 - - - - - - - - - - - - - + + + JFrog V2 + Visual Studio extension to integrate with JFrog Xray for scanning solution components. + Resources\Icon.png + Resources\PreviewImage.png + + + + amd64 + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 56c5bfe..85e1e13 100644 --- a/README.md +++ b/README.md @@ -42,39 +42,8 @@ The icon demonstrates the top severity issue of a selected component and its tra 5. Click on *Download* 6. Once the installation is completed, re-open Visual Studio. -## Building the Sources - -To build the plugin sources, please follow these steps: -1. Clone the code from git. -2. Download the [JFrog CLI executable](https://jfrog.com/getcli/) for Windows and place it under **$PROJECT_LOCATION\JFrogVSExtension\Resources**. -3. Open Visual Studio. -4. Open *Tools* --> *Get Tools and Features* - -![alt](docs/images/getTools.png) - -5. Select the *workloads* tab and scroll to the bottom for the *Other Toolsets* section. Install *Visual Studio extension development*. Read more about Visual Studio SDK [here](https://docs.microsoft.com/en-us/visualstudio/extensibility/installing-the-visual-studio-sdk?view=vs-2017). - -![alt](docs/images/extension.png) - -6. Once the installation is completed, re-open Visual Studio. -7. Click on *File* --> *Open* --> *Project/Solution* and navigate to the project root dir and select the sln file. -8. To build the project, click on *Build* tab --> *Build Solution*. The VSIX file will be created in the following location: **$PROJECT_LOCATION\bin\Release\JFrog.VSExtension.vsix** -9. If the build fails, please refer to the *Troublshooting Issues* section. - -![alt](docs/images/build.png) - -10. If you'd like to help us develop and enhance the extension, this step is for you. - To build and run the plugin following your code changes, click on *Debug* --> *Start Debugging*. - -![alt](docs/images/debug.png) - -## Troublshooting Issues -When openning the project in Visual Studio for the first time, the following error may appear : *"Fody.WeavingTask" task was not given a value for the required parameter "SolutionDir"*. - -To fix this,close the solution and open it again. More information can be found [here](https://stackoverflow.com/questions/50225374/xamarinissues-with-fody-weavingtask-and-solutiondir) - ## Release Notes -The release notes are available [here](RELEASE.md#release-notes). +The release notes are available [here](https://github.com/jfrog/jfrog-visual-studio-extension/releases). ## Code Contributions We welcome community contribution through pull requests. diff --git a/RELEASE.md b/RELEASE.md deleted file mode 100644 index 56dc692..0000000 --- a/RELEASE.md +++ /dev/null @@ -1,19 +0,0 @@ -# Release Notes - -## 2.0.1 (Aug 27, 2024) -- Change Scan Timeout - -## 2.0.0 (October 19, 2022) -- Add support for Xray's Watches. -- Add support for npm projects. -- Add support for connection to JFrog Platform with AccessToken. -- Add Fixed versions field display. - -## 1.0.8 (July 18, 2021) -- Fix marketplace icon. - -## 1.0.7 (July 18, 2021) -- Bug fix - Add critical issue severity (fixes crash in Visual Studio 2019). - -## 1.0.6 (September 2, 2020) -- Bug fix - IDE-20 - Visual studio 2019 crashes when viewing some directories. diff --git a/UnitTestJfrogVSExtension/PowerShellScriptTests.cs b/UnitTestJfrogVSExtension/PowerShellScriptTests.cs new file mode 100644 index 0000000..f8811e2 --- /dev/null +++ b/UnitTestJfrogVSExtension/PowerShellScriptTests.cs @@ -0,0 +1,115 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System.IO; +using System.Diagnostics; +using System; + +namespace UnitTestJfrogVSExtension +{ + [TestClass] + public class PowerShellScriptTests + { + public TestContext TestContext { get; set; } + + // use relative path (from base dir) in order to be able to run in other environments + public static string rootDir = GetProjectRoot(AppDomain.CurrentDomain.BaseDirectory); + public static string updateVersionScriptPath = Path.Combine(rootDir, @"scripts\UpdateVsixVersion.ps1"); + public static string downloadCliScriptPath = Path.Combine(rootDir, @"scripts\DownloadJfrogCli.ps1"); + public static string vsixManifestMockPath = Path.Combine(rootDir, @"scripts\vsixmanifestMock"); + + [TestMethod] + public void Test_UpdateVsixVersion_ValidVersion() + { + var envVars = new Dictionary + { + { "NEW_VERSION", "vs22-1.2.3" }, // Valid version + { "MANIFEST_FILE_LOCATION", vsixManifestMockPath}, + }; + + // script should succeed and return exit code 0 + int exitCode = RunPowerShellScript(updateVersionScriptPath, envVars); + Assert.AreEqual(0, exitCode); + } + + [TestMethod] + public void Test_UpdateVsixVersion_InvalidVersion() + { + var envVars = new Dictionary + { + { "NEW_VERSION", "vs-1.5.56" }, // Invalid version + { "MANIFEST_FILE_LOCATION", vsixManifestMockPath}, + }; + + // script should fail and return exit code 1 + int exitCode = RunPowerShellScript(updateVersionScriptPath, envVars); + Assert.AreEqual(1, exitCode); + } + + + [TestMethod] + public void Test_DownloadJfrogCli() + { + var envVars = new Dictionary + { + { "JFROG_CLI_VERSION", "2.67.0" }, + {"PROJECT_ROOT", rootDir } + }; + + // script should succeed and return exit code 0 + int exitCode = RunPowerShellScript(downloadCliScriptPath, envVars); + Assert.AreEqual(0, exitCode); + } + + private static string GetProjectRoot(string currentDir) + { + while (Directory.GetFiles(currentDir, "*.sln").Length == 0) + { + if (Directory.GetParent(currentDir) == null) + { + Console.WriteLine("ERROR: Root directory not found."); + } else { + currentDir = Directory.GetParent(currentDir).FullName; + } + } + return currentDir; + } + + private int RunPowerShellScript(string scriptPath, Dictionary envVars) + { + // Create a new process to run the PowerShell script + ProcessStartInfo processInfo = new ProcessStartInfo("powershell.exe", $"-ExecutionPolicy Bypass -File \"{scriptPath}\"") + { + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + // Set environment variables + foreach (var envVar in envVars) + { + processInfo.EnvironmentVariables[envVar.Key] = envVar.Value; + } + + // Run the script in a process + using (Process process = new Process()) + { + process.StartInfo = processInfo; + process.Start(); + process.WaitForExit(); + + // read output and error + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + + // log output and error for debug + Debug.WriteLine($"Output: {output}"); + Debug.WriteLine($"Error: {error}"); + + return process.ExitCode; + } + + } + + } +} diff --git a/UnitTestJfrogVSExtension/UnitTest1.cs b/UnitTestJfrogVSExtension/UnitTest1.cs deleted file mode 100644 index bde9a6f..0000000 --- a/UnitTestJfrogVSExtension/UnitTest1.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Diagnostics; - -namespace UnitTestJfrogVSExtension -{ - [TestClass] - public class UnitTest1 - { - public TestContext TestContext { get; set; } - - [TestMethod] - public void TestMethod1() - { - TestContext.WriteLine("Success!!!"); - } - } -} diff --git a/UnitTestJfrogVSExtension/UnitTestJfrogVSExtension.csproj b/UnitTestJfrogVSExtension/UnitTestJfrogVSExtension.csproj index 9ac2522..45e6894 100644 --- a/UnitTestJfrogVSExtension/UnitTestJfrogVSExtension.csproj +++ b/UnitTestJfrogVSExtension/UnitTestJfrogVSExtension.csproj @@ -42,7 +42,7 @@ - + diff --git a/JFrogVSExtension/Resources/DownloadJfrogCli.ps1 b/scripts/DownloadJfrogCli.ps1 similarity index 84% rename from JFrogVSExtension/Resources/DownloadJfrogCli.ps1 rename to scripts/DownloadJfrogCli.ps1 index 376b652..4ae0d27 100644 --- a/JFrogVSExtension/Resources/DownloadJfrogCli.ps1 +++ b/scripts/DownloadJfrogCli.ps1 @@ -6,13 +6,18 @@ if ($env:JFROG_CLI_VERSION) { exit 1 } +# if root was not defined - use current location +if (-not $env:PROJECT_ROOT) { + $env:PROJECT_ROOT="$(pwd)" +} + # Define the URL for the JFrog CLI executable $jfrogCliUrl = "https://releases.jfrog.io/artifactory/jfrog-cli/v2-jf/$($env:JFROG_CLI_VERSION)/jfrog-cli-windows-amd64/jf.exe" # Define the destination path for the downloaded file -$destinationPath = Join-Path (Get-Location).Path "JFrogVSExtension/Resources/jfrog.exe" +$destinationPath = Join-Path $env:PROJECT_ROOT "JFrogVSExtension/Resources/jfrog.exe" -# Download the JFrog CLI executable +# Download the JFrog CLI executable Invoke-WebRequest -Uri $jfrogCliUrl -OutFile $destinationPath -Verbose diff --git a/scripts/UpdateVsixVersion.ps1 b/scripts/UpdateVsixVersion.ps1 new file mode 100644 index 0000000..c7e7553 --- /dev/null +++ b/scripts/UpdateVsixVersion.ps1 @@ -0,0 +1,24 @@ +$newVersion = $env:NEW_VERSION +$manifestFileLocation = $env:MANIFEST_FILE_LOCATION + +# Validate the NEW_VERSION format: "vs22-x.x.x" +if ($newVersion -match "^vs22-(\d+\.\d+\.\d+)$") { + # Extract version from the tag (e.g., 'vs22-1.0.0' -> '1.0.0') + $newVersion = $matches[1] +} else { + Write-Error "Error: NEW_VERSION must be in the format 'vs22-x.x.x' where x is an integer." + exit 1 +} + +if (-not $env:MANIFEST_FILE_LOCATION){ + Write-Error "Error: MANIFEST_FILE_LOCATION environment variable is not set." + exit 1 +} elseif (-not (Test-Path $env:MANIFEST_FILE_LOCATION)){ + Write-Error "The file specified in MANIFEST_FILE_LOCATION does not exist." + exit 1 +} + +# Load the manifest file and update the version +[xml]$manifest = Get-Content -Path $manifestFileLocation +$manifest.PackageManifest.Metadata.Identity.Version = $newVersion +$manifest.Save($manifestFileLocation) \ No newline at end of file diff --git a/scripts/vsixmanifestMock b/scripts/vsixmanifestMock new file mode 100644 index 0000000..62a119e --- /dev/null +++ b/scripts/vsixmanifestMock @@ -0,0 +1,25 @@ + + + + + JFrog V2 + Visual Studio extension to integrate with JFrog Xray for scanning solution components. + Resources\Icon.png + Resources\PreviewImage.png + + + + amd64 + + + + + + + + + + + + + \ No newline at end of file