Continuous integration¶
Note
This is an advanced topic that is closely tied with the further development and customization of the nRF Asset Tracker for your purposes. See the GitHub project page of the nRF Asset Tracker for Azure for an implementation of the process outlined in this section.
Continuous integration involves the following actions:
- Every change to the project is tested against an Azure account, which must be manually prepared.
- A Behavior Driven Development (BDD) test suite of end-to-end tests is run. The test suite is written in Gherkin, which describes the tests in English.
In this way, the tests are not tied to the implementation and you cannot accidentally drop tests during refactoring. Tests written for test runners like Jest tend to be closely tied to the API of the source code implementation. In the case of a larger refactoring, the tests often need to be refactored as well. Since the BDD tests are purely testing based on the public API of the project (which is a mix of the native Azure API and a custom REST API), they can be kept unchanged during refactoring.
Prepare your Azure account¶
Note
The setup process in Azure is more complicated when compared to the AWS continuous integration setup since it involves many manual steps, which cannot be automated. If you have ideas to simplify the process, provide your input.
Log in and create the resource group¶
To create the resource group for the CI resources, complete the following steps:
Log in to the shell:
az login
Export the identifier of the subscription that contains the nRF Asset Tracker resources:
export SUBSCRIPTION_ID="subscription id"
Make sure that you have enabled the correct subscription by using the following commands:
az account set --subscription $SUBSCRIPTION_ID # Verify that it is set to default az account list --output table
Choose a resource group name for the solution and export it as
RESOURCE_GROUP
. In this example,nrfassettrackerci
is used as the resource group name.export RESOURCE_GROUP="nrfassettrackerci"
Choose a name for the solution and export it as
APP_NAME
. Use a short name (not more than 16 characters) composed of numbers and lowercase letters only. In this example,nrfassettrackerci
is used as the application name.export APP_NAME="nrfassettrackerci"
Configure your preferred location (you can list the locations using
az account list-locations
) and export it on the environment variableLOCATION
. In this example,northeurope
is used as the location name.export LOCATION="northeurope"
Create a resource group for the CI resources:
az group create --name ${RESOURCE_GROUP:-nrfassettrackerci} --location ${LOCATION:-northeurope}
Create a secondary tenant (Azure Active Directory B2C)¶
Create an Azure Active Directory B2C. Currently, it is not possible to create an Active Directory B2C and application through the ARM template (see GitHub issue).
Follow the instructions in the tutorial for creating an Azure Active Directory B2C tenant and create a B2C tenant.
Follow the instructions in the tutorial for setting up a resource owner password credentials flow in Azure Active Directory B2C and register an application. Make sure to set the following parameters:
Set the Supported account types to All users
Update the Azure Active Directory app manifest and allow implicit grant flow for OAuth2:
{"oauth2AllowImplicitFlow": true}
Export the initial domain name that you used:
export B2C_TENANT="Initial domain name" # For example, "nrfassettrackerciusers"
Export the Application (client) ID and the Directory (tenant) ID of the created Active Directory B2C App:
export APP_REG_CLIENT_ID="Application (client) id" export B2C_TENANT_ID="Directory (tenant) ID"
For enabling the test-runner to programmatically log in users, enable the resource owner password credentials (ROPC) flow with the following settings on the Active Directory B2C:
- Name -
B2C_1_developer
. - Click Application claims, select Show more … and then mark Email Addresses as a return claim.
- Name -
Grant the B2C directory API permissions for authenticating users:
- In the left menu, under Manage, select API permissions. Add the permission to manage user accounts (Microsoft Graph -> Application permission -> User.ReadWrite.All).
Grant the B2C directory API permissions for the function app:
- Click Expose an API and set the Application ID URI field to
api
. - Click + Add a scope and create a new scope with the following values and click Add a scope:
- Scope name -
nrfassettracker.admin
- Admin consent display name - Administrator access to the nRF Asset Tracker API
- Admin consent description - Allows administrator access to all resources exposed through the nRF Asset Tracker API
- Scope name -
- Click API permissions and then click + Add a permission. Under My APIs, select the app registration.
- Enable the
nrfassettracker.admin
permission and click Add permission.
- Click Expose an API and set the Application ID URI field to
Click Grant admin consent for <your B2C directory>.
Create a new client secret for the App registration (for example,
12OzW72ie-U.vlmzik-eO5gX.x26jLTI6U
) and note it down.export B2C_CLIENT_SECRET="client secret"
Link this Azure AD B2C tenant to the subscription for CI by following the Billing guide.
Set up continuous integration on GitHub¶
Create the CI credentials:
az ad sp create-for-rbac --name 'https://nrfassettracker.invalid/ci' \ --role contributor \ --scopes \ "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP:-nrfassettracker}"\ --sdk-auth \ > ci-credentials.json
Fork the nRF Asset Tracker for Azure project.
Add the following secrets to an environment called
ci
:RESOURCE_GROUP
APP_REG_CLIENT_ID
AZURE_CREDENTIALS
(the contents ofci-credentials.json
)B2C_CLIENT_SECRET
B2C_TENANT_ID
APP_NAME
B2C_TENANT
Commit and push a change¶
Now, commit and push a change to your repository. This will trigger the CI run.
You can also manually trigger a deployment on the Test and Release workflow.
Running the solution during development¶
To run the end-to-end tests against the solution during development, run the following commands:
# Install dependencies
npm ci
# One time operation: create an intermediate CA certificate
node cli create-ca-root
node cli proof-ca-root-possession
node cli create-ca-intermediate
# Run tests
npm run test:e2e
Note
Azure functions allow only one Client ID and Issuer URL in the Active Directory authentication configuration. So, you cannot interact with this instance from the end-to-end tests and the web application since the user flow name differs (B2C_1_developer
for end-to-end tests and B2C_1_signup_signin
for the web application) and it is part of the Issuer URL (for example, https://${TENANT_DOMAIN}.b2clogin.com/${TENANT_DOMAIN}.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_developer
).