Skip to content

Commit

Permalink
Merge test changes to main (#354)
Browse files Browse the repository at this point in the history
Automatically created pull-request in order to merge changes that were
recently pushed to the test branch, back to main
  • Loading branch information
hwinther authored Nov 6, 2024
2 parents cdcf9da + 9a72292 commit bebc43b
Show file tree
Hide file tree
Showing 35 changed files with 13,659 additions and 6,514 deletions.
4 changes: 4 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ MAIN_BRANCH="main"

current_branch="$(git rev-parse --abbrev-ref HEAD)"

if [[ $current_branch =~ dependabot/.* ]]; then
exit 0
fi

case "$current_branch" in
$DEV_BRANCH)
error_msg="Aborting commit. Please use the following format: <Imperative verb> <short description of change>"
Expand Down
2 changes: 1 addition & 1 deletion .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ source .githooks/config.sh
local_branch="$(git rev-parse --abbrev-ref HEAD)"

# valid_branch_regex="^(feature|bugfix|improvement|library|prerelease|release|hotfix)\/[a-z0-9._-]+$"
valid_branch_regex="^(main|qa|test|dev|${BRANCH_PREFIXES}\/${JIRA_TAG}-[0-9]+-[A-Za-z0-9-]+)$"
valid_branch_regex="^(main|qa|test|dev|${BRANCH_PREFIXES}\/${JIRA_TAG}-[0-9]+-[A-Za-z0-9-]+|dependabot/.*)$"

message="There is something wrong with your branch name. Branch names in this project must adhere to this contract: $valid_branch_regex. Your commit will be rejected. You should rename your branch to a valid name and try again."

Expand Down
64 changes: 55 additions & 9 deletions .github/actions/frontend-build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,43 @@ runs:
cache-dependency-path: "${{ inputs.working_directory }}/yarn.lock"

- name: Install dependencies
id: dependency-install
shell: bash
working-directory: ${{ inputs.working_directory }}
run: |
echo "::group::Install dependencies"
[[ "${{ inputs.package_manager }}" == "npm" ]] && npm ci || true
[[ "${{ inputs.package_manager }}" == "yarn" ]] && yarn install --immutable --immutable-cache --check-cache || true
set +e
if [[ "${{ inputs.package_manager }}" == "npm" ]]; then
npm ci 1>dependency.out 2>&1
exit_code=$?
elif [[ "${{ inputs.package_manager }}" == "yarn" ]]; then
yarn install --immutable --immutable-cache --check-cache 1>dependency.out 2>&1
exit_code=$?
else
echo "::error::Invalid package manager: ${{ inputs.package_manager }}"
exit_code=1
fi
echo "Dependency installation exit code: $exit_code"
set -e
echo -e "\nDependency installation:\n"
cat dependency.out
if [[ $exit_code -ne 0 ]]
then
echo "::error::Dependency installation failed with errors."
echo "## ❌ Dependency installation failed with errors:" > dependency.md
cat dependency.out >> dependency.md
exit 1
else
echo "## ✅ Dependency installation successful" > dependency.md
cat dependency.out | grep "packages in" >> dependency.md
fi
echo "::endgroup::"
- name: Build
id: node-build
if: steps.dependency-install.outcome == 'success'
shell: bash
working-directory: ${{ inputs.working_directory }}
run: |
Expand Down Expand Up @@ -86,19 +113,36 @@ runs:
echo "::endgroup::"
- name: Lint
if: always()
if: steps.dependency-install.outcome == 'success'
id: node-lint
shell: bash
working-directory: ${{ inputs.working_directory }}
run: |
echo "::group::Lint"
[[ "${{ inputs.package_manager }}" == "npm" ]] && npm run lint -- -f compact 1>lint.out 2>&1 || (exit 0)
[[ "${{ inputs.package_manager }}" == "yarn" ]] && yarn lint -f compact 1>lint.out 2>&1 || (exit 0)
set +e
if [[ "${{ inputs.package_manager }}" == "npm" ]]; then
npm run lint -- -f compact 1>lint.out 2>&1
LINT_EXIT_CODE=$?
elif [[ "${{ inputs.package_manager }}" == "yarn" ]]; then
yarn lint -f compact 1>lint.out 2>&1
LINT_EXIT_CODE=$?
else
echo "::error::Invalid package manager: ${{ inputs.package_manager }}"
exit 1
fi
echo "Lint exit code: $LINT_EXIT_CODE"
set -e
echo -e "\nLint output:\n"
cat lint.out
cat lint.out | grep ": line " | sed -e 's|${{ env.TRAILING_AGENT_WORK_PATH }}||' >lint.err || (exit 0)
if [ ! -s lint.err ]
if [[ $LINT_EXIT_CODE -ne 0 ]]
then
echo "::error::Linting failed with errors."
echo "## ❌ Linting failed with errors:" > lint.md
cat lint.out >> lint.md
elif [ ! -s lint.err ]
then
echo "## ✅ No linting issues 🎊" > lint.md
else
Expand All @@ -120,8 +164,9 @@ runs:
echo "result<<EOF"$'\n'"$(cat lint.md)"$'\n'EOF >> $GITHUB_OUTPUT
cat lint.md >> $GITHUB_STEP_SUMMARY
if [ -s lint.err ]
if [ -s lint.err ] || [ $LINT_EXIT_CODE -ne 0 ]
then
echo "::error::Linting issues found"
exit 1
fi
echo "::endgroup::"
Expand All @@ -133,8 +178,9 @@ runs:
working-directory: ${{ inputs.working_directory }}
run: |
echo "# ${{ env.WORKFLOW_SHORT_NAME }}" > combined.md
cat build.md >> combined.md
cat lint.md >> combined.md
cat dependency.md >> combined.md
[ -f build.md ] && cat build.md >> combined.md
[ -f lint.md ] && cat lint.md >> combined.md
echo "result<<EOF"$'\n'"$(cat combined.md)"$'\n'EOF >> $GITHUB_OUTPUT
- name: "Create or Update PR Comment"
Expand Down
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ frontend:
- changed-files:
- any-glob-to-any-file: "src/frontend/**"

