6 Commits

Author SHA1 Message Date
a51e61aabc Attempting to fix code first migrations not running against a fresh db
All checks were successful
ci/woodpecker/tag/api_build Pipeline was successful
ci/woodpecker/tag/api_uploadimage Pipeline was successful
2024-04-10 20:52:31 -05:00
8dd914c6c2 Committing work fixing issues found while testing on dev1.bookmarks
All checks were successful
ci/woodpecker/tag/api_build Pipeline was successful
ci/woodpecker/tag/api_uploadimage Pipeline was successful
ci/woodpecker/tag/web_uploadimage Pipeline was successful
ci/woodpecker/push/api_build Pipeline was successful
- Modified EnvironmentUtils to fix proper casing for getting ASPNETCore_Environment
- On Web, modify package.json to delete 'homepage': '.', line to fix issue with app not serving up subroutes. See: https://stackoverflow.com/questions/63036631/nginx-returning-404-when-trying-get-subroute-in-dockerized-react-app
- Added docker-compose for easier setup and deployment of local docker containers
2024-04-08 23:12:16 -05:00
d83b13c093 Updated environment variable to be blank by default
All checks were successful
ci/woodpecker/tag/api_build Pipeline was successful
ci/woodpecker/tag/api_uploadimage Pipeline was successful
2024-04-07 20:36:11 -05:00
9fae3b978f Modified ClaimNameAttribute to support multiple claim names depending on environment
All checks were successful
ci/woodpecker/tag/api_build Pipeline was successful
ci/woodpecker/tag/api_uploadimage Pipeline was successful
Environment name will be pulled from environment variable: ASPNETCORE_ENVIRONMENT
2024-04-07 20:18:53 -05:00
822a8379aa Merge pull request 'Created Woodpecker CI/CD deployment' (#38) from feature/CreateCIPlans into develop
All checks were successful
ci/woodpecker/push/api_build Pipeline was successful
Reviewed-on: #38
2024-04-07 15:20:05 -05:00
a5d5ed048f Created Woodpecker CI/CD deployment
- Created Dockerfile for packing up API and Web projects as Docker image
2024-04-07 14:51:28 -05:00
16 changed files with 170 additions and 62 deletions

1
.gitignore vendored
View File

@ -248,5 +248,4 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
.env .env
Logs/* Logs/*
docker-compose.yml
*exclude* *exclude*

View File

@ -1,43 +0,0 @@
steps:
- name: (YABA.API) Build and run tests
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- dotnet build ./API
- dotnet test ./API
- name: (YABA.API) Deploy Docker Image (Non-Prod Branch)
when:
- event: tag
branch:
exclude: [master]
image: woodpeckerci/plugin-docker-buildx
settings:
repo: gitea.iwanaga.moe/cjtibule/yaba/api
context: ./API
dockerfile: ./API/YABA.API/Dockerfile
tags:
- latest-dev
- ${CI_COMMIT_TAG}
username:
from_secret: gitea_yaba_registry_username
password:
from_secret: gitea_yaba_registry_password
registry: gitea.iwanaga.moe
- name: (YABA.Web) Deploy Docker Image (Non-Prod Branch)
when:
- event: tag
branch:
exclude: [master]
image: woodpeckerci/plugin-docker-buildx
settings:
repo: gitea.iwanaga.moe/cjtibule/yaba/web
context: ./Web
dockerfile: ./Web/Dockerfile
tags:
- latest-dev
- ${CI_COMMIT_TAG}
username:
from_secret: gitea_yaba_registry_username
password:
from_secret: gitea_yaba_registry_password
registry: gitea.iwanaga.moe

View File

@ -0,0 +1,12 @@
when:
- event: [push, pull_request, tag]
ref: [refs/tags/APIDEV-*, refs/tags/API-*, refs/heads/api/*]
steps:
- name: (YABA.API) Build and run tests
when:
- event: [push, pull_request, tag]
branch: [api/*]
image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- dotnet build ./API
- dotnet test ./API

View File

@ -0,0 +1,36 @@
when:
- event: tag
ref: [refs/tags/APIDEV-*, refs/tags/API-*]
steps:
- name: (YABA.API) Determining Docker image version number (dev)
when:
- ref: refs/tags/APIDEV-*
image: alpine:latest
commands:
- rm -f tags.txt
- echo ${CI_COMMIT_TAG} | sed -e "s/^APIDEV-//" >> tags.txt
- echo "latest-dev" >> tags.txt
- name: (YABA.API) Determining Docker image version number (prod)
image: alpine:latest
when:
- ref: refs/tags/API-*
commands:
- rm -f tags.txt
- echo ${CI_COMMIT_TAG} | sed -e "s/^API-//" >> tags.txt
- echo "latest" >> tags.txt
- name: (YABA.API) Package and Upload Docker Image
image: woodpeckerci/plugin-docker-buildx
settings:
repo: gitea.iwanaga.moe/cjtibule/yaba/api
context: ./API
dockerfile: ./API/YABA.API/Dockerfile
tags_file: tags.txt
platforms:
- linux/amd64
username:
from_secret: gitea_yaba_registry_username
password:
from_secret: gitea_yaba_registry_password
registry: gitea.iwanaga.moe
depends_on:
- api_build

View File

@ -0,0 +1,52 @@
when:
- event: tag
ref: [refs/tags/WEBDEV-*, refs/tags/WEB-*]
steps:
- name: (YABA.Web) Determining Docker image version number (dev)
when:
- ref: refs/tags/WEBDEV-*
image: alpine:latest
commands:
- rm -f tags.txt
- echo ${CI_COMMIT_TAG} | sed -e "s/^WEBDEV-//" >> tags.txt
- echo "latest-dev" >> tags.txt
- name: (YABA.Web) Determining Docker image version number (prod)
when:
- ref: refs/tags/WEB-*
image: alpine:latest
commands:
- rm -f tags.txt
- echo ${CI_COMMIT_TAG} | sed -e "s/^WEB-//" >> tags.txt
- echo "latest" >> tags.txt
- name: (YABA.Web) Package and Upload Docker Image (dev)
when:
- ref: refs/tags/WEBDEV-*
image: woodpeckerci/plugin-docker-buildx
settings:
repo: gitea.iwanaga.moe/cjtibule/yaba/web
context: ./Web
dockerfile: ./Web/Dockerfile
tags_file: tags.txt
username:
from_secret: gitea_yaba_registry_username
password:
from_secret: gitea_yaba_registry_password
registry: gitea.iwanaga.moe
build_args:
from_secret: DEV1_BUILDARGS
- name: (YABA.Web) Package and Upload Docker Image (prod)
when:
- ref: refs/tags/WEB-*
image: woodpeckerci/plugin-docker-buildx
settings:
repo: gitea.iwanaga.moe/cjtibule/yaba/web
context: ./Web
dockerfile: ./Web/Dockerfile
tags_file: tags.txt
username:
from_secret: gitea_yaba_registry_username
password:
from_secret: gitea_yaba_registry_password
registry: gitea.iwanaga.moe
build_args:
from_secret: PROD_BUILDARGS

View File

@ -6,14 +6,16 @@ EXPOSE 80
EXPOSE 443 EXPOSE 443
# Set environment variables # Set environment variables
ENV ASPNETCORE_Environment=Development ENV ASPNETCORE_Environment=
ENV ASPNETCORE_Authentication__Auth0__ClientId= ENV ASPNETCORE_Authentication__Auth0__ClientId=
ENV ASPNETCORE_Authentication__Auth0__ClientSecret= ENV ASPNETCORE_Authentication__Auth0__ClientSecret=
ENV ASPNETCORE_Authentication__Auth0__Domain= ENV ASPNETCORE_Authentication__Auth0__Domain=
ENV ASPNETCORE_Authentication__Auth0__Identifier= ENV ASPNETCORE_Authentication__Auth0__Identifier=
ENV ASPNETCORE_ConnectionStrings__YABAReadOnlyDbConnectionString= ENV ASPNETCORE_ConnectionStrings__YABAReadOnlyDbConnectionString=
ENV ASPNETCORE_ConnectionStrings__YABAReadWriteDbConnectionString= ENV ASPNETCORE_ConnectionStrings__YABAReadWriteDbConnectionString=
ENV ASPNETCORE_WebClient__Url= ENV WebClient__Url=
ENV Serilog__WriteTo__1__Args__Uri=
ENV Serilog__WriteTo__1__Args__Labels__1__Value=
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build
WORKDIR /src WORKDIR /src

View File

@ -2,6 +2,7 @@
using YABA.API.Extensions; using YABA.API.Extensions;
using YABA.Common.Extensions; using YABA.Common.Extensions;
using YABA.Common.Lookups; using YABA.Common.Lookups;
using YABA.Common.Utils;
using YABA.Service.Interfaces; using YABA.Service.Interfaces;
namespace YABA.API.Middlewares namespace YABA.API.Middlewares
@ -31,7 +32,7 @@ namespace YABA.API.Middlewares
userId = registedUser.Id; userId = registedUser.Id;
} }
httpContext.User.Identities.FirstOrDefault().AddClaim(new Claim(ClaimsLookup.UserId.GetClaimName(), userId.ToString())); httpContext.User.Identities.FirstOrDefault().AddClaim(new Claim(ClaimsLookup.UserId.GetClaimName(EnvironmentUtils.IsDevelopmentEnvironment()), userId.ToString()));
} }
} }

View File

@ -97,7 +97,7 @@ var app = builder.Build();
// Run database migrations // Run database migrations
using (var scope = app.Services.CreateScope()) using (var scope = app.Services.CreateScope())
{ {
var yabaDbContext = scope.ServiceProvider.GetRequiredService<YABAReadWriteContext>(); var yabaDbContext = scope.ServiceProvider.GetRequiredService<YABABaseContext>();
yabaDbContext.Database.Migrate(); yabaDbContext.Database.Migrate();
} }

View File

@ -4,11 +4,13 @@ namespace YABA.Common.Attributes
{ {
public class ClaimNameAttribute : Attribute public class ClaimNameAttribute : Attribute
{ {
public string Name { get; private set; } public string DevClaimName { get; private set; }
public string ProdClaimName { get; private set; }
public ClaimNameAttribute(string name) public ClaimNameAttribute(string devClaimName, string prodClaimName)
{ {
this.Name = name; this.DevClaimName = devClaimName;
ProdClaimName = prodClaimName;
} }
} }
} }

View File

@ -28,9 +28,9 @@ namespace YABA.Common.Extensions
return enumValue.GetAttribute<DisplayAttribute>().Name; return enumValue.GetAttribute<DisplayAttribute>().Name;
} }
public static string GetClaimName(this ClaimsLookup claimLookup) public static string GetClaimName(this ClaimsLookup claimLookup, bool isDevelopmentEnvironment)
{ {
return claimLookup.GetAttribute<ClaimNameAttribute>().Name; return isDevelopmentEnvironment ? claimLookup.GetAttribute<ClaimNameAttribute>().DevClaimName : claimLookup.GetAttribute<ClaimNameAttribute>().ProdClaimName;
} }
public static bool IsCrudResultSuccessful(this CrudResultLookup importStatusLookup) => SuccessfulCrudStatuses.Contains(importStatusLookup); public static bool IsCrudResultSuccessful(this CrudResultLookup importStatusLookup) => SuccessfulCrudStatuses.Contains(importStatusLookup);

View File

@ -1,6 +1,8 @@
using System.Security.Claims; using System;
using System.Security.Claims;
using System.Security.Principal; using System.Security.Principal;
using YABA.Common.Lookups; using YABA.Common.Lookups;
using YABA.Common.Utils;
namespace YABA.Common.Extensions namespace YABA.Common.Extensions
{ {
@ -12,7 +14,7 @@ namespace YABA.Common.Extensions
public static string GetCustomClaim(this IIdentity identity, ClaimsLookup claim) public static string GetCustomClaim(this IIdentity identity, ClaimsLookup claim)
{ {
var claimsIdentity = identity as ClaimsIdentity; var claimsIdentity = identity as ClaimsIdentity;
return claimsIdentity.FindFirst(claim.GetClaimName())?.Value.ToString(); return claimsIdentity.FindFirst(claim.GetClaimName(EnvironmentUtils.IsDevelopmentEnvironment()))?.Value.ToString();
} }
} }
} }

View File

@ -4,19 +4,19 @@ namespace YABA.Common.Lookups
{ {
public enum ClaimsLookup public enum ClaimsLookup
{ {
[ClaimNameAttribute("https://dev.iwanaga.moe/api/auth_provider_id")] [ClaimName("https://auth.dev.iwanaga.moe/api/auth_provider_id", "https://auth.iwanaga.moe/api/auth_provider_id")]
AuthProviderId = 1, AuthProviderId = 1,
[ClaimNameAttribute("https://dev.iwanaga.moe/api/email_address")] [ClaimName("https://auth.dev.iwanaga.moe/api/email_address", "https://auth.iwanaga.moe/api/email_address")]
UserEmail = 2, UserEmail = 2,
[ClaimNameAttribute("https://dev.iwanaga.moe/api/email_verified")] [ClaimName("https://auth.dev.iwanaga.moe/api/email_verified", "https://auth.iwanaga.moe/api/email_verified")]
IsEmailConfirmed = 3, IsEmailConfirmed = 3,
[ClaimNameAttribute("https://dev.iwanaga.moe/api/username")] [ClaimName("https://auth.dev.iwanaga.moe/api/username", "https://auth.iwanaga.moe/api/username")]
Username = 4, Username = 4,
[ClaimNameAttribute("https://dev.iwanaga.moe/api/id")] [ClaimName("https://auth.dev.iwanaga.moe/api/id", "https://auth.iwanaga.moe/api/id")]
UserId = 5 UserId = 5
} }
} }

View File

@ -0,0 +1,9 @@
using System;
namespace YABA.Common.Utils
{
public static class EnvironmentUtils
{
public static bool IsDevelopmentEnvironment() => Environment.GetEnvironmentVariable("ASPNETCORE_Environment") == "Development";
}
}

View File

@ -1,6 +1,5 @@
server { server {
listen 80; listen 80;
server_name localhost;
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html; index index.html;
location / { location / {

View File

@ -2,7 +2,6 @@
"name": "yaba-web", "name": "yaba-web",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"homepage": ".",
"dependencies": { "dependencies": {
"@auth0/auth0-react": "^2.0.0", "@auth0/auth0-react": "^2.0.0",
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",

38
docker-compose.yaml Normal file
View File

@ -0,0 +1,38 @@
version: "3"
services:
web:
build:
context: ./Web
dockerfile: Dockerfile
args:
REACT_APP_API_BASE_URL: http://localhost:32270/api
REACT_APP_AUTH0_DOMAIN: iwanaga-dev.us.auth0.com
REACT_APP_AUTH0_CLIENT_ID: ${AUTH0_CLIENT_ID}
REACT_APP_AUTH0_CALLBACK_URL: http://localhost:32271/redirect
REACT_APP_AUTH0_AUDIENCE: https://yaba.dev.iwanaga.moe
container_name: yaba_web
restart: unless-stopped
ports:
- 32271:80
depends_on:
- api
api:
build:
context: ./API
dockerfile: YABA.API/Dockerfile
args:
MODE: Debug
container_name: yaba_api
ports:
- 32270:80
environment:
ASPNETCORE_Environment: Development
ASPNETCORE_Authentication__Auth0__ClientId: ${AUTH0_CLIENT_ID}
ASPNETCORE_Authentication__Auth0__ClientSecret: ${AUTH0_CLIENT_SECRET}
ASPNETCORE_Authentication__Auth0__Domain: iwanaga-dev.us.auth0.com
ASPNETCORE_Authentication__Auth0__Identifier: https://yaba.dev.iwanaga.moe
ASPNETCORE_ConnectionStrings__YABAReadOnlyDbConnectionString: ${RO_CONNECTION_STRING}
ASPNETCORE_ConnectionStrings__YABAReadWriteDbConnectionString: ${RW_CONNECTION_STRING}
WebClient__Url: http://localhost:32271
Serilog__WriteTo__1__Args__Uri: https://loki.iwanaga.moe
Serilog__WriteTo__1__Args__Labels__1__Value: localhost