This repository contains a Blazor-based weather visualization application. It is structured into three main projects, each serving a distinct purpose:
- Backend: Handles server-side logic, including API endpoints and business logic for weather data.
- BlazorUI: A Blazor-based frontend for visualizing weather data and interacting with the backend.
- Tests: Contains unit tests to validate the functionality of the backend and potentially the frontend.
- Languages: C#, CSS, HTML
- Frameworks: ASP.NET Core (Backend), Blazor (Frontend)
- Libraries: xUnit (Testing), Moq (Mocking), Swagger (API Documentation), Bootstrap (Styling)
- Backend provides weather data through APIs.
- BlazorUI visualizes weather data and interacts with the backend.
- Tests ensure the correctness of backend logic and APIs.
This exercise aims to get you familiar with GitHub Copilot by using it to refactor and enhance a Blazor application that visualizes weather data. While all tasks can be done without assistive tooling, you are strongly encouraged to use Copilot for everything first, and only then explore the "manual" way. By the end of this exercise, you should have a better understanding of Copilot's strengths, limitations, and current best uses.
Experiment with all Copilot modes: inline suggestions, chat, and edits. If you have access to Copilot Agents (currently in Visual Studio Insider), feel free to experiment with that as well.
Use Copilot to explore and document the project. Specifically, use Copilot to:
- Identify the major components of the solution
- Determine the programming languages, frameworks, and libraries used, and how they relate to each other
- Generate instructions on how to run and test the application
- (If using Agent mode) Attempt to use Copilot to build and run the application
Example prompts:
- "List the programming languages used in this project"
- "Describe used frameworks and major libraries and their purpose"
- "Describe the purpose of the [Project name] project"
Read the "End goal" section first. Then, use Copilot to break down the end goal into smaller, actionable steps. Document these steps in the end of this readme file.
Example prompts: "List all frontend logic that could be refactored to the backend" "Suggest a plan to refactor a frontend functionality for [feature/functionality name] to move business logic to the backend and visualize data"
The objective is to refactor and add features to the existing application. Use Copilot to assist with each of the following:
-
Implement TDD for Backend: Write tests for all backend code before implementing the actual code
- Follow Test-Driven Development (TDD) principles
- Generate test data with Copilot, if required
- Optional: Test the frontend using a testing framework like bUnit
-
Move Business Logic: Move all existing business logic from the frontend project to the backend.
-
Implement Persistent Storage: If any functionality (outside of tests) uses random data or doesn't store data, move it to a persistent storage solution
- Examples: in-memory database, a file, or a proper database
- Generate initial data and import it into the storage
-
Visualize Weather Data: Create visualizations (e.g., graphs) for the weather page data
-
Dockerize the Application: Create Dockerfiles for both the frontend and backend projects, and document them in the readme
- If you have Docker installed, build and run the application using Docker
-
Infrastructure as Code: Create infrastructure-as-code definitions to run the application on a cloud provider or other infrastructure
- Examples: Use e.g. Terraform, Bicep, or AWS CloudFormation
-
Implement CI/CD: Create CI/CD definition files for your preferred platform (e.g., GitHub Actions, Azure DevOps Pipelines, Jenkins)
- The CI/CD pipeline should automate the build and test process
- Optional: Configure the pipeline to automate deployment
-
Write Tests for Weather Data Retrieval
- Create unit tests for the
WeatherForecastController
to validate theGet
method. - Mock dependencies (e.g.,
ILogger
) to isolate the controller logic.
- Create unit tests for the
-
Implement Weather Data Retrieval
- Implement the
Get
method inWeatherForecastController
to return weather data.
- Implement the
-
Write Tests for Persistent Storage
- Write tests to validate saving and retrieving weather data from a persistent storage solution.
- Mock the storage layer to ensure isolation.
-
Implement Persistent Storage
- Add a persistent storage solution (e.g., in-memory database or file-based storage).
- Implement logic to save and retrieve weather data.
-
Write Tests for Business Logic
- Write unit tests for any business logic that needs to be moved from the frontend to the backend.
- Ensure edge cases are covered.
-
Write Tests for Frontend API Integration
- Use a testing framework like
bUnit
to validate that the frontend correctly calls backend APIs and displays data.
- Use a testing framework like
-
Refactor Frontend to Use Backend Logic
- Update the BlazorUI project to fetch data and rely on backend APIs for business logic. Run tests afterwards.
-
Write Tests for Weather Data Visualization
- Write tests to validate the rendering of weather data visualizations (e.g., graphs).
-
Implement Weather Data Visualization
- Add visualizations (e.g., graphs) to the weather page using a library like Chart.js or similar.
-
Write Tests for Dockerized Environment
- Validate that the application runs correctly in a Dockerized environment (e.g., using integration tests).
-
Create Dockerfiles
- Write Dockerfiles for both the backend and frontend projects.
- Ensure the application can be built and run using Docker.
-
Write Tests for Infrastructure Deployment
- Validate infrastructure definitions using tools like
terraform validate
orbicep build
.
- Validate infrastructure definitions using tools like
-
Create Infrastructure Definitions
- Write infrastructure-as-code definitions (e.g., Terraform, Bicep) to deploy the application to a cloud provider.
- Implement CI/CD Pipeline
- Create CI/CD workflows using GitHub Actions or another platform.
- Automate the build, test, and deployment process.
The project includes a comprehensive CI/CD pipeline implemented using GitHub Actions, which automates the build, test, and deployment process of the Weather Visualization application to Azure.
The CI/CD pipeline consists of three main stages:
-
Build and Test
- Builds the .NET 8 solution
- Runs all unit tests
- Publishes the backend and frontend applications
- Creates build artifacts
-
Build and Push Docker Images
- Deploys Azure infrastructure using Bicep templates
- Builds Docker images for both backend and frontend
- Pushes images to Azure Container Registry (ACR)
-
Deploy to Azure
- Updates the container apps to use the latest images
- Outputs the deployment URLs
The pipeline is triggered by:
- Pushes to main/master branches
- Pull requests to main/master branches
- Manual workflow dispatch (with environment selection)
To use this CI/CD pipeline, the following secrets need to be configured in your GitHub repository:
AZURE_CREDENTIALS
: Azure service principal credentials for authenticationACR_USERNAME
: Username for Azure Container RegistryACR_PASSWORD
: Password for Azure Container Registry
-
Create an Azure service principal:
az ad sp create-for-rbac --name "GitHubActions" --role contributor --scopes /subscriptions/<subscription-id> --sdk-auth
-
Copy the JSON output and add it as a repository secret named
AZURE_CREDENTIALS
. -
After deploying the infrastructure, retrieve and set the ACR credentials:
az acr credential show --name <acr-name> --resource-group weather-app-rg
-
Add the username and password as secrets named
ACR_USERNAME
andACR_PASSWORD
.
The pipeline uses the following environment variables:
DOTNET_VERSION
: Set to '8.0.x' for .NET 8 LTSRESOURCE_GROUP
: Azure resource group (default: weather-app-rg)LOCATION
: Azure region (default: uksouth)NAME_PREFIX
: Resource name prefix (default: weather)
These can be modified directly in the workflow file if needed.