playwright:
- changed-files:
- any-glob-to-any-file: "tests/playwright/**"

dependencies:
- changed-files:
- any-glob-to-any-file: ["src/**/*.lock.json", "src/**/yarn.lock"]
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/backend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ jobs:

- name: Stryker
id: stryker
if: ${{ github.event_name == 'pull_request' && github.base_ref == 'main' }}
run: |
dotnet stryker --reporter "html" --reporter "json" --reporter "markdown" --solution Backend.sln --output StrykerOutput
cp -r StrykerOutput/reports StrykerReports
Expand All @@ -206,21 +207,22 @@ jobs:
echo "EOF" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
if: ${{ github.event_name == 'pull_request' && github.base_ref == 'main' }}
with:
name: StrykerReports
path: ${{ env.BACKEND_SOLUTION_PATH }}/StrykerReports

- name: "Create or Update PR Comment"
uses: im-open/[email protected]
if: ${{ always() && github.event_name == 'pull_request' }}
if: ${{ always() && github.event_name == 'pull_request' && github.base_ref == 'main' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
comment-identifier: "${{ env.WORKFLOW_SHORT_NAME }}-Stryker"
comment-content: ${{ steps.stryker.outputs.markdown }}

- name: Inspect code
uses: muno92/resharper_inspectcode@v1
if: ${{ github.event_name == 'pull_request' }}
if: ${{ github.event_name == 'pull_request' && github.base_ref == 'main' }}
with:
workingDirectory: ${{ env.BACKEND_SOLUTION_PATH }}
solutionPath: Backend.sln
Expand Down
8 changes: 4 additions & 4 deletions src/backend/WebApi/Controllers/SendMessageController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public class SendMessageController(IMessageSender messageSender) : ControllerBas
/// </summary>
/// <returns>A string indicating the result of the message sending operation.</returns>
[HttpGet]
public Task<ActionResult<GenericValue<string>>> Get() =>
Task.FromResult<ActionResult<GenericValue<string>>>(Ok(new GenericValue<string>
public async Task<ActionResult<GenericValue<string>>> Get() =>
Ok(new GenericValue<string>
{
Value = messageSender.SendMessage()
}));
Value = await messageSender.SendMessageAsync()
});
}
25 changes: 16 additions & 9 deletions src/backend/WebApi/Messaging/MessageReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public sealed class MessageReceiver : IDisposable

