Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions .github/actions/validate-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Validate version
description: Validate that provided version can be released
inputs:
version:
description: Full version
required: true
outputs:
major:
description: Major version
value: ${{ steps.validate.outputs.major }}
minor:
description: Minor version
value: ${{ steps.validate.outputs.minor }}
patch:
description: Patch version
value: ${{ steps.validate.outputs.patch }}
prerelease:
description: Prerelease label
value: ${{ steps.validate.outputs.prerelease }}
container-tags:
description: Tags to be added for container releases (comma-separated)
value: ${{ steps.validate.outputs.container-tags }}
latest:
description: Evaluates to `true` if the version should be flagged as the new latest version
value: ${{ steps.validate.outputs.latest }}
runs:
using: composite
steps:
- name: Validate versions
id: validate
shell: pwsh
run: |
$version = "${{ inputs.version }}"

Write-Output "Received version: $version"
$isMatch = $version -match '^(?<Major>\d+)\.(?<Minor>\d+)\.(?<Patch>\d+)(-(?<PrereleaseLabel>[\w\-\.]+))?$'
if ( -not $isMatch)
{
throw "Invalid version $version"
exit 1
}

Write-Output "Version $version is valid."

$major = [int]$Matches.Major
$minor = [int]$Matches.Minor
$patch = [int]$Matches.Patch
$prereleaseLabel = $Matches.PrereleaseLabel
$isPrerelease = -not -not $prereleaseLabel

echo "major=$major" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append
echo "minor=$minor" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append
echo "patch=$patch" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append
echo "prerelease=$prereleaseLabel" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append

# Get highest-versioned releases
$releases = Invoke-WebRequest -Uri https://api.github.com/repos/particular/ServiceControl/releases -UseBasicParsing |
ConvertFrom-Json -ErrorAction Stop
$releasedVersions = $releases |
where Draft -eq $false |
where Prerelease -eq $false |
where Name -match '^\d+\.\d+\.\d+$' | # Ignore prerelease tags
select -ExpandProperty tag_name

$latestVersion = $releasedVersions |
Sort-Object { [System.Version]$_ } -Descending |
select -First 1
Write-Output "Latest released version on GitHub = $latestVersion"

$latestForMajor = $releasedVersions |
where { ([System.Version]$_).Major -eq $major } |
Sort-Object { [System.Version]$_ } -Descending |
select -First 1
Write-Output "Latest released v$major version on GitHub = $latestForMajor"

$latestForMinor = $releasedVersions |
where { ([System.Version]$_).Major -eq $major -and ([System.Version]$_).Minor -eq $minor } |
Sort-Object { [System.Version]$_ } -Descending |
select -First 1
Write-Output "Latest released v$major.$minor version on GitHub = $latestForMinor"

$isLatest = $false
if ( -not $isPrerelease ) {
$vNew = [System.Version]$version
$vPrev = [System.Version]$latestVersion
$vPrevForMajor = [System.Version]$latestForMajor
$vPrevForMinor = [System.Version]$latestForMinor

if ($vNew -ge $vPrev) {
$isLatest = $true
}

# For new majors, vNew < null evaluates to false, no exception thrown
# Logic would not be appropriate if support policy allows backports to previous minors
if ($vNew -lt $vPrevForMajor) {
throw "Releasing a version $version that is not the latest version for the major would break container tagging and is not supported. (Latest v$major version is $latestForMajor)"
}

# For new minors, vNew < null evaluates to false, no exception thrown
if ($vNew -lt $vPrevForMinor) {
throw "Releasing a version $version that is not the latest version for the minor would break container tagging and is not supported. (Latest v$major.$minor version is $latestForMinor)"
}
}

Write-Output "Major = $major, Minor = $minor, Patch = $patch, PrereleaseLabel = $prereleaseLabel, IsPrerelease = $isPrerelease, IsLatest = $isLatest"

Write-Output "Determining container tags..."
$tags = @($version)

if ( -not $isPrerelease ) {
$tags += "$major.$minor"
$tags += "$major"
if ($isLatest) {
$tags += 'latest'
}
}

Write-Output "Tags to apply:"
$tags | ForEach-Object { Write-Output " * '$_'" }

