Skip to Content
New release 12 available 🎉

AppVeyor

Obfuscate on AppVeyor by hosting the Babel Obfuscator NuGet package on your AppVeyor account feed and passing the license through a secure variable.

AppVeyor builds the solution with the .NET SDK, and the Babel.Obfuscator package adds the Babel task to that build. As with any other build server, the work is limited to two things: letting the agent reach the private feed that holds the package, and giving Babel a license without writing it into the repository.

The sample used on this page is a small console application:

git clone https://github.com/babelfornet/appveyor-integration.git

Upload the Package to the AppVeyor Feed

Every AppVeyor account has its own NuGet feed. From Account Settings → NuGet, copy the feed URL and the API key, then push the package:

dotnet nuget push Babel.Obfuscator.12.0.0.nupkg \ --api-key APPVEYOR_API_KEY \ --source https://ci.appveyor.com/nuget/ACCOUNT/api/v2/package

The account feed is private, but it is the only thing standing between the package and the internet. Never push Babel.Obfuscator to nuget.org or to any feed outside your organisation.

Register the same feed as a package source so the solution restores identically on a developer machine and on the build agent:

NuGet.config
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <clear /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="appveyor" value="https://ci.appveyor.com/nuget/ACCOUNT/api/v2" /> </packageSources> </configuration>

Do not put the feed credentials in this file, and do not pass them on a nuget sources add command line in appveyor.yml. Both end up committed, and a password in a public repository is a password that has been read. Use AppVeyor’s encrypted variables, as below.

Encrypt the feed password with Account Settings → Encrypt YAML, then reference the encrypted value from the build configuration. AppVeyor decrypts it only for builds of your own repository, and never for pull requests from forks.

Reference the Package

AppVeyorIntegration.csproj
<ItemGroup> <PackageReference Include="Babel.Obfuscator" Version="12.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> </ItemGroup>

Referencing the package is all it takes: the Babel task is injected into the build and obfuscates the project’s output assembly. Building locally already produces obfuscated output, and the Babel log appears in the build output — which is the right moment to check the configuration, before involving the build server at all.

Supply the License

Add the license key as a secure variable in Settings → Environment, named BABEL_LICENSE, then read it from the project file:

AppVeyorIntegration.csproj
<PropertyGroup Condition="'$(BABEL_LICENSE)' != ''"> <BabelLicense>$(BABEL_LICENSE)</BabelLicense> </PropertyGroup>

The condition keeps developer machines working unchanged: with the variable unset, Babel falls back to the babel.licenses file found in the project folder or a parent folder. BabelLicense also accepts a floating license user key written as floating:<user key>, which is the better choice when several build agents share one license. See Package Setup.

Adding babel.licenses to the repository, as older guides suggested, exposes the license to anyone who can read or fork it. Deleting the file later does not undo the exposure: the blob remains reachable in every fork and in the repository’s own history.

The Build Configuration

appveyor.yml at the root of the repository replaces whatever is configured in the AppVeyor UI:

appveyor.yml
version: '1.0.{build}' image: Visual Studio 2022 branches: only: - main configuration: Release environment: feed_user: ACCOUNT feed_password: secure: <paste the value produced by Encrypt YAML> install: - ps: dotnet nuget update source appveyor --username $env:feed_user --password $env:feed_password --store-password-in-clear-text before_build: - ps: dotnet restore AppVeyorIntegration.sln build_script: - ps: dotnet build AppVeyorIntegration.sln --configuration $env:CONFIGURATION --no-restore artifacts: - path: AppVeyorIntegration\bin\$(configuration)\net10.0 name: Build_$(configuration)_$(appveyor_build_version) type: zip

The Visual Studio 2022 image ships current .NET SDKs; add a dotnet-install step only if you need an SDK the image does not carry. Obfuscation happens inside dotnet build, so there is no Babel step to add and a licensing failure fails the build.

The artifacts block collects the build output into a zip published on the Artifacts tab, so you can download the obfuscated assembly and inspect it.

--store-password-in-clear-text writes the feed password into the agent’s NuGet.config. That is acceptable on a disposable build VM, which is destroyed when the build ends, but it is the reason this command must never be run on a developer machine.

Configure the Obfuscation

Babel settings are MSBuild properties, applied per configuration so that debugging stays untouched:

AppVeyorIntegration.csproj
<PropertyGroup Condition="'$(Configuration)' == 'Debug'"> <BabelEnabled>false</BabelEnabled> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)' == 'Release'"> <StringEncryption>stream</StringEncryption> <ControlFlowObfuscation>if=on;goto=on;switch=on;case=on;call=on</ControlFlowObfuscation> <ControlFlowIterations>3</ControlFlowIterations> </PropertyGroup>

The full set is in Package Reference; Configuring Obfuscation covers what each one does. When a whole-assembly setting is too blunt, an obfuscation rules file narrows it down to the types and members that matter.

Verifying the Result

Download the artifact and confirm the assembly is obfuscated instead of assuming it — the Detecting Babel Obfuscation example automates that check, and running it in the build turns a silently unobfuscated release into a failed build.

Last updated on