private readonly ILogger<MessageReceiver> _logger;
private readonly IConnection _connection;
private readonly IModel _channel;
private readonly IChannel _channel;

/// <summary>
/// Initializes a new instance of the <see cref="MessageReceiver" /> class, creating a connection to RabbitMQ
Expand All @@ -32,8 +32,13 @@ public sealed class MessageReceiver : IDisposable
public MessageReceiver(ILogger<MessageReceiver> logger)
{
_logger = logger;
_connection = RabbitMqHelper.CreateConnection();
_channel = RabbitMqHelper.CreateModelAndDeclareTestQueue(_connection);
_connection = RabbitMqHelper.CreateConnectionAsync()
.GetAwaiter()
.GetResult();

_channel = RabbitMqHelper.CreateModelAndDeclareTestQueueAsync(_connection)
.GetAwaiter()
.GetResult();
}

/// <summary>
Expand All @@ -48,9 +53,9 @@ public void Dispose()
/// <summary>
/// Starts the message consumer which listens for messages on the declared queue and processes them.
/// </summary>
public void StartConsumer()
public async Task StartConsumerAsync()
{
RabbitMqHelper.StartConsumer(_channel, ReceiveMessage);
await RabbitMqHelper.StartConsumerAsync(_channel, ReceiveMessageAsync);
}

