Skip to content

Commit 601fe9b

Browse files
committed
Fix some other deployment related bugs
1 parent 63125d8 commit 601fe9b

10 files changed

Lines changed: 46 additions & 32 deletions

File tree

CruSibyl.Core/Configuration/DBContextConfig.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,27 @@ public static class DBContextConfig
1010
public static void Configure(IConfiguration configuration, IServiceCollection services, out bool migrationScaffoldRequested)
1111
{
1212
// Migration scaffolding in EF Core 8 appears to instantiate a DbContext, so we're using
13-
// an environment variable set by CreateMigration.sh to ensure the correct provider is used.
14-
var migrationUseSql = configuration.GetValue<bool?>("Migration:UseSql");
15-
var useSql = migrationUseSql.HasValue ? migrationUseSql.Value : configuration.GetValue<bool>("Dev:UseSql");
13+
// an environment variable set by CreateMigration.sh to opt into Sqlite when needed.
14+
var migrationUseSqlite = configuration.GetValue<bool?>("Migration:UseSqlite");
15+
var useSqlite = migrationUseSqlite.HasValue ? migrationUseSqlite.Value : configuration.GetValue<bool>("Dev:UseSqlite");
1616

17-
if (useSql)
17+
if (useSqlite)
1818
{
19-
services.AddDbContextPool<AppDbContext, AppDbContextSqlServer>(ConfigSqlServer(configuration));
20-
services.AddDbContextFactory<AppDbContextSqlServer>(ConfigSqlServer(configuration));
19+
services.AddDbContextPool<AppDbContext, AppDbContextSqlite>(ConfigSqlite(configuration));
20+
services.AddDbContextFactory<AppDbContextSqlite>(ConfigSqlite(configuration));
2121
services.AddScoped<IDbContextFactory<AppDbContext>>(sp =>
22-
new DbContextFactoryAdapter<AppDbContextSqlServer>(sp.GetRequiredService<IDbContextFactory<AppDbContextSqlServer>>()));
22+
new DbContextFactoryAdapter<AppDbContextSqlite>(sp.GetRequiredService<IDbContextFactory<AppDbContextSqlite>>()));
2323
}
2424
else
2525
{
26-
services.AddDbContextPool<AppDbContext, AppDbContextSqlite>(ConfigSqlite(configuration));
27-
services.AddDbContextFactory<AppDbContextSqlite>(ConfigSqlite(configuration));
26+
services.AddDbContextPool<AppDbContext, AppDbContextSqlServer>(ConfigSqlServer(configuration));
27+
services.AddDbContextFactory<AppDbContextSqlServer>(ConfigSqlServer(configuration));
2828
services.AddScoped<IDbContextFactory<AppDbContext>>(sp =>
29-
new DbContextFactoryAdapter<AppDbContextSqlite>(sp.GetRequiredService<IDbContextFactory<AppDbContextSqlite>>()));
29+
new DbContextFactoryAdapter<AppDbContextSqlServer>(sp.GetRequiredService<IDbContextFactory<AppDbContextSqlServer>>()));
3030
}
3131

3232
// A null value indicates that no migration scaffold has been requested.
33-
migrationScaffoldRequested = migrationUseSql.HasValue;
33+
migrationScaffoldRequested = migrationUseSqlite.HasValue;
3434
}
3535

3636
static Action<IServiceProvider, DbContextOptionsBuilder> ConfigSqlServer(IConfiguration configuration)
@@ -63,4 +63,4 @@ static Action<IServiceProvider, DbContextOptionsBuilder> ConfigSqlite(IConfigura
6363
#endif
6464
};
6565
}
66-
}
66+
}

CruSibyl.Core/CreateMigration.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[ "$#" -eq 1 ] || { echo "1 argument required, $# provided. Useage: sh CreateMigration <MigrationName>"; exit 1; }
22

3-
export Migration__UseSql=false
3+
export Migration__UseSqlite=true
44
dotnet ef migrations add $1 --context AppDbContextSqlite --output-dir Migrations/Sqlite --project CruSibyl.Core.csproj --startup-project ../CruSibyl.Web/CruSibyl.Web.csproj -- --provider Sqlite
5-
export Migration__UseSql=true
5+
export Migration__UseSqlite=false
66
dotnet ef migrations add $1 --context AppDbContextSqlServer --output-dir Migrations/SqlServer --project CruSibyl.Core.csproj --startup-project ../CruSibyl.Web/CruSibyl.Web.csproj -- --provider SqlServer
77
# usage from PM console in the CruSibyl.Core directory: ./CreateMigration.sh <MigrationName>
88

9-
echo 'All done';
9+
echo 'All done';

CruSibyl.Functions/WebJobStatusSyncFunction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public WebJobStatusSyncFunction(
2424
_azureSettings = azureSettings.Value;
2525
}
2626

27-
[Function("WebJobStatusSyncFunction_Timer")]
27+
[Function("WebJobStatusSyncFunction")]
2828
public async Task RunTimer(
2929
[TimerTrigger("0 */15 * * * *")] TimerInfo timerInfo,
3030
CancellationToken cancellationToken)

