Skip to content

Commit

Permalink
create ci workflows (#4)
Browse files Browse the repository at this point in the history
* cleanup c# files

* add docker image build ci

* add paths to ci trigger

* docker context

* pass secret as build arg

* env var to run command

* app config fixes + ci updates

* docker run formatting

* env->env

* stringify?

* new env syntax

* try env for task

* try dockerfile args

* standard bash syntax

* workflow level env

* env. syntax

* try using just env

* try quotes

* remove extra quote
  • Loading branch information
erikrose100 authored May 1, 2024
1 parent fe3232d commit 522963f
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 48 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/docker-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: ci

on:
push:
branches-ignore:
- "main"
# paths:
# - "MediaFileMetadataCheckerAPI/**"

env:
TEST_TAG: user/app:test
LATEST_TAG: user/app:latest
METADATA_API_CONFIG_CONNECTION_STRING: ${{ secrets.APP_CONFIG_CONNECTION_STRING }}

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export to local images
uses: docker/build-push-action@v5
with:
context: "{{defaultContext}}:MediaFileMetadataCheckerAPI"
load: true
tags: ${{ env.TEST_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Test running image
run: |
docker run --rm ${{ env.TEST_TAG }} -e METADATA_API_CONFIG_CONNECTION_STRING="${{ env.METADATA_API_CONFIG_CONNECTION_STRING }}" -e METADATA_API_CONFIG_CACHE_EXPIRATION="1" --stop-timeout 30
25 changes: 9 additions & 16 deletions MediaFileMetadataCheckerAPI/Controllers/FileUploadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using System.IO;
using System.Threading.Tasks;
Expand All @@ -21,11 +22,13 @@ namespace MediaFileMetadataCheckerAPI.Controllers
[Route("[controller]")]
public class FileUploadController : ControllerBase
{
private readonly Settings _settings;
private readonly ILogger<FileUploadController> _logger;

public FileUploadController(ILogger<FileUploadController> logger)
public FileUploadController(ILogger<FileUploadController> logger, IOptionsSnapshot<Settings> settings)
{
_logger = logger;
_settings = settings.Value;
}

/// <summary>
Expand All @@ -39,15 +42,14 @@ public FileUploadController(ILogger<FileUploadController> logger)
[HttpPost]
[Route(nameof(UploadLargeFileForMetadata))]
[ProducesResponseType(typeof(FileStreamResult), 200, "application/json")]
// [Produces("application/json", "application/json")]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadLargeFileForMetadata()
{
var request = HttpContext.Request;

// validation of Content-Type
// 1. first, it must be a form-data request
// 2. a boundary should be found in the Content-Type
// Validation of Content-Type
// 1. First, it must be a form-data request
// 2. A boundary should be found in the Content-Type
if (!request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
Expand All @@ -59,8 +61,6 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
var reader = new MultipartReader(boundary, request.Body);
var section = await reader.ReadNextSectionAsync();

// This sample try to get the first file from request and save it
// Make changes according to your needs in actual use
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
Expand All @@ -70,11 +70,6 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
!string.IsNullOrEmpty(contentDisposition.FileName.Value))
{
// Don't trust any file name, file extension, and file data from the request unless you trust them completely
// Otherwise, it is very likely to cause problems such as virus uploading, disk filling, etc
// In short, it is necessary to restrict and verify the upload
// Here, we just use the temporary folder and a random file name

// Get the temporary folder, and combine a random file name with it
var fileName = Path.GetRandomFileName();
var saveToPath = Path.Combine(Path.GetTempPath(), fileName);
Expand All @@ -88,7 +83,8 @@ public async Task<IActionResult> UploadLargeFileForMetadata()

if (mediaInfo is not null)
{
HashSet<string> returnProperties = Settings.ReturnProperties.Split(";").ToHashSet();
// Get return properties from App Config and only return configured properties
HashSet<string> returnProperties = _settings.ReturnProperties.Split(";").ToHashSet();

var File = new FileUploadItem();
File.Duration = returnProperties.Contains("Duration") ? mediaInfo.Duration : null;
Expand All @@ -105,12 +101,9 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
}

}
#pragma warning restore CS8602 // Dereference of a possibly null reference.

section = await reader.ReadNextSectionAsync();
}

// If the code runs to this location, it means that no files have been saved
return BadRequest("No files data in the request.");
}
}
Expand Down
28 changes: 0 additions & 28 deletions MediaFileMetadataCheckerAPI/Filters/FileFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)

if (formParameters.Any())
{
// already taken care by swashbuckle. no need to add explicitly.
return;
}
if (operation.RequestBody != null)
{
// NOT required for form type
return;
}
if (context.ApiDescription.HttpMethod == HttpMethod.Post.Method)
Expand Down Expand Up @@ -64,29 +62,3 @@ internal static bool IsFromForm(this ApiParameterDescription apiParameter)
return (elementType != null && typeof(IFormFile).IsAssignableFrom(elementType));
}
}