/// <summary>
Expand All @@ -59,7 +64,7 @@ public void StartConsumer()
/// duration.
/// </summary>
/// <param name="ea">The event arguments containing the message and metadata.</param>
public void ReceiveMessage(BasicDeliverEventArgs ea)
public Task ReceiveMessageAsync(BasicDeliverEventArgs ea)
{
// Extract the PropagationContext of the upstream parent from the message headers.
var parentContext = Propagator.Extract(default, ea.BasicProperties, ExtractTraceContextFromBasicProperties);
Expand All @@ -74,7 +79,7 @@ public void ReceiveMessage(BasicDeliverEventArgs ea)
{
var message = Encoding.UTF8.GetString(ea.Body.Span.ToArray());

_logger.LogInformation($"Message received: [{message}]");
_logger.LogInformation("Message received: [{Message}]", message);

activity?.SetTag("message", message);

Expand All @@ -89,13 +94,15 @@ public void ReceiveMessage(BasicDeliverEventArgs ea)
{
_logger.LogError(ex, "Message processing failed.");
}

return Task.CompletedTask;
}

private IEnumerable<string> ExtractTraceContextFromBasicProperties(IBasicProperties props, string key)
private IEnumerable<string> ExtractTraceContextFromBasicProperties(IReadOnlyBasicProperties props, string key)
{
try
{
if (props.Headers.TryGetValue(key, out var value) && value is byte[] bytes)
if (props.Headers != null && props.Headers.TryGetValue(key, out var value) && value is byte[] bytes)
return
[
Encoding.UTF8.GetString(bytes)
Expand Down
25 changes: 15 additions & 10 deletions src/backend/WebApi/Messaging/MessageSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public sealed class MessageSender : IMessageSender, IDisposable

private readonly ILogger<MessageSender> _logger;
private readonly IConnection _connection;
private readonly IModel _channel;
private readonly IChannel _channel;

/// <summary>
/// Initializes a new instance of the <see cref="MessageSender" /> class, establishing a connection and channel to
Expand All @@ -31,8 +31,13 @@ public sealed class MessageSender : IMessageSender, IDisposable
public MessageSender(ILogger<MessageSender> logger)
{
_logger = logger;
_connection = RabbitMqHelper.CreateConnection();
_channel = RabbitMqHelper.CreateModelAndDeclareTestQueue(_connection);
_connection = RabbitMqHelper.CreateConnectionAsync()
.GetAwaiter()
.GetResult();

_channel = RabbitMqHelper.CreateModelAndDeclareTestQueueAsync(_connection)
.GetAwaiter()
.GetResult();
}

/// <summary>
Expand All @@ -46,7 +51,7 @@ public void Dispose()

/// <inheritdoc />
/// <remarks>Including propagating the OpenTelemetry trace context.</remarks>
public string SendMessage()
public async Task<string> SendMessageAsync()
{
try
{
Expand All @@ -55,7 +60,7 @@ public string SendMessage()
var activityName = $"{RabbitMqHelper.TestQueueName} send";

using var activity = ActivitySource.StartActivity(activityName, ActivityKind.Producer);
var props = _channel.CreateBasicProperties();
var props = new BasicProperties();

// Depending on Sampling (and whether a listener is registered or not), the
// activity above may not be created.
Expand All @@ -77,13 +82,14 @@ public string SendMessage()

var body = $"Published message: DateTime.Now = {DateTime.Now}.";

_channel.BasicPublish(
await _channel.BasicPublishAsync(
RabbitMqHelper.DefaultExchangeName,
RabbitMqHelper.TestQueueName,
true,
props,
Encoding.UTF8.GetBytes(body));

_logger.LogInformation($"Message sent: [{body}]");
_logger.LogInformation("Message sent: [{Body}]", body);

return body;
}
Expand All @@ -104,8 +110,7 @@ private void InjectTraceContextIntoBasicProperties(IBasicProperties props, strin
{
try
{
if (props.Headers == null)
props.Headers = new Dictionary<string, object>();
props.Headers ??= new Dictionary<string, object?>();

props.Headers[key] = value;
}
Expand All @@ -126,5 +131,5 @@ public interface IMessageSender
/// Sends a message to a RabbitMQ queue
/// </summary>
/// <returns>A string representing the message that was sent.</returns>
public string SendMessage();
public Task<string> SendMessageAsync();
}
19 changes: 9 additions & 10 deletions src/backend/WebApi/Messaging/RabbitMqHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,22 @@ public static class RabbitMqHelper
/// Creates and returns a new RabbitMQ connection using the configured ConnectionFactory.
/// </summary>
/// <returns>A new IConnection instance for interacting with RabbitMQ.</returns>
public static IConnection CreateConnection() => ConnectionFactory.CreateConnection();
public static async Task<IConnection> CreateConnectionAsync() => await ConnectionFactory.CreateConnectionAsync();

/// <summary>
/// Creates a new channel from the given connection, and declares a test queue for message delivery.
/// </summary>
/// <param name="connection">The RabbitMQ connection to use for creating the channel and declaring the queue.</param>
/// <returns>A new IModel instance representing the channel with the declared queue.</returns>
public static IModel CreateModelAndDeclareTestQueue(IConnection connection)
public static async Task<IChannel> CreateModelAndDeclareTestQueueAsync(IConnection connection)
{
var channel = connection.CreateModel();
var channel = await connection.CreateChannelAsync();

channel.QueueDeclare(
await channel.QueueDeclareAsync(
TestQueueName,
false,
false,
false,
null);
false);

return channel;
}
Expand All @@ -68,13 +67,13 @@ public static IModel CreateModelAndDeclareTestQueue(IConnection connection)
/// </summary>
/// <param name="channel">The channel to start the consumer on.</param>
/// <param name="processMessage">The callback to invoke for each received message.</param>
public static void StartConsumer(IModel channel, Action<BasicDeliverEventArgs> processMessage)
public static async Task StartConsumerAsync(IChannel channel, Func<BasicDeliverEventArgs, Task> processMessage)
{
var consumer = new EventingBasicConsumer(channel);
var consumer = new AsyncEventingBasicConsumer(channel);

consumer.Received += (bc, ea) => processMessage(ea);
consumer.ReceivedAsync += (bc, ea) => processMessage(ea);

channel.BasicConsume(TestQueueName, true, consumer);
await channel.BasicConsumeAsync(TestQueueName, true, consumer);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/backend/WebApi/WebApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
<PackageReference Include="RabbitMQ.Client" Version="7.0.0" />
<PackageReference Include="SauceControl.InheritDoc" Version="2.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading

0 comments on commit bebc43b

Please sign in to comment.