CruSibyl.Functions/appsettings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@
1616
"Enabled": false
1717
}
1818
}
19+
},
20+
"Dev": {
21+
"UseSqlite": "false"
1922
}
2023
}

CruSibyl.Functions/local.settings.json.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
"AzureWebJobs.AppWebJobSyncFunction.Disabled": "true",
77
"AzureWebJobs.ManifestSyncFunction.Disabled": "true",
88
"AzureWebJobs.PackageVersionSyncFunction.Disabled": "true",
9-
"AzureWebJobs.WebJobStatusSyncFunction_Timer.Disabled": "true"
9+
"AzureWebJobs.WebJobStatusSyncFunction.Disabled": "true"
1010
}
1111
}

CruSibyl.Web/appsettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@
2626
"Dev": {
2727
"RecreateDb": "false",
2828
"InitializeDb": "true",
29-
"UseSql": "true"
29+
"UseSqlite": "false"
3030
}
3131
}

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ variables:
3636
deployInfra: 'false'
3737
WEB_APP_SETTINGS_JSON: '[]'
3838
FUNCTION_APP_SETTINGS_JSON: '[]'
39-
EXPECTED_FUNCTIONS: 'AppWebJobSyncFunction,ManifestSyncFunction,PackageVersionSyncFunction,WebJobStatusSyncFunction_Timer'
39+
EXPECTED_FUNCTIONS: 'AppWebJobSyncFunction,ManifestSyncFunction,PackageVersionSyncFunction,WebJobStatusSyncFunction'
4040

4141
stages:
4242
- stage: Build

infrastructure/azure/README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Notes:
110110
- `WEB_APP_NAME` and `FUNCTION_APP_NAME` are only strictly required when `deployInfra=false` and the pipeline cannot look up names from a prior Bicep deployment output.
111111
- `SQL_ADMIN_LOGIN` and `SQL_ADMIN_PASSWORD` are only required when `deployInfra=true`.
112112
- `WEB_APP_SETTINGS_JSON` and `FUNCTION_APP_SETTINGS_JSON` default to `[]` in the pipeline and are meant to hold Azure App Service settings payloads.
113-
- `EXPECTED_FUNCTIONS` defaults to the current timer functions: `AppWebJobSyncFunction,ManifestSyncFunction,PackageVersionSyncFunction,WebJobStatusSyncFunction_Timer`.
113+
- `EXPECTED_FUNCTIONS` defaults to the current timer functions: `AppWebJobSyncFunction,ManifestSyncFunction,PackageVersionSyncFunction,WebJobStatusSyncFunction`.
114114

115115
Example `WEB_APP_SETTINGS_JSON` value:
116116

