# CI/CD

> Build and publish a Windows Forms app with TX Text Control in CI/CD: GitHub Actions on windows-latest, private NuGet feed secrets, artifacts, Azure Pipelines.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Deployment Guide > CI/CD
- **1799 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/ci-cd/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/ci-cd/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/ci-cd/llms-full.txt

---

A pipeline that builds a Windows Forms application with TX Text Control is an ordinary .NET desktop pipeline with two additions: it restores `TXTextControl.TextControl.WinForms.SDK` from a feed that needs credentials, and it publishes the application for the platform it ships for. The restore and the licensing of build servers are covered in the Installation Guide; what follows continues from there, with a complete GitHub Actions workflow that publishes the application as a build artifact.

### What the Build Server Needs

- **A Windows agent.** Text Control's pipelines for Windows Forms and WPF build on a Windows image, such as `windows-latest`.
- **Access to the package.** The package isn't on nuget.org. The pipeline restores it from the Text Control Private NuGet Feed, or from your own feed such as Azure Artifacts, with credentials stored as secrets. [Build Servers](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/licensing/build-servers/llms-full.txt) describes both ways.
- **No license of its own,** under the conditions listed in [License Rules for Build Servers](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/licensing/build-servers/#license-rules-for-build-servers).

### Build and Publish With GitHub Actions

The workflow below restores the package from the private feed, builds the application, publishes it for `win-x64` and uploads the publish folder. It expects three repository secrets: `TEXTCONTROL_FEED_URL` with the feed URL `https://www.textcontrol.com/nuget/v3/index.json`, `TEXTCONTROL_EMAIL` with the email address of a licensed developer, and `TEXTCONTROL_API_TOKEN` with that developer's API token. Save it as *.github/workflows/build.yml*, and replace *MyApp/MyApp.csproj* with the path of your project:

```yaml
name: Build

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]

jobs:
  build:
    runs-on: windows-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup .NET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: 8.0.x

    - name: Create nuget.config
      shell: pwsh
      run: |
        $content = @"
        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
          <packageSources>
            <clear />
            <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
            <add key="TextControl" value="${{ secrets.TEXTCONTROL_FEED_URL }}" />
          </packageSources>
          <packageSourceCredentials>
            <TextControl>
              <add key="Username" value="${{ secrets.TEXTCONTROL_EMAIL }}" />
              <add key="ClearTextPassword" value="${{ secrets.TEXTCONTROL_API_TOKEN }}" />
            </TextControl>
          </packageSourceCredentials>
        </configuration>
        "@
        Set-Content -Path "nuget.config" -Value $content -Encoding utf8

    - name: Build
      run: dotnet build MyApp/MyApp.csproj -c Release

    - name: Publish
      run: dotnet publish MyApp/MyApp.csproj -c Release -r win-x64 --self-contained false -o publish

    - name: Upload artifact
      uses: actions/upload-artifact@v4
      with:
        name: myapp-win-x64
        path: publish
```

The workflow works as follows:

- **`runs-on: windows-latest`** builds on a Windows agent.
- **`dotnet-version: 8.0.x`** installs the .NET SDK. Use the version your project targets, such as `10.0.x` for .NET 10.
- **Create nuget.config** writes the file into the root of the repository from the secrets, so the credentials never reach the repository or the log. The package it restores contains your license, so the build needs no further license step.
- **Publish** copies the application, the assemblies of TX Text Control and the 64-bit native libraries into *publish*. For a 32-bit application, use `-r win-x86`.
- **Upload artifact** stores the publish folder as the result of the run. The folder contains no license file and no *nuget.config*.

The blog article [Building a TX Text Control Project with GitHub Actions and the Text Control NuGet Feed](https://www.textcontrol.com/blog/2026/02/09/building-a-tx-text-control-project-with-github-actions-and-the-text-control-nuget-feed/) sets up the repository and the secrets step by step and adds a test step.

### Build With Azure Pipelines

Azure Pipelines builds the application on a `windows-latest` agent as well. Text Control's pipeline for Windows Forms and WPF restores the package from an Azure Artifacts feed with the `NuGetCommand@2` task and builds with `VSBuild@1`; [Restore the Package From Your Own Feed](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/licensing/build-servers/#restore-the-package-from-your-own-feed) describes it, and the blog article [Azure Pipelines with TX Text Control .NET for WPF and Windows Forms 32.0 with Azure DevOps and Artifacts](https://www.textcontrol.com/blog/2024/01/05/azure-pipelines-with-tx-text-control-net-for-wpf-and-windows-forms-320-with-azure-devops-and-artifacts/) shows the complete pipeline. To publish, run the `dotnet publish` command of the previous section in a script step after the restore.

### .NET Framework Applications

A .NET Framework project gets its license from *licenses.licx* and the license compiler, which needs the assemblies of the TX Text Control setup. On a hosted agent, where the setup can't be installed, compile the license once on a development machine and add it to the project as an embedded resource, as [.NET Framework Projects](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/licensing/build-servers/#net-framework-projects) describes. The files to deploy are then collected as described in [Deploying .NET Framework Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/dotnet-framework/llms-full.txt).

### Keep the Versions Consistent

Reference one fixed version of `TXTextControl.TextControl.WinForms.SDK`, such as 34.0.5, so that every developer and every build restores the same package. Update the version in the project when a service pack is released, as [Installing and Updating Packages](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/nuget/install-update/#update-to-a-new-service-pack) describes.

### Next Steps

- [Build Servers](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/licensing/build-servers/llms-full.txt): licensing and package restore on build servers.
- [Configuring Package Sources](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/installation/nuget/sources/llms-full.txt): the private feed and *nuget.config*.
- [Publishing .NET Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/dotnet/llms-full.txt): what the publish folder contains.

---

## Nearby

- **Previous:** [MSIX Packaging and Microsoft Store Deployment](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/deployment/msix/llms-full.txt)
- **Next:** [Security](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/security/llms-full.txt)
