Skip to content
Merged
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Please ADD ALL Changes to the UNRELEASED SECTION and not a specific release
- Guard against IndexOutOfRangeException when Branches list is empty in GithubStatusNotificationHandler
- Fixed CS0433 ambiguous xunit type conflict in test projects caused by FunFair.Test.Common now depending on the AOT-flavoured xunit v3 packages, by switching test projects to the matching xunit.v3.aot.mtp-v2 runner package
- Added missing IncludeAssets on NuGet package references required by FunFair.BuildCheck
- Resolved cfn-lint W1030 warning on the TaskRoleArn CloudFormation property by only setting it when a TaskRole is provided
- Added missing build;buildTransitive IncludeAssets on Serilog package reference required by FunFair.BuildCheck
- CloudFormation task settings now live in Mappings so every deploy applies them, reducing ECS task memory from 4 GB to 1 GB
Comment thread
credfeto marked this conversation as resolved.
### Changed
- Dependencies - Updated NSubstitute.Analyzers.CSharp to 1.0.17
- Switched to use minimal APIs
Expand Down
33 changes: 33 additions & 0 deletions COVERAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Coverage

Generated by the AI Coverage phase. Do not edit by hand.

## .NET

| Project | Line Coverage |
| --- | --- |
| BuildBot | n/a (no instrumented lines) |
| BuildBot.CloudFormation | 100.0% |
| BuildBot.Discord | 96.8% |
| BuildBot.GitHub | 100.0% |
| BuildBot.Health | 100.0% |
| BuildBot.Json | 100.0% |
| BuildBot.ServiceModel | 100.0% |
| BuildBot.Watchtower | 100.0% |
| **Overall (.NET)** | **99.0%** |

## Node

n/a (no code)

## Python

n/a (no code)

## Shell

excluded

---