$tagsDelimited = $tags -Join ','
echo "container-tags=$tagsDelimited" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append
echo "latest=$($isLatest.ToString().ToLower())" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf-8 -Append
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI
on:
push:
branches:
- master
- release-*
pull_request:
workflow_dispatch:
env:
DOTNET_NOLOGO: true
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Check for secrets
env:
SECRETS_AVAILABLE: ${{ secrets.SECRETS_AVAILABLE }}
shell: pwsh
run: exit $(If ($env:SECRETS_AVAILABLE -eq 'true') { 0 } Else { 1 })
- name: Checkout
uses: actions/checkout@v4.1.7
with:
fetch-depth: 0
submodules: true
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4.0.1
with:
dotnet-version: 8.0.x
- name: Build
run: dotnet build src --configuration Release -graph --property:WindowsSelfContained=true
- name: Run tests
uses: Particular/run-tests-action@v1.7.0
- name: Test publish arm64
run: dotnet publish --os linux --arch arm64 src/ServiceControl.Connector.MassTransit.Host/ServiceControl.Connector.MassTransit.Host.csproj --configuration Release --graph
- name: Test publish amd64
run: dotnet publish --os linux --arch amd64 src/ServiceControl.Connector.MassTransit.Host/ServiceControl.Connector.MassTransit.Host.csproj --configuration Release --graph
21 changes: 21 additions & 0 deletions .github/workflows/clean-ghcr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Cleanup GitHub Container Registry
on:
schedule:
- cron: "0 0 * * *" # Midnight UTC daily
workflow_dispatch:
jobs:
clean:
name: Delete unused containers
runs-on: ubuntu-latest
steps:
- name: Clean up images
uses: snok/container-retention-policy@v3.0.0
with:
image-names: servicecontrol-connector-masstransit
image-tags: pr-*, *-alpha.*
tag-selection: both
cut-off: 2w
timestamp-to-use: updated_at
account: particular
token: ${{ secrets.GITHUB_TOKEN }}
dry-run: false
51 changes: 51 additions & 0 deletions .github/workflows/push-container-images.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Push container images
on:
workflow_dispatch:
inputs:
version:
description: Full version of container image to push. Normally, this should exactly match the tag name.
required: true
type: string
jobs:
push:
runs-on: ubuntu-latest
name: Push
defaults:
run:
shell: pwsh
steps:
- name: Checkout
uses: actions/checkout@v4.1.7
- name: Validate build version
id: validate
uses: ./.github/actions/validate-version
with:
version: ${{ inputs.version }}
- name: Log in to GitHub container registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Login to Docker Hub
uses: docker/login-action@v3.3.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Publish to Docker Hub
run: |
$tags = "${{ steps.validate.outputs.container-tags }}" -Split ','
$sourceTag = "${{ inputs.version }}"

foreach ($tag in $tags)
{
Write-Output "::group::Pushing servicecontrol-connector-masstransit:$($tag)"
$cmd = "docker buildx imagetools create --tag particular/servicecontrol-connector-masstransit:$($tag) ghcr.io/particular/servicecontrol-connector-masstransit:$($sourceTag)"
Write-Output "Command: $cmd"
Invoke-Expression $cmd
Write-Output "::endgroup::"
}
- name: Update Docker Hub Description
if: ${{ steps.validate.outputs.latest == 'true' }}
uses: peter-evans/dockerhub-description@v4.0.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: particular/servicecontrol-connector-masstransit
readme-filepath: ./Container-README.md
76 changes: 76 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Release
on:
push:
branches:
- master
- release-*
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-*'
pull_request:
workflow_dispatch:
env:
DOTNET_NOLOGO: true
jobs:
container:
if: ${{ github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-22.04
Comment thread
ramonsmits marked this conversation as resolved.
defaults:
run:
shell: bash
steps:
- name: Check for secrets
env:
SECRETS_AVAILABLE: ${{ secrets.SECRETS_AVAILABLE }}
shell: pwsh
run: exit $(If ($env:SECRETS_AVAILABLE -eq 'true') { 0 } Else { 1 })
- name: Checkout
uses: actions/checkout@v4.1.7
with:
fetch-depth: 0
submodules: true
- name: Install MinVer CLI
run: dotnet tool install --global minver-cli
- name: Determine versions
shell: pwsh
run: |
# Read settings from Custom.Build.props
[xml]$xml = Get-Content ./src/Custom.Build.props
$minMajorMinor = $xml.selectNodes('/Project/PropertyGroup/MinVerMinimumMajorMinor').InnerText
$autoIncrement = $xml.selectNodes('/Project/PropertyGroup/MinVerAutoIncrement').InnerText
echo "MinVerMinimumMajorMinor=$minMajorMinor, MinVerAutoIncrement=$autoIncrement"
if (-not ($minMajorMinor -and $autoIncrement)) {
throw "Missing MinVer settings in Custom.Build.props"
}

# Execute MinVer
echo "MinVerVersion=$(minver --minimum-major-minor $minMajorMinor --auto-increment $autoIncrement)" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append
- name: Validate build version
if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }}
uses: ./.github/actions/validate-version
with:
version: ${{ env.MinVerVersion }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.6.1
- name: Log in to GitHub container registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build & inspect image
env:
TAG_NAME: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || env.MinVerVersion }}
run: |
docker buildx build --push --tag ghcr.io/particular/servicecontrol-connector-masstransit:${{ env.TAG_NAME }} \
--file src/ServiceControl.Connector.MassTransit.Host/Dockerfile \
--build-arg VERSION=${{ env.MinVerVersion }} \
--annotation "index:org.opencontainers.image.title=ServiceControl.Connector.MassTransit" \
--annotation "index:org.opencontainers.image.description=ServiceControl MassTransit connector" \
--annotation "index:org.opencontainers.image.created=$(date '+%FT%TZ')" \
--annotation "index:org.opencontainers.image.revision=${{ github.sha }}" \
--annotation "index:org.opencontainers.image.authors=Particular Software" \
--annotation "index:org.opencontainers.image.vendor=Particular Software" \
--annotation "index:org.opencontainers.image.version=${{ env.MinVerVersion }}" \
--annotation "index:org.opencontainers.image.source=https://github.com/Particular/ServiceControl.Connector.MassTransit/tree/${{ github.sha }}" \
--annotation "index:org.opencontainers.image.url=https://hub.docker.com/r/particular/servicecontrol-connector-masstransit" \
--annotation "index:org.opencontainers.image.documentation=https://docs.particular.net/servicecontrol/" \
--annotation "index:org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0" \
--platform linux/arm64,linux/amd64 .
docker buildx imagetools inspect ghcr.io/particular/servicecontrol-connector-masstransit:${{ env.TAG_NAME }}
3 changes: 3 additions & 0 deletions Container-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Particular Software ServiceControl Masstransit connector

