Skip to content

Commit

Permalink
Set up NuGet packages and related CI infrastructure.
Browse files Browse the repository at this point in the history
Related changes:
* Updated to ClangSharp.Pathogen 0.0.0 (which is published on NuGet.org.)
* Biohazrd is no longer marked as x64-only.
  * This restriction was in place primarily because ClangSharp.Pathogen only provides x64 matrix runtimes. While this is still true, nothing about Biohazrd its self is x64-only, and advanced users can manually provide their own libclang-pathogen for their platform as necessary.

Closes #214
  • Loading branch information
PathogenDavid committed Sep 7, 2021
1 parent ad822e7 commit 20e2099
Show file tree
Hide file tree
Showing 15 changed files with 390 additions and 14 deletions.
159 changes: 155 additions & 4 deletions .github/workflows/Biohazrd.yml
Original file line number Diff line number Diff line change
@@ -1,49 +1,200 @@
name: Biohazrd
on:
push:
# This prevents tag pushes from triggering this workflow
branches: ['*']
pull_request:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: "Version"
default: ""
will_publish_packages:
description: "Publish packages?"
default: "false"
env:
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
ContinuousIntegrationBuild: true
# This URL will be added to the restore sources if it isn't the official NuGet.org
# (This is mainly intended to allow using the NuGet.org test servers to test CI in forks.)
CiNuGetApiUrl: ${{secrets.NUGET_API_URL}}
jobs:
build-and-test:
strategy:
fail-fast: false
matrix:
os: ['windows-latest', 'ubuntu-latest']
platform:
- name: Windows
architecture: x64
runs-on: windows-latest
- name: Linux
architecture: x64
runs-on: ubuntu-latest
configuration: ['Debug', 'Release']
name: Build and Test ${{matrix.configuration}} ${{matrix.os}}
runs-on: ${{matrix.os}}
include:
# Linux Release x64 builds create packages (if applicable)
- platform:
runs-on: ubuntu-latest
configuration: Release
create-packages: true
name: Build and Test ${{matrix.platform.name}} ${{matrix.platform.architecture}} ${{matrix.configuration}}
runs-on: ${{matrix.platform.runs-on}}
steps:
# ----------------------------------------------------------------------- Checkout
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive

# ----------------------------------------------------------------------- Setup Python
- name: Setup Python 3.8
uses: actions/setup-python@v2
with:
python-version: '3.8'

# ----------------------------------------------------------------------- Setup .NET
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x

# ----------------------------------------------------------------------- Configure versioning
- name: Configure build
id: configuration
run: python .github/workflows/configure-build.py
env:
github_event_name: ${{github.event_name}}
github_ref: ${{github.ref}}
github_run_number: ${{github.run_number}}
release_version: ${{github.event.release.tag_name}}
workflow_dispatch_version: ${{github.event.inputs.version}}
workflow_dispatch_will_publish_packages: ${{github.event.inputs.will_publish_packages}}

# ----------------------------------------------------------------------- Build
- name: Restore
run: dotnet restore

- name: Build
run: dotnet build --no-restore --configuration ${{matrix.configuration}}

- name: Pack
id: pack
if: matrix.create-packages
run: dotnet pack --no-build --configuration ${{matrix.configuration}}

# ----------------------------------------------------------------------- Test
- name: Test
run: dotnet test --no-restore --no-build --configuration ${{matrix.configuration}} --verbosity normal

