Skip to content

Commit 31b9710

Browse files
committed
feat: Add Azure DevOps pipeline configurations and ARM templates for deployment
- Introduced ARM template for Azure Web App and hosting plan configuration. - Created Azure Pipelines YAML files for CI/CD processes including build, test, and deployment. - Implemented CI build pipeline with .NET Core project build and test steps. - Added GitHub issue templates for bug reports and enhancements. - Established CodeQL and SonarQube workflows for code analysis. - Configured manual workflow for custom triggers. - Enhanced documentation for code review and documentation writing processes. - Updated repository settings and labels for better issue tracking and management.
1 parent db1278c commit 31b9710

24 files changed

+1183
-26
lines changed

.azure/pipelines/arm-template.yml

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"hostingPlanName": {
6+
"type": "string",
7+
"minLength": 1,
8+
"metadata": {
9+
"description": "Name of the hosting plan to use in Azure."
10+
}
11+
},
12+
"appName": {
13+
"type": "string",
14+
"minLength": 1,
15+
"metadata": {
16+
"description": "Name of the Azure Web app to create."
17+
}
18+
},
19+
"skuName": {
20+
"type": "string",
21+
"defaultValue": "F1",
22+
"allowedValues": [
23+
"F1",
24+
"D1",
25+
"B1",
26+
"B2",
27+
"B3",
28+
"S1",
29+
"S2",
30+
"S3",
31+
"P1",
32+
"P2",
33+
"P3",
34+
"P4"
35+
],
36+
"metadata": {
37+
"description": "Describes plan's pricing tier and instance size. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/"
38+
}
39+
},
40+
"skuCapacity": {
41+
"type": "int",
42+
"defaultValue": 1,
43+
"minValue": 1,
44+
"maxValue": 3,
45+
"metadata": {
46+
"description": "Describes plan's instance count"
47+
}
48+
},
49+
"location": {
50+
"type": "string",
51+
"defaultValue": "[resourceGroup().location]",
52+
"metadata": {
53+
"description": "Location for all resources."
54+
}
55+
},
56+
"imageTag": {
57+
"type": "string",
58+
"defaultValue": "latest"
59+
},
60+
"username": {
61+
"type": "string",
62+
"defaultValue": "username"
63+
},
64+
"password": {
65+
"type": "string",
66+
"minLength": 6
67+
}
68+
},
69+
"resources": [
70+
{
71+
"apiVersion": "2018-11-01",
72+
"name": "[parameters('hostingPlanName')]",
73+
"type": "Microsoft.Web/serverfarms",
74+
"location": "[parameters('location')]",
75+
"kind": "linux",
76+
"tags": {
77+
"displayName": "HostingPlan"
78+
},
79+
"sku": {
80+
"name": "[parameters('skuName')]",
81+
"capacity": "[parameters('skuCapacity')]"
82+
},
83+
"properties": {
84+
"name": "[parameters('hostingPlanName')]",
85+
"reserved": true,
86+
"zoneRedundant": false
87+
}
88+
},
89+
{
90+
"apiVersion": "2018-11-01",
91+
"name": "[parameters('appName')]",
92+
"type": "Microsoft.Web/sites",
93+
"location": "[parameters('location')]",
94+
"tags": {
95+
"[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource",
96+
"displayName": "Website"
97+
},
98+
"dependsOn": [
99+
"[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
100+
],
101+
"properties": {
102+
"name": "[parameters('appName')]",
103+
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]",
104+
"siteConfig": {
105+
"appSettings": [
106+
{
107+
"name": "DOCKER_REGISTRY_SERVER_URL",
108+
"value": "https://index.docker.io"
109+
},
110+
{
111+
"name": "DOCKER_REGISTRY_SERVER_USERNAME",
112+
"value": ""
113+
},
114+
{
115+
"name": "DOCKER_REGISTRY_SERVER_PASSWORD",
116+
"value": null
117+
},
118+
{
119+
"name": "WEBSITES_ENABLE_APP_SERVICE_STORAGE",
120+
"value": "false"
121+
},
122+
{
123+
"name": "DISABLE_SIGNUP_WITHOUT_LINK",
124+
"value": "0"
125+
},
126+
{
127+
"name": "LABEL_STUDIO_ONE_CLICK_DEPLOY",
128+
"value": "1"
129+
}
130+
],
131+
"linuxFxVersion": "[concat('DOCKER|heartexlabs/label-studio:', parameters('imageTag'))]",
132+
"appCommandLine": "[concat('label-studio --username ', parameters('username'), ' --password ', parameters('password'))]"
133+
},
134+
"clientAffinityEnabled": false
135+
}
136+
}
137+
]
138+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
variables:
2+
repositoryName: workflow
3+
chartPath: charts/workflow
4+
dockerFileName: src/shipping/workflow/Dockerfile
5+
imageName: $(repositoryName):$(Build.SourceBranchName)
6+
azureSubscription: AZURE_PIPELINES_SERVICE_CONN_NAME_VAR_VAL
7+
azureContainerRegistry: ACR_SERVER_VAR_VAL
8+
azureContainerRegistryName: ACR_NAME_VAR_VAL
9+
10+
name: $(build.sourceBranch)-$(Date:yyyyMMdd)$(Rev:.rr)
11+
12+
pr: # only valid for GitHub. Using Azure repo it must be configure as a Branch Policy
13+
paths:
14+
include:
15+
- /src/shipping/workflow/
16+
17+
branches:
18+
include:
19+
- master
20+
- release/workflow/v* # for bug fixes
21+
22+
trigger:
23+
batch: true
24+
branches:
25+
include:
26+
# for new release to production: release flow strategy
27+
- release/workflow/v*
28+
- refs/relelase/workflow/v*
29+
- master
30+
- feature/workflow/*
31+
- topic/workflow/*
32+
paths:
33+
include:
34+
- /src/shipping/workflow/
35+
36+
resources:
37+
- repo: self
38+
39+
jobs:
40+
# CI
41+
- job: workflowjobci
42+
displayName: "Workflow CI"
43+
pool:
44+
vmImage: "Ubuntu 20.04"
45+
timeoutInMinutes: 90
46+
variables:
47+
fullCI: $[ startsWith(variables['build.sourceBranch'], 'refs/heads/release/workflow/v') ]
48+
buildImage: $[ eq(variables['build.sourceBranch'], 'refs/heads/master') ]
49+
steps:
50+
- task: Docker@1
51+
displayName: "Build testrunner image"
52+
inputs:
53+
azureSubscriptionEndpoint: $(azureSubscription)
54+
azureContainerRegistry: $(azureContainerRegistry)
55+
arguments: "--pull --target testrunner"
56+
dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
57+
imageName: "$(imageName)-test"
58+
59+
- task: Docker@1
60+
displayName: "Run tests"
61+
inputs:
62+
azureSubscriptionEndpoint: $(azureSubscription)
63+
azureContainerRegistry: $(azureContainerRegistry)
64+
command: "run"
65+
containerName: testrunner
66+
volumes: "$(System.DefaultWorkingDirectory)/TestResults:/src/tests/TestResults"
67+
imageName: "$(imageName)-test"
68+
runInBackground: false
69+
70+
- task: PublishTestResults@2
71+
displayName: "Publish test results"
72+
inputs:
73+
testResultsFormat: "VSTest" # Options: JUnit, NUnit, VSTest, xUnit
74+
testResultsFiles: "TestResults/*.trx"
75+
searchFolder: "$(System.DefaultWorkingDirectory)"
76+
publishRunAttachments: true
77+
78+
- task: Docker@1
79+
condition: or(eq(variables['buildImage'],True),eq(variables['fullCI'],True))
80+
displayName: "Build runtime image"
81+
inputs:
82+
azureSubscriptionEndpoint: $(azureSubscription)
83+
azureContainerRegistry: $(azureContainerRegistry)
84+
dockerFile: $(System.DefaultWorkingDirectory)/$(dockerFileName)
85+
includeLatestTag: false
86+
imageName: "$(imageName)"
87+
88+
- task: Docker@1
89+
condition: eq(variables['fullCI'],True)
90+
displayName: "Push runtime image"
91+
inputs:
92+
azureSubscriptionEndpoint: $(azureSubscription)
93+
azureContainerRegistry: $(azureContainerRegistry)
94+
command: "Push an image"
95+
imageName: "$(imageName)"
96+
includeSourceTags: false
97+
98+
- task: HelmInstaller@0
99+
condition: eq(variables['fullCI'],True)
100+
displayName: "Install Helm 3.0.3"
101+
inputs:
102+
helmVersion: 3.0.3
103+
checkLatestHelmVersion: false
104+
kubectlVersion: 1.12.4
105+
checkLatestKubectl: false
106+
107+
- task: HelmDeploy@0
108+
condition: eq(variables['fullCI'],True)
109+
displayName: "helm package"
110+
inputs:
111+
command: package
112+
chartPath: $(chartPath)
113+
chartVersion: $(Build.SourceBranchName)
114+
updateDependency: true
115+
save: false
116+
arguments: "--app-version $(Build.SourceBranchName)"
117+
118+
- task: AzureCLI@1
119+
condition: eq(variables['fullCI'],True)
120+
displayName: "Push a helm package"
121+
inputs:
122+
azureSubscription: $(azureSubscription)
123+
scriptLocation: inlineScript
124+
125+
inlineScript: |
126+
az acr helm push $(System.ArtifactsDirectory)/$(repositoryName)-$(Build.SourceBranchName).tgz --name $(azureContainerRegistryName) --force;

.azure/pipelines/ci-build.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
pool:
2+
name: Azure Pipelines
3+
#Your build pipeline references an undefined variable named ‘Parameters.RestoreBuildProjects’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
4+
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
5+
#Your build pipeline references an undefined variable named ‘Parameters.TestProjects’. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab. See https://go.microsoft.com/fwlink/?linkid=865972
6+
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
7+
#Your build pipeline references the ‘BuildConfiguration’ variable, which you’ve selected to be settable at queue time. Create or edit the build pipeline for this YAML file, define the variable on the Variables tab, and then select the option to make it settable at queue time. See https://go.microsoft.com/fwlink/?linkid=865971
8+
9+
steps:
10+
- task: NuGetAuthenticate@0
11+
displayName: "NuGet Authenticate"
12+
13+
- task: DotNetCoreCLI@2
14+
displayName: "Build projects"
15+
inputs:
16+
projects: "$(Parameters.RestoreBuildProjects)"
17+
arguments: "--configuration $(BuildConfiguration)" # Update this to match your need
18+
19+
# Run the Test (after building)
20+
- task: DotNetCoreCLI@2
21+
displayName: "Run tests"
22+
inputs:
23+
command: "test"
24+
projects: "$(Parameters.TestProjects)"
25+
arguments: "--configuration $(BuildConfiguration)"
26+
27+
# Publish the artifact to be ready for deploy
28+
- task: DotNetCoreCLI@2
29+
displayName: Publish
30+
inputs:
31+
command: "publish"
32+
publishWebProjects: true
33+
arguments: "--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)"
34+
zipAfterPublish: True
35+
36+
- task: PublishBuildArtifacts@1
37+
displayName: "Publish Artifact"
38+
inputs:
39+
pathToPublish: "$(build.artifactstagingdirectory)"
40+
condition: succeededOrFailed()

.azure/pipelines/ci-cd.yml

Whitespace-only changes.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
description: This rule provides comprehensive best practices for developing dotnet applications, covering code organization, security, performance, testing, and common pitfalls. It aims to improve code quality, security posture, and overall efficiency when working with the .NET Core framework.
3+
globs: *.tf,*.bicep,*.json,*.yml,*.yaml,*.cs,*.csproj,*.sln
4+
alwaysApply: false
5+
---
6+
7+
# .NET Core Library Best Practices and Coding Standards
8+
9+
This document outlines the recommended best practices for developing applications and infrastructure using Microsoft .NET Core, Azure DevOps and Azure services. It covers various aspects including solution setup, code organization, security, and tooling to ensure robust, scalable, and secure solutions.
10+
11+
## 1. Code Organization and Structure
12+
13+
A well-organized codebase is crucial for maintainability, scalability, and collaboration. The following guidelines provide a structured approach to organizing your .NET projects.
14+
15+
### Directory Structure Best Practices
16+
17+
Adopt a modular and logical directory structure based on the application's architecture and components.
18+
19+
* **`devops/`**: Contains the root folder for DevOps pipelines for your application.
20+
* **`azure/`**: Contains the source code of Azure DevOps pipelines for your application.
21+
* **`infrastructure/`**: Contains the source code of IaC and platform setup scripts for your application.
22+
* **`bicep/`**: Contains the source code of Bicep templates for your application.
23+
* **`terraform/`**: Contains the source code of Terraform templates for your application.
24+
* **`scripts/`**: Automation scripts for deployment, build processes, etc.
25+
* **`src/`**: Contains the source code of your application.
26+
27+
28+
Example:
29+
30+
root-project/
31+
├── .cursor/
32+
│ └── rules/
33+
├── .git/
34+
├── .github/
35+
│ ├── chatmode
36+
│ ├── instructions
37+
│ └── workflows/
38+
├── devops/
39+
│ └── azure/
40+
├── infrastructure/
41+
│ ├── bicep/
42+
│ └── terraform/
43+
├── scripts/
44+
├── src/
45+
├── .editorconfig
46+
├── .gitattributes
47+
├── .gitignore
48+
├── CHANGELOG.md
49+
├── CODE_OF_CONDUCT.md
50+
├── Directory.Build.props
51+
├── Directory.Build.targets
52+
├── dotnet.ruleset
53+
├── global.json
54+
├── stylecop.json
55+
├── nuget.config
56+
├── project.sln
57+
└── README.md
58+
59+
60+
### File Naming Conventions
61+
62+
Maintain consistency in file naming to improve readability and searchability.
63+
64+
* Use descriptive names that reflect the file's purpose.
65+
* Use a consistent case (e.g., camelCase or kebab-case).
66+
* Use appropriate file extensions (e.g., `.cs`, `.csproj`, `.tf`, `.bicep`).
67+
* For CSharp components, use `ClassName.cs` or `ComponentName.SubComponent.cs`.
68+
69+
Example:
70+
71+
* `user-service.js` (for a user service module)
72+
* `UserProfile.jsx` (for a user profile component)
73+
* `storage-account.tf` (for a Terraform file defining a storage account)
74+
75+
### Module Organization
76+
77+
Divide the application into independent and reusable modules based on functionality.
78+
79+
* Each module should have a clear responsibility and a well-defined interface.
80+
* Minimize dependencies between modules to promote loose coupling.
81+
* Consider using a module bundler (e.g., Webpack, Parcel) to manage dependencies and optimize the build process.
82+
83+
Example:
84+
85+
A `user-management` module could contain components and services related to user authentication, authorization, and profile management.
86+
87+
88+
By following these best practices, you can build robust, scalable, secure, and maintainable .NET applications.

0 commit comments

Comments
 (0)