{"id":17902080,"url":"https://github.com/lancemccarthy/devopsexamples","last_synced_at":"2025-03-23T13:31:54.336Z","repository":{"id":38351374,"uuid":"269422216","full_name":"LanceMcCarthy/DevOpsExamples","owner":"LanceMcCarthy","description":"A repo to show you how to use a private NuGet feed to restore packages in Azure DevOps, GitHub Actions, GitLab CI and AppCenter.","archived":false,"fork":false,"pushed_at":"2024-10-24T14:14:30.000Z","size":20495,"stargazers_count":30,"open_issues_count":0,"forks_count":21,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-10-25T17:41:58.894Z","etag":null,"topics":["angular","aspnetcore","ci-cd","ci-cd-pipeline","dotnet","nuget","react","uwp","vue","wpf","xamarin","xamarin-forms"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LanceMcCarthy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-04T17:26:17.000Z","updated_at":"2024-10-24T14:14:29.000Z","dependencies_parsed_at":"2023-09-22T07:12:33.494Z","dependency_job_id":"ed54f4b6-0cb3-4649-90f9-c3be0f452d69","html_url":"https://github.com/LanceMcCarthy/DevOpsExamples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanceMcCarthy%2FDevOpsExamples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanceMcCarthy%2FDevOpsExamples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanceMcCarthy%2FDevOpsExamples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LanceMcCarthy%2FDevOpsExamples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LanceMcCarthy","download_url":"https://codeload.github.com/LanceMcCarthy/DevOpsExamples/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245108238,"owners_count":20562010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","aspnetcore","ci-cd","ci-cd-pipeline","dotnet","nuget","react","uwp","vue","wpf","xamarin","xamarin-forms"],"created_at":"2024-10-28T16:04:45.678Z","updated_at":"2025-03-23T13:31:54.317Z","avatar_url":"https://github.com/LanceMcCarthy.png","language":"C#","readme":"# DevOps - Pipeline and Workflow Examples\n\nThis repository contains a rich set of CI-CD demos where I show you how to:\n\n- Connect to private nuget feeds; Azure, GitHub packages, and custom (eg Telerik).\n- Build .NET apps and publish to a container registry; Docker, Azure, GitHub, etc.\n\nAlthough I use Telerik's NuGet server because I have a license, these demos are good for any private feed type; just use your source URL and credentials instead!\n\n## Table of Contents\n- [CI Systems](https://github.com/LanceMcCarthy/DevOpsExamples#ci-systems)\n- [Build Badges](https://github.com/LanceMcCarthy/DevOpsExamples#badges)\n- [Videos](https://github.com/LanceMcCarthy/DevOpsExamples#videos)\n  - [Authenticating in Azure DevOps](https://github.com/LanceMcCarthy/DevOpsExamples#azure-devops-with-telerik-nuget-server)\n- [Tips and Troubleshooting](https://github.com/LanceMcCarthy/DevOpsExamples#tips-and-troubleshooting)\n  - [Walkthrough: Use GitHub Secrets](https://github.com/LanceMcCarthy/DevOpsExamples#github-actions-using-secrets-to-set-environment-variables)\n  - [Example: Update package source dynamically](https://github.com/LanceMcCarthy/DevOpsExamples#powershell-update-package-source-dynamically)\n  - [Example Using Telerik NuGet Keys](https://github.com/LanceMcCarthy/DevOpsExamples#using-telerik-nuget-keys)\n  - [Dockerfile: Using Secrets](https://github.com/LanceMcCarthy/DevOpsExamples#dockerfile-using-secrets)\n  - [Telerik License Approaches](https://github.com/LanceMcCarthy/DevOpsExamples#telerik-license-approaches)\n- Related Blog Posts\n  - [Blog: DevOps and Telerik NuGet Packages](https://www.telerik.com/blogs/azure-devops-and-telerik-nuget-packages)\n  - [Blog: Announcing Telerik NuGet Keys](https://www.telerik.com/blogs/announcing-nuget-keys)\n\n## CI Systems\n\n| System        | CI/CD file(s) |\n|---------------|------------------|\n| GitHub Actions | [.github/workflows](/.github/workflows) |\n| Azure DevOps (YAML) | [azure-pipelines.yml](https://github.com/LanceMcCarthy/DevOpsExamples/blob/main/azure-pipelines.yml) |\n| Azure DevOps (classic) | click build badge |\n| GitLab CI/CD  | [.gitlab-ci.yml](https://gitlab.com/LanceMcCarthy/DevOpsExamples/-/blob/main/.gitlab-ci.yml) ↗|\n\n## Badges\n\n| Project | GitHub Actions | Azure DevOps | GitLab CI |\n|---------|--------------|----------------|-----------|\n| .NET MAUI | [![MAUI main](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-maui.yml/badge.svg?branch=main)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-maui.yml) | [![Build - CLASSIC](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status/Build%20MAUI)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=72) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| ASP.NET Core | [![Build ASP.NET Core Application](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-aspnetcore.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-aspnetcore.yml) | [![Build Status](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status%2FLanceMcCarthy.DevOpsExamples?branchName=main\u0026jobName=BuildAspNetCoreApp)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=45\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) | \n| ASP.NET Blazor | [![Build Blazor Application](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-blazor.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-blazor.yml) | [![Build Status](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status%2FLanceMcCarthy.DevOpsExamples?branchName=main\u0026jobName=BuildBlazorApp)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=45\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| WPF (`net48`) | [![WPF (.NET Framework)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-wpf.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-wpf.yml) | [![Build - CLASSIC](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status/Build%20WPF%20and%20WinForms)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=46) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| WinForms (`net48`) | [![WinForms (.NET Framework)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-winforms.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-winforms.yml) | [![Build - CLASSIC](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status/Build%20WinForms?branchName=main)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=79\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| Console | [![Console (.NET)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-console.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-console.yml) | [![Build Status AKEYLESS](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status%2FLanceMcCarthy.DevOpsExamples?branchName=main\u0026jobName=BuildConsoleApp_Akeyless)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=45\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| WinUI 3 | [![Build WinUI3 Project](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-winui.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-winui.yml) | | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| Kendo Angular | [![Build Angular](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-angular.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-angular.yml) | [![Build Status](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status%2FLanceMcCarthy.DevOpsExamples?branchName=main\u0026jobName=BuildAngularApp)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=45\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n| ASP.NET AJAX (`net48`) | [![Build AJAX Application](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-ajax.yml/badge.svg)](https://github.com/LanceMcCarthy/DevOpsExamples/actions/workflows/main_build-ajax.yml) | [![Build Status](https://dev.azure.com/lance/DevOps%20Examples/_apis/build/status%2FLanceMcCarthy.DevOpsExamples?branchName=main\u0026jobName=BuildAjaxApp)](https://dev.azure.com/lance/DevOps%20Examples/_build/latest?definitionId=45\u0026branchName=main) | [![Build status](https://gitlab.com/LanceMcCarthy/DevOpsExamples/badges/main/pipeline.svg)](https://gitlab.com/LanceMcCarthy/DevOpsExamples) |\n\n\n### Bonus Notes\n\n- Docker and DockerHub integration:\n    - The `workflows/main_build-aspnetcore.yml` uses a Dockerfile to build and publish a Linux image to DockerHub =\u003e [lancemccarthy/myaspnetcoreapp](https://hub.docker.com/r/lancemccarthy/myaspnetcoreapp).\n        - Ex. `docker run -d  -p 8080:8080 lancemccarthy/myaspnetcoreapp:latest`\n        - Ex. `docker run -d  -p 8080:8080 lancemccarthy/myblazorapp:latest`\n    - For a real-world example, visit [Akeyless Web Target's docker-publish.yml](https://github.com/LanceMcCarthy/akeyless-web-target/blob/main/.github/workflows/docker-publish.yml), which builds and publishes the [lancemccarthy/secretsmocker](https://hub.docker.com/r/lancemccarthy/secretsmocker) container image to Docker Hub.\n        - Ex. `docker run -d  -p 8080:80 lancemccarthy/secretsmocker:latest`\n- Azure DevOps: All statuses are for classic pipelines, except the `Console` project, which uses Azure DevOps YAML pipelines.\n\n## Videos\n\n### Azure DevOps with Telerik NuGet Server\n\nThe following **4 minute** video takes you though all the steps on adding a private NuGet feed as a Service Connection and consuming that service in three different pipeline setups.\n\n[![YouTube tutorial](https://img.youtube.com/vi/rUWU2n6FwgA/0.jpg)](https://www.youtube.com/watch?v=rUWU2n6FwgA)\n\n- [0:09](https://youtu.be/rUWU2n6FwgA?t=9) Add a Service connection to the Telerik server\n- [1:14](https://youtu.be/rUWU2n6FwgA?t=74) Classic pipeline for .NET Core\n- [1:47](https://youtu.be/rUWU2n6FwgA?t=107) Classic .NET Framework pipeline\n- [2:25](https://youtu.be/rUWU2n6FwgA?t=145) YAML pipeline setup for .NET Core\n\n## Tips and Troubleshooting\n\n### GitHub Actions: Using Secrets to Set Environment Variables\n\nA common problem to run into is to think that the environment variable is the same thing as the GitHub Secret (or Azure DevOps pipeline variable). In this demo, I intentionally named the secrets a different name than the environment variable name so that it is easier for you to tell the difference.\n\nHowever, I know that not everyone has the time to watch the video and just copy/paste the YAML instead. This will cause you to hit a roadblock because you missed the part about setting up the GitHub secret, Azure DevOps pipeline variable or . Here is a 2 screenshot crash-course on how to get back on track.\n\nIn your YAML, you probably have done this:\n\n![image](https://user-images.githubusercontent.com/3520532/104634697-f57e0480-566e-11eb-8b84-06fcf3ffe753.png)\n\nThat mean you must also have the secrets in your **Settings** \u003e **Secrets** list\n\n![image](https://user-images.githubusercontent.com/3520532/104634438-9cae6c00-566e-11eb-9a78-79d955247867.png)\n\n\n### Powershell: Adding or Updating Package Source Dynamically\n\n#### Option 1 - Update existing package source\n\nYou could also dynamically update the credentials of a Package Source defined in your nuget.config file This is a good option when you do not want to use a `packageSourceCredentials` section that uses environment variables.\n\n```powershell\n# Updates a source named 'Telerik' in the nuget.config\ndotnet nuget update source \"Telerik\" -s \"https://nuget.telerik.com/v3/index.json\" --configfile \"src/nuget.config\" -u '${{secrets.MyTelerikEmail}}' -p '${{secrets.MyTelerikPassword}}' --store-password-in-clear-text\n```\nThat command will look through the nuget.config for a package source with the key `Telerik` and then add/update the credentials for that source.\n\n#### Option 2 - Add a new package source\n\nThe other approach is a bit simpler because you dont need a custom nuget.config file. Just use the dotnet nuget add source command\n\n```powershell\ndotnet nuget add source 'https://nuget.telerik.com/v3/index.json' -n \"AddedTelerikServer\" -u ${{secrets.MyTelerikEmail}} -p ${{secrets.MyTelerikPassword}} --store-password-in-clear-text\n```\n\n\u003e The `--store-password-in-clear-text` switch is important. It does *not* mean the password is visible, rather it means that you're using the password text and not a custom encrypted variant. For more information, please visit https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file#packagesourcecredentials\n\n### Using Telerik NuGet Keys\n\nYou can use the same approach in the previous section. Everything is exactly the same, except you use `api-key` for the username and the NuGet key for the password.\n\nPlease visit the [Announcing NuGet Keys](https://www.telerik.com/blogs/announcing-nuget-keys) blog post for more details how ot create the key and how to use it.\n\n```powershell\ndotnet nuget update source \"Telerik\" --source \"https://nuget.telerik.com/v3/index.json\" --configfile \"src/nuget.config\" --username 'api-key' --password '${{ secrets.MyNuGetKey }}' --store-password-in-clear-text\n```\n\n\u003e [!CAUTION]\n\u003e Protect your key by storing it in a GitHub Secret, then use the secret's varible name in the command\n\n### Dockerfile: Using Secrets\n\nWhen using a Dockerfile to build a .NET project that uses the Telerik NuGet server, you'll need a safe and secure way to handle your NuGet crednetials and your Telerik License Key. This can be done my mounting a Docker secret.\n\nIn your GitHub Actions workflow, you can define and set docker secrets in the docker build step. Take a look at the following example, we using GitHub secrest to set two docker secrets `telerik-nuget-key=${{secrets.MY_NUGET_KEY}}` and `telerik-license-key=${{secrets.MY_TELERIK_LICENSE_KEY}}`.\n\n```yaml\n    - uses: docker/build-push-action@v3\n      with:\n        secrets: |\n          telerik-nuget-key=${{secrets.MY_NUGET_KEY}}\n          telerik-license-key=${{secrets.MY_TELERIK_LICENSE_KEY}}\n```\n\nNow, inside the Dockerfile's `build` stage, you can mount and use those secrets. See Stage 2 in the following example:\n\n```Dockerfile\n### STAGE 1 ###\nFROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/aspnet:9.0 AS base\nWORKDIR /app\n\n### STAGE 2 ###\nFROM mcr.microsoft.com/dotnet/sdk:9.0 AS build\nWORKDIR /src/MyApp\nCOPY . .\n# 1. Mount the ecret and use it to add the Telerik server as a package source\nRUN --mount=type=secret,id=telerik-nuget-key \\\n    dotnet nuget add source 'https://nuget.telerik.com/v3/index.json' -n \"TelerikNuGetServer\" -u \"api-key\" -p $(cat /run/secrets/telerik-nuget-key) --store-password-in-clear-text\n# 2. Restore NuGet packages\nRUN dotnet restore \"MyBlazorApp.csproj\"\n# 3. Mount the \"telerik-license-key\" secret as an env var and build the project\nRUN --mount=type=secret,id=telerik-license-key \\\n    TELERIK_LICENSE=\"$(cat /run/secrets/telerik-license-key)\" \\\n    dotnet publish \"MyBlazorApp.csproj\" -o /app/publish /p:UseAppHost=false --self-contained false\n\n\n### STAGE 3 ###\n# Build final from base, but copy ONLY THE PUBLISH ARTIFACTS from stage 2\nFROM base AS final\nWORKDIR /app\nCOPY --from=build /app/publish .\nENTRYPOINT [\"dotnet\", \"MyBlazorApp.dll\"]\n```\n\n\u003e [!CAUTION]\n\u003e Only set these sensitive values in the build stage or you risk leaking secrets in the final image. Please [visit the complete Dockerfile](https://github.com/LanceMcCarthy/DevOpsExamples/blob/main/src/AspNetCore/MyAspNetCoreApp/Dockerfile) and [the workflow](https://github.com/LanceMcCarthy/DevOpsExamples/blob/main/.github/workflows/main_build-aspnetcore.yml).\n\n### Telerik License Approaches\n\nDepending on how you're building our code, there are several ways to introduce the Telerik License Key at the right time for the build. Let me show you two; variable and file.\n\n- [Approach 1 - Using an Environment Variable](https://github.com/LanceMcCarthy/DevOpsExamples?tab=readme-ov-file#approach-1---using-a-variable)\n- [Approach 2 - Using a License File](https://github.com/LanceMcCarthy/DevOpsExamples?tab=readme-ov-file#approach-2---using-a-file)\n  - [In a YAML Pipeline](https://github.com/LanceMcCarthy/DevOpsExamples?tab=readme-ov-file#yaml-pipeline)\n  - [In a Classic Pipeline](https://github.com/LanceMcCarthy/DevOpsExamples?tab=readme-ov-file#classic-pipeline)\n\n\n#### Approach 1 - Using a Variable\n\nThis is by far the easiest and safest way. You can use a secret (GitHub Action secret or AzDO Variable secret) and set the `TELERIK_LICENSE` environment variable before the project is compiled.\n\nIn a YAML workflow/pipeline, you can set the environment variable at the beginning of the job or on a step that needs it.\n\nGH Actions\n```yaml\n  - run: dotnet publish MyApp.csproj -o /app/publish /p:UseAppHost=false --no-restore\n    env:\n      TELERIK_LICENSE: ${{secrets.TELERIK_LICENSE_KEY}}\n```\n\nAzure Pipelines YAML\n\n```yaml\n  - powershell: dotnet publish MyApp.csproj -o /app/publish /p:UseAppHost=false --no-restore\n    displayName: 'Build and publish the project'\n    env:\n      TELERIK_LICENSE: $(MY_TELERIK_LICENSE_KEY) # AzDO pipeline secret variable\n```\n\nIf you're using classic pipelines, you can use a pipeline variable:\n\n![Image](https://github.com/user-attachments/assets/bcdcc8c3-8ec7-43af-8452-4bace4e8ee83)\n\n\u003e [!IMPORTANT]\n\u003e License key length - If you are using a Library **Variable Group**, there is a character limit for the variable values. The only way to have a long value in the Variable Group is to link it from Azure KeyVault. If you cannot use Azure KeyVault, then use a normal pipeline variable instead (seen above) or use the Secure File approach instead (see below).\n\n\n#### Approach 2 - Using a File\n\nYou have two options for a file-base option. Set the TELERIK_LICENSE_PATH variable or add a file named **telerik-license.txt** to the project directory. The licensing runtime will do a recursive check from the project directory to root, and then finally %appdata%/telerik/.\n\nOn Azure DevOps, there is a powerful feature called Secure Files. It lets you upload a file and then use it in a pipeline. Go to your Library tab, then select Secure File\n\nAfter you've uploaded the Secure File to your Azure DevOps project, you can use it in a pipeline, liek this:\n\n\u003e [!CAUTION]\n\u003e Never check in the **telerik-license.txt** file with your code and never distr4ibute it with your application/docker image.\n\n##### YAML Pipeline\n\nWith a YAML pipeline, you can use the **DownloadSecureFile@1** task, then use `$(name.secureFilePath)` to reference it. For example:\n\n```yaml\n  - task: DownloadSecureFile@1\n    name: DownloadTelerikLicenseFile # defining the 'name' is important\n    displayName: 'Download Telerik License Key File'\n    inputs:\n      secureFile: 'telerik-license.txt'\n\n  - task: MSBuild@1\n    displayName: 'Build Project'\n    inputs:\n      solution: 'myapp.csproj'\n      platform: Any CPU\n      configuration: Release\n      msbuildArguments: '/p:RestorePackages=false'\n    env:\n      # use the name.secureFilePath value to set the special TELERIK_LICENSE_PATH\n      TELERIK_LICENSE_PATH: $(DownloadTelerikLicenseFile.secureFilePath) \n```\n\n##### Classic Pipeline\n\nWith a classic pipeline, you can use the same `DownloadSecureFile` Task\n\n![Image](https://github.com/user-attachments/assets/8c9f0aa4-0ef8-48a9-9805-b0686db1109c)\n\n\u003e [!IMPORTANT]\n\u003e See the screenshot above. You must set the output variable's name, this is the **reference name** which gets prepended to the `.secureFilePath` output variable.\n\nWith the secure file downloaded to the runner, you have two options again:\n\n- A) Set the TELERIK_LICENSE_PATH variable with the path $(telerik.secureFilePath)\n- or\n- B) Copy the actual license file to a directory you want to use it in.\n\n![Image](https://github.com/user-attachments/assets/0b1fd81f-5ee6-49e1-8ce3-031ed379c1d6)\n\n\u003e [!CAUTION]\n\u003e If you distribute the source code with your artifacts, make sure you delete the copied license.txt file immediately after the build step.\n\nUltimately, there are many routes to take, and you can choose th eone that best suits your CI-CD needs. What is most important is that you protect the key value/file as you'd protect any sensitive secret.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flancemccarthy%2Fdevopsexamples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flancemccarthy%2Fdevopsexamples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flancemccarthy%2Fdevopsexamples/lists"}