# ----------------------------------------------------------------------- Collect Artifacts
- name: Collect NuGet Packages
uses: actions/upload-artifact@v2
# We always want to collect packages when they were produced
if: steps.pack.outcome == 'success' && always()
with:
name: Packages
if-no-files-found: error
path: packages/**

publish-packages-github:
name: Publish to GitHub
runs-on: ubuntu-latest
needs: build-and-test
# Pushes always publish CI packages (configure-build.py will add the branch name to the version string for branches besides main)
# Published releases always publish packages
# A manual workflow only publishes packages if explicitly enabled
if: github.event_name == 'push' || github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.will_publish_packages == 'true')
steps:
# ----------------------------------------------------------------------- Setup .NET
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x

# ----------------------------------------------------------------------- Download built packages
- name: Download built packages
uses: actions/download-artifact@v2
with:
name: Packages

# ----------------------------------------------------------------------- Upload release assets
- name: Upload release assets
if: github.event_name == 'release'
uses: actions/github-script@v4
with:
user-agent: actions/github-script for ${{github.repository}}
script: |
const fs = require('fs').promises;
const path = require('path');
const upload_url = context.payload.release.upload_url;
if (!upload_url) {
throw "Missing release asset upload URL!";
}
for (let filePath of await fs.readdir('.')) {
const fileExtension = path.extname(filePath);
if (fileExtension != '.nupkg' && fileExtension != '.snupkg') {
continue;
}
console.log(`Uploading '${filePath}'`);
const contentLength = (await fs.stat(filePath)).size;
const fileContents = await fs.readFile(filePath);
await github.repos.uploadReleaseAsset({
url: upload_url,
headers: {
'content-type': 'application/octet-stream',
'content-length': contentLength
},
name: path.basename(filePath),
data: fileContents
});
}
# ----------------------------------------------------------------------- Push to GitHub Packages
- name: Push to GitHub Packages
run: dotnet nuget push "*.nupkg" --skip-duplicate --no-symbols true --api-key ${{secrets.GITHUB_TOKEN}} --source https://nuget.pkg.github.com/${{github.repository_owner}}
env:
# This is a workaround for https://github.com/NuGet/Home/issues/9775
DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER: 0

publish-packages-nuget-org:
name: Publish to NuGet.org
runs-on: ubuntu-latest
needs: build-and-test
environment: NuGet.org
# Release builds always publish packages to NuGet.org
# Workflow dispatch builds will only publish packages if enabled and an explicit version number is given
# Make sure this logic matches configure-build.py to ensure we don't accidentally depend on sibling CI pre-release packages
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.will_publish_packages == 'true' && github.event.inputs.version != '')
steps:
# ----------------------------------------------------------------------- Setup .NET
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 5.0.x

# ----------------------------------------------------------------------- Download built packages
- name: Download built packages
uses: actions/download-artifact@v2
with:
name: Packages

# ----------------------------------------------------------------------- Push to NuGet.org
- name: Push to NuGet.org
run: dotnet nuget push "*.nupkg" --api-key ${{secrets.NUGET_API_KEY}} --source ${{secrets.NUGET_API_URL}}
env:
# This is a workaround for https://github.com/NuGet/Home/issues/9775
DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER: 0

send-ci-failure-notification:
name: Send CI Failure Notification
needs: build-and-test
needs: [build-and-test, publish-packages-github, publish-packages-nuget-org]
if: failure() && github.event_name != 'pull_request'
continue-on-error: true
runs-on: ubuntu-latest
Expand Down
88 changes: 88 additions & 0 deletions .github/workflows/configure-build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env python3
import os
import re

import gha

#==================================================================================================
# Get inputs
#==================================================================================================
def get_environment_variable(name):
ret = os.getenv(name)

if ret is None:
gha.print_error(f"Missing required parameter '{name}'")

if (ret == ''):
return None

return ret

github_event_name = get_environment_variable('github_event_name')
github_run_number = get_environment_variable('github_run_number')
github_ref = get_environment_variable('github_ref')

#==================================================================================================
# Determine build settings
#==================================================================================================

# For GitHub refs besides main, include the branch/tag name in the default version string
ref_part = ''
if github_ref != 'refs/heads/main':
ref = github_ref

# Strip the ref prefix
branch_prefix = 'refs/heads/'
tag_prefix = 'refs/tags/'
if ref.startswith(branch_prefix):
ref = ref[len(branch_prefix):]
elif ref.startswith(tag_prefix):
ref = f'tag-{ref[len(tag_prefix):]}'

# Replace illegal characters with dashes
ref = re.sub('[^0-9A-Za-z-]', '-', ref)

# Make the ref part
ref_part = f'-{ref}'

# Build the default version string
version = f'0.0.0{ref_part}-ci{github_run_number}'
is_for_release = False

# Handle non-default version strings
# Make sure logic relating to is_for_release matches the publish-packages-nuget-org in the workflow
if github_event_name == 'release':
version = get_environment_variable('release_version')
is_for_release = True
elif github_event_name == 'workflow_dispatch':
workflow_dispatch_version = get_environment_variable('workflow_dispatch_version')
workflow_dispatch_will_publish_packages = get_environment_variable('workflow_dispatch_will_publish_packages')

if workflow_dispatch_version is not None:
version = workflow_dispatch_version

if workflow_dispatch_will_publish_packages.lower() == 'true':
is_for_release = True

# Trim leading v off of version if present
if version.startswith('v'):
version = version[1:]

# Validate the version number
if not re.match('^\d+\.\d+\.\d+(-[0-9a-zA-Z.-]+)?$', version):
gha.print_error(f"'{version}' is not a valid semver version!")

# If there are any errors at this point, make sure we exit with an error code
gha.fail_if_errors()

#==================================================================================================
# Emit MSBuild properties
#==================================================================================================
print(f"Configuring build environment to build{' and release' if is_for_release else ''} version {version}")
gha.set_environment_variable('CiBuildVersion', version)
gha.set_environment_variable('CiIsForRelease', str(is_for_release).lower())

#==================================================================================================
# Final check to exit with an error code if any errors were printed
#==================================================================================================
gha.fail_if_errors()
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vs/
bin/
obj/
/packages/
29 changes: 29 additions & 0 deletions Biohazrd.AllInOne/Biohazrd.AllInOne.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>

<!--
This package is just a convenience package which brings in all the other components of Biohazrd.
It does not contain code.
-->
<PackageId>Biohazrd</PackageId>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IncludeSymbols>false</IncludeSymbols>

<!--
This warning basically happens because this package has no assemblies but does have dependencies
https://github.com/NuGet/Home/issues/8583
-->
<NoWarn>$(NoWarn);NU5128</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Biohazrd.CSharp\Biohazrd.CSharp.csproj" />
<ProjectReference Include="..\Biohazrd.OutputGeneration\Biohazrd.OutputGeneration.csproj" />
<ProjectReference Include="..\Biohazrd.Transformation\Biohazrd.Transformation.csproj" />
<ProjectReference Include="..\Biohazrd.Utilities\Biohazrd.Utilities.csproj" />
<ProjectReference Include="..\Biohazrd\Biohazrd.csproj" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions Biohazrd.CSharp/Biohazrd.CSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageDescription>This package provides transformations and binding generation for C#.</PackageDescription>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Biohazrd.OutputGeneration/Biohazrd.OutputGeneration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageDescription>This package provides language-agnostic functionality for writing out code and other files.</PackageDescription>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Biohazrd.Transformation/Biohazrd.Transformation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageDescription>This package provides language-agnostic functionality for manipulating declaration trees.</PackageDescription>
</PropertyGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Biohazrd.Utilities/Biohazrd.Utilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageDescription>This package provides various language-agnostic helpers for Biohazrd generators.</PackageDescription>
</PropertyGroup>

<ItemGroup>
Expand Down
12 changes: 10 additions & 2 deletions Biohazrd.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
# Visual Studio Version 17
VisualStudioVersion = 17.0.31612.314
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A8649210-1355-403A-8B2D-45BD759B1B32}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -21,6 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tooling", "tooling", "{09A8
ProjectSection(SolutionItems) = preProject
tooling\Common.csproj.props = tooling\Common.csproj.props
tooling\Common.csproj.targets = tooling\Common.csproj.targets
tooling\Common.props = tooling\Common.props
tooling\Common.targets = tooling\Common.targets
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biohazrd.Utilities", "Biohazrd.Utilities\Biohazrd.Utilities.csproj", "{12BCC25F-9712-4223-8E34-50B7C060D8E2}"
Expand All @@ -41,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biohazrd.CSharp.Tests", "Te
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Biohazrd.OutputGeneration.Tests", "Tests\Biohazrd.OutputGeneration.Tests\Biohazrd.OutputGeneration.Tests.csproj", "{00E42A88-A883-4C43-BE2E-8A241A32EDA9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Biohazrd.AllInOne", "Biohazrd.AllInOne\Biohazrd.AllInOne.csproj", "{093ABF1F-E8E2-4E24-BCEA-845255E5BC5F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -87,6 +91,10 @@ Global
{00E42A88-A883-4C43-BE2E-8A241A32EDA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00E42A88-A883-4C43-BE2E-8A241A32EDA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00E42A88-A883-4C43-BE2E-8A241A32EDA9}.Release|Any CPU.Build.0 = Release|Any CPU
{093ABF1F-E8E2-4E24-BCEA-845255E5BC5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{093ABF1F-E8E2-4E24-BCEA-845255E5BC5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{093ABF1F-E8E2-4E24-BCEA-845255E5BC5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{093ABF1F-E8E2-4E24-BCEA-845255E5BC5F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 20e2099

Please sign in to comment.