Captured at commit `ea570db40d30284e19e2944d3301d0d2c1ac4a9f` on 2026-10-13.
144 changes: 59 additions & 85 deletions cloudformation.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
"ApplicationVersion": {
"Type": "String"
},
"ECSClusterName": {
"Type": "String",
"Default": "DiscordBots"
},
"SecurityGroupIDs": {
"Type": "CommaDelimitedList",
"Default": "sg-e3e65a9a,sg-0272027302777cb4d"
Expand All @@ -27,65 +23,36 @@
"Type": "String",
"Default": "vpc-ad3bd9ca"
},
"LoadBalancerArn": {
"Type": "String",
"Default": "arn:aws:elasticloadbalancing:eu-west-1:117769150821:listener/app/testing/c383c5dd580a74f5/e82083ed48688c7a"
},
"LoadBalancerHostName": {
"Type": "String"
},
"LoadBalancerPriority": {
"Type": "Number"
},
"ContainerPort": {
"Type": "Number",
"Default": "8080"
},
"TaskDefinitionCPU": {
"Type": "String",
"Default": "512"
},
"TaskDefinitionMemory": {
"Type": "String",
"Default": "4096"
},
"TaskRole": {
"Type": "String",
"Default": ""
},
"TaskExecutionRole": {
Comment thread
credfeto marked this conversation as resolved.
"Type": "String",
"Default": "arn:aws:iam::117769150821:role/ecsTaskExecutionRole"
},
"DesiredCount": {
"Type": "Number",
"Default": "1"
},
"MinimumHealthPercent": {
"Type": "Number",
"Default": "100"
},
"MaximumHealthPercent": {
"Type": "Number",
"Default": "200"
},
"SecretsManagerArn": {
"Type": "String",
"Default": "arn:aws:secretsmanager:eu-west-1:117769150821:secret:BuildBot-ph1YIJ"
}
},
"Conditions": {
"HasTaskRole": {
"Fn::Not": [
{
"Fn::Equals": [
{
"Ref": "TaskRole"
},
""
]
}
]
"Mappings": {
Comment thread
credfeto marked this conversation as resolved.
"Deployment": {
"Cluster": {
"Name": "DiscordBots"
},
"LoadBalancer": {
"ListenerArn": "arn:aws:elasticloadbalancing:eu-west-1:117769150821:listener/app/testing/c383c5dd580a74f5/e82083ed48688c7a"
Comment thread
credfeto marked this conversation as resolved.
},
"Task": {
"Cpu": "512",
"Memory": "1024",
Comment thread
credfeto marked this conversation as resolved.
"ContainerPort": "8080",
"SecretsManagerArn": "arn:aws:secretsmanager:eu-west-1:117769150821:secret:BuildBot-ph1YIJ"
},
"Service": {
"DesiredCount": "1",
"MinimumHealthPercent": "100",
"MaximumHealthPercent": "200"
}
}
},
"Metadata": {
Expand Down Expand Up @@ -125,7 +92,12 @@
"Value": {
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{ "SecretsManagerArn": { "Ref": "SecretsManagerArn" }, "Key": "DISCORD_TOKEN" }
{
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
Comment thread
credfeto marked this conversation as resolved.
},
"Key": "DISCORD_TOKEN"
}
]
}
},
Expand All @@ -134,7 +106,12 @@
"Value": {
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{ "SecretsManagerArn": { "Ref": "SecretsManagerArn" }, "Key": "DISCORD_SERVER" }
{
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "DISCORD_SERVER"
}
]
}
},
Expand All @@ -144,7 +121,9 @@
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": { "Ref": "SecretsManagerArn" },
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "DISCORD_CHANNEL"
}
]
Expand All @@ -156,7 +135,9 @@
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": { "Ref": "SecretsManagerArn" },
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "DISCORD_RELEASE_CHANNEL"
}
]
Expand All @@ -168,7 +149,9 @@
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": { "Ref": "SecretsManagerArn" },
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "OCTOPUS_URL"
}
]
Expand All @@ -180,7 +163,9 @@
"Fn::Sub": [
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": { "Ref": "SecretsManagerArn" },
"SecretsManagerArn": {
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "OCTOPUS_API_KEY"
}
]
Expand All @@ -193,7 +178,7 @@
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": {
"Ref": "SecretsManagerArn"
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "SNS_TOPIC_ARN"
}
Expand All @@ -207,7 +192,7 @@
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": {
"Ref": "SecretsManagerArn"
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "AWS_REGION"
}
Expand All @@ -221,7 +206,7 @@
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": {
"Ref": "SecretsManagerArn"
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "AWS_ACCESS_KEY_ID"
}
Expand All @@ -235,7 +220,7 @@
"{{resolve:secretsmanager:${SecretsManagerArn}:SecretString:${Key}}}",
{
"SecretsManagerArn": {
"Ref": "SecretsManagerArn"
"Fn::FindInMap": ["Deployment", "Task", "SecretsManagerArn"]
},
"Key": "AWS_SECRET_KEY"
}
Expand All @@ -259,8 +244,8 @@
},
"PortMappings": [
{
"ContainerPort": { "Ref": "ContainerPort" },
"HostPort": { "Ref": "ContainerPort" },
"ContainerPort": { "Fn::FindInMap": ["Deployment", "Task", "ContainerPort"] },
Comment thread
credfeto marked this conversation as resolved.
"HostPort": { "Fn::FindInMap": ["Deployment", "Task", "ContainerPort"] },
"Protocol": "tcp"
}
],
Expand All @@ -284,25 +269,14 @@
"Ref": "ApplicationName"
},
"Cpu": {
"Ref": "TaskDefinitionCPU"
"Fn::FindInMap": ["Deployment", "Task", "Cpu"]
},
"Memory": {
"Ref": "TaskDefinitionMemory"
"Fn::FindInMap": ["Deployment", "Task", "Memory"]
},
"ExecutionRoleArn": {
"Ref": "TaskExecutionRole"
},
"TaskRoleArn": {
"Fn::If": [
"HasTaskRole",
{
"Ref": "TaskRole"
},
{
"Ref": "AWS::NoValue"
}
]
},
"RequiresCompatibilities": ["FARGATE"],
Comment thread
credfeto marked this conversation as resolved.
"NetworkMode": "awsvpc",
"Volumes": [],
Expand Down Expand Up @@ -330,13 +304,13 @@
"Ref": "ApplicationName"
},
"Cluster": {
"Ref": "ECSClusterName"
"Fn::FindInMap": ["Deployment", "Cluster", "Name"]
},
"TaskDefinition": {
"Ref": "TaskDefinition"
},
"DesiredCount": {
"Ref": "DesiredCount"
"Fn::FindInMap": ["Deployment", "Service", "DesiredCount"]
},
"EnableECSManagedTags": false,
"Tags": [],
Expand All @@ -350,16 +324,16 @@
},
"DeploymentConfiguration": {
"MaximumPercent": {
"Ref": "MaximumHealthPercent"
"Fn::FindInMap": ["Deployment", "Service", "MaximumHealthPercent"]
},
"MinimumHealthyPercent": {
"Ref": "MinimumHealthPercent"
"Fn::FindInMap": ["Deployment", "Service", "MinimumHealthPercent"]
}
},
"LoadBalancers": [
{
"ContainerName": { "Ref": "ApplicationName" },
"ContainerPort": { "Ref": "ContainerPort" },
"ContainerPort": { "Fn::FindInMap": ["Deployment", "Task", "ContainerPort"] },
"TargetGroupArn": { "Ref": "TargetGroup" }
}
]
Expand All @@ -373,12 +347,12 @@
"Ref": "ApplicationName"
},
"HealthCheckPath": "/ping?source=target-group",
"Port": { "Ref": "ContainerPort" },
"Port": { "Fn::FindInMap": ["Deployment", "Task", "ContainerPort"] },
"Protocol": "HTTP",
"TargetType": "ip",
"HealthCheckEnabled": true,
"HealthCheckProtocol": "HTTP",
"HealthCheckPort": { "Ref": "ContainerPort" },
"HealthCheckPort": { "Fn::FindInMap": ["Deployment", "Task", "ContainerPort"] },
"HealthCheckTimeoutSeconds": 4,
"HealthyThresholdCount": 5,
"HealthCheckIntervalSeconds": 5,
Expand Down Expand Up @@ -416,7 +390,7 @@
"Values": [{ "Ref": "LoadBalancerHostName" }]
}
],
"ListenerArn": { "Ref": "LoadBalancerArn" },
"ListenerArn": { "Fn::FindInMap": ["Deployment", "LoadBalancer", "ListenerArn"] },
"Priority": { "Ref": "LoadBalancerPriority" }
}
}
Expand Down
Loading