This document describes basic usage and information related `particular/servicecontrol-connector-masstransit` image. It is a component that is part of the Particular Platform. Complete documentation of the ServiceControl container images can be found in the [Particular Software ServiceControl documentation](https://docs.particular.net/servicecontrol).
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ServiceControl.Connector.MassTransit

A ServiceControl container image that adds support for processing [MassTransit](https://masstransit.io/) failures with the Particular Platform. Making all its recoverability feature for managing message processing failures like (group) retrying, message editing and failed message inspection available to the MassTransit community.

## Installation

The connector is container image which is Linux Arm64 and Linux Amd64 compatible. The image is available at https://hub.docker.com/r/particular/servicecontrol-connector-masstransit . Please read the docker hub README for more information on available tags and container usage.

## Local container creation

To locally build and test the container run the following in any shell:

```shell
git submodule init
git submodule update
docker buildx build --file src/ServiceControl.Connector.MassTransit.Host/Dockerfile --platform linux/arm64,linux/amd64 --tag particular/servicecontrol-connector-masstransit:latest .
```
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
name: servicecontrol-connector-sample
x-transport: &transport-env
env_file: "rabbit.env"

services:
service-control-db:
container_name: "servicecontrol-db"
image: "particular/servicecontrol-ravendb:latest"
ports:
- "8080:8080"
volumes:
- C:\servicecontrol\db:/opt/RavenDB/Server/RavenData
- db:/opt/RavenDB/Server/RavenData
servicecontrol-setup:
depends_on:
- service-control-db
container_name: "servicecontrol-setup"
image: "particular/servicecontrol:latest"
command: "--setup"
ports:
- "33333:33333"
<< : [*transport-env]
service-control:
depends_on:
Expand All @@ -27,14 +24,13 @@ services:
container_name: "servicecontrol"
image: "particular/servicecontrol:latest"
ports:
- "33333:33333"
- 33333:33333
<< : [*transport-env]
masstransit-connector:
depends_on:
- service-control
container_name: "masstransit-connector"
image: "servicecontrol-connector-masstransit:latest"
pull_policy: if_not_present
image: "particular/servicecontrol-connector-masstransit:latest"
<< : [*transport-env]
service-pulse:
depends_on:
Expand All @@ -45,3 +41,6 @@ services:
- 9090:9090
environment:
- SERVICECONTROL_URL=http://servicecontrol:33333/api/

volumes:
db:
File renamed without changes.
File renamed without changes.
3 changes: 0 additions & 3 deletions make.bat

This file was deleted.

Loading