Skip to content
Andrei edited this page Aug 27, 2025 · 26 revisions

Environment Overview

HintKeep is an app deployed in the cloud using two platforms, Netlify for the frontend and DNS configuration, and Azure for the backend and storage.

Used Services and Features

  • Netlify
    • Account
      • Team
        • Projects (sites)
          • Zip deployments
          • DNS configuration
          • Environment variables
          • Post-processing scripts
  • Azure
    • Entra ID
      • Service Principals
    • Environment Resource Group
      • App Service Plan (shared)
        • Functions App
          • System Managed Identity
        • Storage Account
    • Azure Bicep
    • Zip deployments
  • GitHub
    • Repository
    • Issues
    • Actions
    • Wiki
    • Projects

architecture overview

Setup and Configuration

Prerequisites

Manual Steps

Configure Netlify

Configure Azure

Configure GitHub

Automated Steps

For builds and deployments the project uses GitHub actions. All pipelines are defined in .github/workflows/ as required by the platform.

During deployments, provisioning templates (Azure Bicep) are deployed beforehand to ensure resources are available and properly configured. All related templates and parameter files are located in .infrastructure/.

As part of deployment, Netlify projects (sites) are updated with variables and post-processing scripts. The former are set through the deployment job while the latter are specified in files under .infrastructure/Netlify/Post-Processing Scripts/.

Build

The build is split in two jobs, one that builds the WebClient and the other that builds the GraphQL API. Each job publishes a related artifact containing the deployment files, the artifact itself is a ZIP archive containing the build files. When downloaded, the files are no longer in a ZIP archive and need to be packaged depending on deployment details (ZIP, FTP, git push and so on).

WebClient Build (webpack)

The related package.json file defines several scripts that are used both for local development and to generate release (production) builds.

Release/production builds are minified and have a number of other optimizations applied to them in order to reduce the bundle size as much as possible.

Bundles within the WebClient are optimized further to extract libraries into separate files composed of the library name and content hash allowing browsers to effectively cache the file between deployments. All of these are configured in webpack.config.ts.

GraphQL Build (dotnet)

Although the related directory contains a package.json, the referenced packages and defined scripts are used exclusively for development. The GraphQL application is deployed as an Azure Functions app and requires the SDK to be available when running the application, this is the reason the dotnet watch command needs to be launched through and npm script rather than directly.

All build steps in the pipeline use the dotnet tooling directly, first testing the solution in Debug mode and afterwards publishing the application in Release mode. The key difference is that the GraphQL project contains both the code and the tests where the latter are included only for Debug builds. This configuration allows for both application code and tests to be located in the same project, side-by-side, making it easy to browse and maintain.

Deploy

Deployments are performed using a bottom-up approch assuming that new versions of the application are backwards compatible with the immediate previous version. Non-adjacent versions can contain breaking changes though.

The first step in the deployment is the Azure Bicep deployment which ensures all resources are available and configured. The application uses Azure Functions and Azure Storage Accounts and connects the two through system managed identities, there are no connection strings anywhere in the configuration.

Adding configurations does not harm the current version of the application as these would be values that are simply not read. Azure Table Storage is updated through this step as well, but only by adding missing tables, no tables or records are automatically deleted. Any removal of records or tables needs to be performed manually or through the application by user action or background job.

The second step is GraphQL deployment, once again, there can be no breaking changes introduced with the previous version, the WebClient can continue to work even with the new version as any new definitions that are added are simply not yet used.

Finally, the WebClient is deployed to Netlify in a similar fashion. First, the environment variables and post-process scripts are applied to the target project (site). Once again, these changes are backwards compatible with what is already deployed.

Once the project (site) is configured the app itself is deployed providing a new set of features to users.

At every step, the deployment can fail and only apply halfway, because the deploy version is backwards compatible with the current version, there is no break in functionality. The app continues to work until it has been fully deployed across infrastructures.

HintKeep Development Environment Deployment Flow

Development

To work locally, after cloning the repository run npm install in both GraphQL and WebClient directories to restore related packages, then use the predefined tasks in VS Code to run the application or run npm run azurite and npm run dev npm scripts to launch the GraphQL project and npm run dev for the WebClient.

References

Azure Deployment

Netlify Deployment

Clone this wiki locally