public class FileDownloadFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.ApiDescription.SupportedResponseTypes.Any(x =>
x.Type == typeof(FileStreamResult) ||
x.Type == typeof(FileResult)))

if (operation.RequestBody == null)
{
return;
}

// See https://github.com/Azure/autorest.csharp/issues/197
foreach (var content in operation.RequestBody.Content)
foreach (var contentProperty in content.Value.Schema.Properties)
{
var schema = contentProperty.Value;
if (schema.Format == "binary")
{
schema.Type = "file";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
Expand Down
7 changes: 5 additions & 2 deletions MediaFileMetadataCheckerAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using MediaFileMetadataCheckerAPI.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Azure.AppConfiguration.AspNetCore;
using Microsoft.Extensions.Configuration;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -13,7 +14,7 @@
opt.UseInMemoryDatabase("FileUploadList"));
// Get connection string from Environment variables
string? connectionString = Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CONNECTION_STRING");
double? configCacheExpiration = Convert.ToDouble(Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CACHE_EXPIRATION"));
double configCacheExpiration = Convert.ToDouble(Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CACHE_EXPIRATION"));

// Load configuration from Azure App Configuration
builder.Configuration.AddAzureAppConfiguration(options =>
Expand All @@ -24,8 +25,10 @@
// Configure to reload configuration if the registered sentinel key is modified
.ConfigureRefresh(refreshOptions =>
refreshOptions.Register("MetadataApp:Settings:Sentinel", refreshAll: true)
.SetCacheExpiration(TimeSpan.FromHours(configCacheExpiration ?? 1)));
.SetCacheExpiration(TimeSpan.FromHours(configCacheExpiration)));
});
// Add Azure App Configuration middleware to the container of services.
builder.Services.AddAzureAppConfiguration();
// Bind configuration "MetadataApp:Settings" section to the Settings object
builder.Services.Configure<MetadataAppConfig.Settings>(builder.Configuration.GetSection("MetadataApp:Settings"));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
Expand Down
2 changes: 1 addition & 1 deletion MediaFileMetadataCheckerAPI/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace MetadataAppConfig
{
public class Settings
{
public static string? ReturnProperties { get; set; }
public string? ReturnProperties { get; set; }
}
}
10 changes: 9 additions & 1 deletion scripts/docker-run.zsh
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#!/usr/bin/env zsh
# doc: https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md
docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password=$pass -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ mediametadata
docker run --rm -it -p 8000:80 -p 8001:443 /
-e ASPNETCORE_URLS="https://+;http://+" /
-e ASPNETCORE_HTTPS_PORTS=8001 /
-e ASPNETCORE_Kestrel__Certificates__Default__Password=$pass /
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx /
-e ASPNETCORE_ENVIRONMENT=Development /
-e METADATA_API_CONFIG_CACHE_EXPIRATION=1 /
-e METADATA_API_CONFIG_CONNECTION_STRING=$connectionString /
-v ${HOME}/.aspnet/https:/https/ mediametadata

0 comments on commit 522963f

Please sign in to comment.