@@ -120,12 +120,12 @@ Example `WEB_APP_SETTINGS_JSON` value:
120120
{ "name": "Authentication__ClientSecret", "value": "$(AUTHENTICATION_CLIENT_SECRET)", "slotSetting": false },
121121
{ "name": "Authentication__Authority", "value": "https://cas.ucdavis.edu/cas/oidc", "slotSetting": false },
122122
{ "name": "Authentication__IamKey", "value": "$(AUTHENTICATION_IAM_KEY)", "slotSetting": false },
123-
{ "name": "Azure__Subscriptions__CAES-Test__SubscriptionId", "value": "$(CAES_TEST_SUBSCRIPTION_ID)", "slotSetting": false },
124-
{ "name": "Azure__Subscriptions__CAES-Test__Enabled", "value": "true", "slotSetting": false },
125-
{ "name": "Azure__Subscriptions__CAES-Test__Default", "value": "true", "slotSetting": false },
126-
{ "name": "Azure__Subscriptions__CAES-Prod__SubscriptionId", "value": "$(CAES_PROD_SUBSCRIPTION_ID)", "slotSetting": false },
127-
{ "name": "Azure__Subscriptions__CAES-Prod__Enabled", "value": "true", "slotSetting": false },
128-
{ "name": "Azure__Subscriptions__CAES-Prod__Default", "value": "false", "slotSetting": false },
123+
{ "name": "Azure__Subscriptions__CAESTest__SubscriptionId", "value": "$(CAES_TEST_SUBSCRIPTION_ID)", "slotSetting": false },
124+
{ "name": "Azure__Subscriptions__CAESTest__Enabled", "value": "true", "slotSetting": false },
125+
{ "name": "Azure__Subscriptions__CAESTest__Default", "value": "true", "slotSetting": false },
126+
{ "name": "Azure__Subscriptions__CAESProd__SubscriptionId", "value": "$(CAES_PROD_SUBSCRIPTION_ID)", "slotSetting": false },
127+
{ "name": "Azure__Subscriptions__CAESProd__Enabled", "value": "true", "slotSetting": false },
128+
{ "name": "Azure__Subscriptions__CAESProd__Default", "value": "false", "slotSetting": false },
129129
{ "name": "Serilog__Environment", "value": "$(ENVIRONMENT)", "slotSetting": false },
130130
{ "name": "Serilog__ElasticUrl", "value": "$(SERILOG_ELASTIC_URL)", "slotSetting": false }
131131
]
@@ -137,18 +137,19 @@ Example `FUNCTION_APP_SETTINGS_JSON` value:
137137
[
138138
{ "name": "GitHub__RepoOwner", "value": "ucdavis", "slotSetting": false },
139139
{ "name": "GitHub__AccessToken", "value": "$(GITHUB_ACCESS_TOKEN)", "slotSetting": false },
140-
{ "name": "Azure__Subscriptions__CAES-Test__SubscriptionId", "value": "$(CAES_TEST_SUBSCRIPTION_ID)", "slotSetting": false },
141-
{ "name": "Azure__Subscriptions__CAES-Test__Enabled", "value": "true", "slotSetting": false },
142-
{ "name": "Azure__Subscriptions__CAES-Prod__SubscriptionId", "value": "$(CAES_PROD_SUBSCRIPTION_ID)", "slotSetting": false },
143-
{ "name": "Azure__Subscriptions__CAES-Prod__Enabled", "value": "true", "slotSetting": false },
140+
{ "name": "Azure__Subscriptions__CAESTest__SubscriptionId", "value": "$(CAES_TEST_SUBSCRIPTION_ID)", "slotSetting": false },
141+
{ "name": "Azure__Subscriptions__CAESTest__Enabled", "value": "true", "slotSetting": false },
142+
{ "name": "Azure__Subscriptions__CAESProd__SubscriptionId", "value": "$(CAES_PROD_SUBSCRIPTION_ID)", "slotSetting": false },
143+
{ "name": "Azure__Subscriptions__CAESProd__Enabled", "value": "true", "slotSetting": false },
144144
{ "name": "Serilog__Environment", "value": "$(ENVIRONMENT)", "slotSetting": false },
145145
{ "name": "Serilog__ElasticUrl", "value": "$(SERILOG_ELASTIC_URL)", "slotSetting": false }
146146
]
147147
```
148148

149149
## Notes
150150

151-
- Resource names default to deterministic values derived from app name, environment, and resource group.
151+
- Resource names default to deterministic values derived from app name, environment, and resource group. The Web App defaults are `crusibyl-test` for test and `crusibyl` for prod unless explicitly overridden.
152152
- Monitoring is enabled by default and can be disabled with `DEPLOY_MONITORING=false`.
153153
- The Function App currently uses the SQL connection string via `ConnectionStrings__DefaultConnection`.
154+
- The Function App allows `https://portal.azure.com` in CORS so HTTP-trigger functions can be invoked from the Azure portal.
154155
- The pipeline template validates host health plus registered function names, which is our first-pass check that timer triggers synced after deployment.

infrastructure/azure/main.bicep

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,10 @@ param assignResourceGroupReader bool = false
7171
var appSlug = toLower(replace(replace(replace(appName, '-', ''), '_', ''), ' ', ''))
7272
var envSlug = toLower(replace(replace(env, '-', ''), ' ', ''))
7373
var nameToken = substring(uniqueString(resourceGroup().id, appName, env), 0, 6)
74+
var defaultWebAppName = env == 'prod' ? appSlug : '${appSlug}-${envSlug}'
7475

7576
var resolvedAppServicePlanName = appServicePlanName == '' ? toLower('asp-${appSlug}-${envSlug}-${nameToken}') : appServicePlanName
76-
var resolvedWebAppName = webAppName == '' ? toLower('web-${appSlug}-${envSlug}-${nameToken}') : toLower(webAppName)
77+
var resolvedWebAppName = webAppName == '' ? defaultWebAppName : toLower(webAppName)
7778
var resolvedFunctionAppName = functionAppName == '' ? toLower('fn-${appSlug}-${envSlug}-${nameToken}') : toLower(functionAppName)
7879

7980
var storageNameToken = nameToken

infrastructure/azure/modules/compute.bicep

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ param appInsightsConnectionString string = ''
3939
@description('Application Insights instrumentation key (optional).')
4040
param appInsightsInstrumentationKey string = ''
4141

42+
@description('Allowed CORS origins for the Function App.')
43+
param functionAppCorsAllowedOrigins array = [
44+
'https://portal.azure.com'
45+
]
46+
4247
resource sharedPlan 'Microsoft.Web/serverfarms@2025-03-01' = {
4348
name: planName
4449
location: location
@@ -107,6 +112,10 @@ resource functionApp 'Microsoft.Web/sites@2025-03-01' = {
107112
ftpsState: 'FtpsOnly'
108113
linuxFxVersion: 'DOTNET-ISOLATED|8.0'
109114
minTlsVersion: '1.2'
115+
cors: {
116+
allowedOrigins: functionAppCorsAllowedOrigins
117+
supportCredentials: false
118+
}
110119
appSettings: concat([
111120
{
112121
name: 'AZURE_FUNCTIONS_ENVIRONMENT'

0 commit comments

Comments
 (0)