From 4e9f1dff5cb69d2468929b3e08f638228ff9b3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rasmus=20Lystr=C3=B8m?= Date: Sat, 24 Aug 2024 15:20:25 +0200 Subject: [PATCH] Add lint and dependabot (#7) * Add lint and dependabot --- .github/dependabot.yml | 12 ++++ .github/linters/.checkov.yaml | 6 ++ .github/linters/yaml-lint.yml | 48 ++++++++++++++ .github/workflows/application.yml | 19 +++--- .github/workflows/infrastructure.yml | 23 +++---- .github/workflows/lint.yml | 48 ++++++++++++++ .vscode/extensions.json | 18 +++--- .vscode/settings.json | 33 +++++----- README.md | 80 +++++++++++++----------- src/MyApp/Properties/launchSettings.json | 36 +++++------ 10 files changed, 226 insertions(+), 97 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/linters/.checkov.yaml create mode 100644 .github/linters/yaml-lint.yml create mode 100644 .github/workflows/lint.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2e5bd6b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +--- +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + + - package-ecosystem: nuget + directory: / + schedule: + interval: weekly diff --git a/.github/linters/.checkov.yaml b/.github/linters/.checkov.yaml new file mode 100644 index 0000000..c8be3a6 --- /dev/null +++ b/.github/linters/.checkov.yaml @@ -0,0 +1,6 @@ +--- +quiet: true +skip-check: + - CKV_AZURE_35 # Ensure default network access rule for storage accounts is set to deny + - CKV_AZURE_59 # Ensure that storage accounts disallow public access + - CKV_AZURE_109 # Ensure that key vault allows firewall rules settings diff --git a/.github/linters/yaml-lint.yml b/.github/linters/yaml-lint.yml new file mode 100644 index 0000000..87326f3 --- /dev/null +++ b/.github/linters/yaml-lint.yml @@ -0,0 +1,48 @@ +--- +rules: + braces: + forbid: true + level: error + brackets: + forbid: true + level: error + colons: + level: error + commas: + level: error + comments: + level: error + comments-indentation: + level: error + document-end: + present: false + level: error + document-start: + present: true + level: error + empty-lines: + max: 1 + level: error + empty-values: disable + hyphens: + level: error + indentation: + spaces: 2 + level: error + key-duplicates: + level: error + key-ordering: disable + line-length: disable + new-line-at-end-of-file: + level: error + new-lines: + type: unix + level: error + octal-values: disable + quoted-strings: + quote-type: single + required: only-when-needed + trailing-spaces: + level: error + truthy: + level: error diff --git a/.github/workflows/application.yml b/.github/workflows/application.yml index b2f4a49..ca4bcbf 100644 --- a/.github/workflows/application.yml +++ b/.github/workflows/application.yml @@ -4,18 +4,21 @@ name: Application on: push: branches: - - main + - main paths: - - .github/workflows/application.yml - - src/** - - tests/** + - .github/workflows/application.yml + - src/** + - tests/** pull_request: branches: - - main + - main paths: - - .github/workflows/application.yml - - src/** - - tests/** + - .github/workflows/application.yml + - src/** + - tests/** + workflow_dispatch: {} + +permissions: {} jobs: build: diff --git a/.github/workflows/infrastructure.yml b/.github/workflows/infrastructure.yml index a0862c4..4951d8f 100644 --- a/.github/workflows/infrastructure.yml +++ b/.github/workflows/infrastructure.yml @@ -1,19 +1,22 @@ --- name: Infrastructure -on: +"on": push: branches: - - main + - main paths: - - .github/workflows/infrastructure.yml - - infrastructure/** + - .github/workflows/infrastructure.yml + - infrastructure/** pull_request: branches: - - main + - main paths: - - .github/workflows/infrastructure.yml - - infrastructure/** + - .github/workflows/infrastructure.yml + - infrastructure/** + workflow_dispatch: {} + +permissions: {} jobs: build: @@ -29,14 +32,12 @@ jobs: runs-on: ubuntu-latest needs: build if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request' + environment: Staging + permissions: id-token: write - environment: Staging steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Azure Login uses: azure/login@v2 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..acaa1f4 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,48 @@ +--- +name: Lint + +"on": + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: {} + +permissions: {} + +jobs: + build: + name: Lint + runs-on: ubuntu-latest + + permissions: + contents: read + packages: read + # To report GitHub Actions status checks + statuses: write + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + # super-linter needs the full git history to get the + # list of files that changed across commits + fetch-depth: 0 + + - name: Super-Linter + uses: super-linter/super-linter@v7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VALIDATE_CSS: false + VALIDATE_CSS_PRETTIER: false + VALIDATE_JSON_PRETTIER: false + + - name: Lint Bicep Files + run: | + Get-ChildItem -Filter "*.bicep*" -Recurse | ForEach-Object { + Write-Output "Linting $PSItem" + az bicep lint --file $PSItem + } + shell: pwsh diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0eb00b7..f2afe9d 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,11 +1,11 @@ { - "recommendations": [ - "davidanson.vscode-markdownlint", - "ms-vscode.azure-account", - "ms-azuretools.vscode-bicep", - "ms-dotnettools.vscodeintellicode-csharp", - "ms-azuretools.vscode-azureappservice", - "redhat.vscode-yaml", - "streetsidesoftware.code-spell-checker" - ] + "recommendations": [ + "davidanson.vscode-markdownlint", + "ms-vscode.azure-account", + "ms-azuretools.vscode-bicep", + "ms-dotnettools.vscodeintellicode-csharp", + "ms-azuretools.vscode-azureappservice", + "redhat.vscode-yaml", + "streetsidesoftware.code-spell-checker" + ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 6706d3f..d563dff 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,17 +1,20 @@ { - "cSpell.enabled": true, - "cSpell.language": "en", - "cSpell.enableFiletypes": [ - "*" - ], - "cSpell.words": [ - "azcliversion" - ], - "editor.trimAutoWhitespace": true, - "files.autoSave": "afterDelay", - "files.trimFinalNewlines": true, - "files.trimTrailingWhitespace": true, - "[github-actions-workflow]": { - "editor.tabSize": 2 - } + "cSpell.enabled": true, + "cSpell.language": "en", + "cSpell.enableFiletypes": [ + "*" + ], + "cSpell.words": [ + "ASPNETCORE", + "azcliversion", + "Entra", + "pwsh" + ], + "editor.trimAutoWhitespace": true, + "files.autoSave": "afterDelay", + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "[github-actions-workflow]": { + "editor.tabSize": 2 + } } \ No newline at end of file diff --git a/README.md b/README.md index a61a6f3..83c042f 100644 --- a/README.md +++ b/README.md @@ -2,59 +2,67 @@ This project demonstrates a number of capabilities in Azure DevOps and Microsoft Azure: -- Continuous Planning using *GitHub Issues* -- Continuous Integration using *GitHub Repositories* and *GitHub Actions* -- Continuous Deployment to *App Services* and *Azure SQL* using *GitHub Actions* -- Continuous Security using *GitHub Advanced Security* -- Continuous Monitoring using *Azure Monitor* and *Application Insights* -- Continuous Quality using unit tests and *GitHub Actions* -- Database migration using *Entity Framework* and *GitHub Actions* -- Blue/green deployments to *App Services* using *Deployment Slots* +- Continuous Planning using _GitHub Issues_ +- Continuous Integration using _GitHub Repositories_ and _GitHub Actions_ +- Continuous Deployment to _App Services_ and _Azure SQL_ using _GitHub Actions_ +- Continuous Security using _GitHub Advanced Security_ +- Continuous Monitoring using _Azure Monitor_ and _Application Insights_ +- Continuous Quality using unit tests and _GitHub Actions_ +- Database migration using _Entity Framework_ and _GitHub Actions_ +- Blue/green deployments to _App Services_ using _Deployment Slots_ ## Prerequisites -1. Create a *Microsoft Entra application (SPN)* and connect it to *GitHub* cf. . +1. Create a _Microsoft Entra application (SPN)_ and connect it to _GitHub_ cf. . 1. Create SQL admin group: - ```bash - GROUP="Movie Database Admins" - GROUP_MAIL_NICKNAME=movie-database-admins - az ad group create --display-name "$GROUP" --mail-nickname $GROUP_MAIL_NICKNAME - ``` + ```bash + GROUP="Movie Database Admins" + GROUP_MAIL_NICKNAME=movie-database-admins + az ad group create --display-name "$GROUP" --mail-nickname $GROUP_MAIL_NICKNAME + ``` 1. Add yourself to the group: - ```bash - ME=$(az ad signed-in-user show --query id --output tsv) - az ad group member add --group "$GROUP" --member-id $ME - ``` + ```bash + ME=$(az ad signed-in-user show --query id --output tsv) + az ad group member add --group "$GROUP" --member-id $ME + ``` -1. Add the *SPN* to the group. +1. Add the _SPN_ to the group. 1. Update [`/infrastructure/main.bicepparam`](/infrastructure/main.bicepparam). -1. Deploy the *infrastructure* pipeline +1. Deploy the _infrastructure_ pipeline 1. Connect web app to SQL database, - **Notes**: + **Notes**: - - Commands must be run in *Azure Cloud Shell* as the SQL Server firewall is configured to block requests from outside Azure. - - When running the commands, answer `n` to the question *"Do you want to set current user as Entra admin? (y/n)"* + - Commands must be run in _Azure Cloud Shell_ as the SQL Server firewall is configured to block requests from outside Azure. + - When running the commands, answer `n` to the question _"Do you want to set current user as Entra admin? (y/n)"_ - ```bash - RESOURCE_GROUP=MyWebApp2 - SQL_SERVER=sql-968b52419901 - WEBAPP=web-968b52419901 - DATABASE=Movies + ```bash + RESOURCE_GROUP=MyWebApp2 + SQL_SERVER=sql-968b52419901 + WEBAPP=web-968b52419901 + DATABASE=Movies - az webapp connection create sql --resource-group $RESOURCE_GROUP --name $WEBAPP --target-resource-group $RESOURCE_GROUP --server $SQL_SERVER --database $DATABASE --system-identity --client-type dotnet --connection $DATABASE # --config-connstr (in preview; to be enabled later) + az webapp connection create sql --resource-group $RESOURCE_GROUP --name $WEBAPP --target-resource-group $RESOURCE_GROUP --server $SQL_SERVER --database $DATABASE --system-identity --client-type dotnet --connection $DATABASE # --config-connstr (in preview; to be enabled later) - SLOT=staging - SLOT_DATABASE=MoviesStaging + SLOT=staging + SLOT_DATABASE=MoviesStaging - az webapp connection create sql --resource-group $RESOURCE_GROUP --name $WEBAPP --slot $SLOT --target-resource-group $RESOURCE_GROUP --server $SQL_SERVER --database $SLOT_DATABASE --system-identity --client-type dotnet --connection $SLOT_DATABASE # --config-connstr (in preview; not working for deployment slots yet) - ``` + az webapp connection create sql --resource-group $RESOURCE_GROUP --name $WEBAPP --slot $SLOT --target-resource-group $RESOURCE_GROUP --server $SQL_SERVER --database $SLOT_DATABASE --system-identity --client-type dotnet --connection $SLOT_DATABASE # --config-connstr (in preview; not working for deployment slots yet) + ``` 1. Before running the app locally; apply migrations on the local database: - ```bash - dotnet ef database update - ``` + ```bash + dotnet ef database update + ``` + +## Notes + +To lint codebase locally you can run [Super-Linter](https://github.com/super-linter/super-linter): + +```bash +docker run -e LOG_LEVEL=DEBUG -e RUN_LOCAL=true -e DEFAULT_BRANCH=main -e VALIDATE_CSS=false -e VALIDATE_CSS_PRETTIER=false -e -v .:/tmp/lint ghcr.io/super-linter/super-linter:latest +``` diff --git a/src/MyApp/Properties/launchSettings.json b/src/MyApp/Properties/launchSettings.json index 9daf762..5a8bf7f 100644 --- a/src/MyApp/Properties/launchSettings.json +++ b/src/MyApp/Properties/launchSettings.json @@ -1,23 +1,23 @@ { "$schema": "https://json.schemastore.org/launchsettings.json", - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "http://localhost:5253", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7083;http://localhost:5253", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5253", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7083;http://localhost:5253", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" } } } +}