Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Replace AppCenter in favor of Firebase App Distribution in UnoA… #420

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions .azure-pipelines-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,17 @@ stages:
removeHyperlinksFromReleaseNotes: true
BannerVersionNameText: "CANARY"

- stage: AppCenter_TestFlight_Canary
- stage: FirebaseDistribution_TestFlight_Canary
condition: and(succeeded(), eq(variables['IsCanary'], 'true'))
dependsOn: Build_Canary

jobs:
- template: build/stage-release-appcenter.yml
- template: build/stage-release-firebase-app-distribution.yml
parameters:
applicationEnvironment: Staging
deploymentEnvironment: AppCenter
appCenterWindowsSlug: $(AppCenterWindowsSlug_Canary)
appCenteriOSSlug: $(AppCenteriOSSlug_Canary)
appCenterAndroidSlug: $(AppCenterAndroidSlug_Canary)
androidKeyStoreFile: $(InternalKeystore)
deploymentEnvironment: Firebase App Distribution
androidVariableGroup: 'ApplicationTemplate.Distribution.Internal.Android'
appCenterServiceConnectionName: $(AppCenterCanaryServiceConnection)
appCenterDistributionGroup: $(AppCenterCanaryDistributionGroup)
serviceConnectionKeyFileName: $(FirebaseAppDistributionServiceConnection)
artifactFileName: 'com.nventive.internal.applicationtemplate-Signed.apk'

- template: build/stage-release-appstore.yml
parameters:
Expand Down
30 changes: 12 additions & 18 deletions .azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ trigger:
- main

variables:
- name: system.debug
value: true
#-if false
- name: IsReleaseBranch
value: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
Expand Down Expand Up @@ -80,21 +82,17 @@ stages:
iosVariableGroup: 'ApplicationTemplate.Distribution.Internal.iOS'
BannerVersionNameText: "STAGING"

- stage: AppCenter_TestFlight_Staging
- stage: FirebaseDistribution_TestFlight_Staging
condition: and(succeeded(), eq(variables['IsLightBuild'], 'false'))
dependsOn: Build_Staging
jobs:
- template: build/stage-release-appcenter.yml
- template: build/stage-release-firebase-app-distribution.yml
parameters:
applicationEnvironment: Staging
deploymentEnvironment: AppCenter
appCenterWindowsSlug: $(AppCenterWindowsSlug)
appCenteriOSSlug: $(AppCenteriOSSlug)
appCenterAndroidSlug: $(AppCenterAndroidSlug)
androidKeyStoreFile: $(InternalKeystore)
deploymentEnvironment: Firebase App Distribution
androidVariableGroup: 'ApplicationTemplate.Distribution.Internal.Android'
appCenterServiceConnectionName: $(AppCenterServiceConnection)
appCenterDistributionGroup: $(AppCenterDistributionGroup)
serviceConnectionKeyFileName: $(FirebaseAppDistributionServiceConnection)
artifactFileName: 'com.nventive.internal.applicationtemplate-Signed.apk'

- template: build/stage-release-appstore.yml
parameters:
Expand All @@ -114,21 +112,17 @@ stages:
iosCertificateFile: $(AppStoreCertificate)
iosVariableGroup: 'ApplicationTemplate.Distribution.AppStore'

- stage: AppCenter_Production
- stage: FirebaseDistribution_Production
condition: and(succeeded(), eq(variables['IsLightBuild'], 'false'))
dependsOn: Build_Production
jobs:
- template: build/stage-release-appcenter.yml
- template: build/stage-release-firebase-app-distribution.yml
parameters:
applicationEnvironment: Production
deploymentEnvironment: 'AppCenter Prod'
appCenterWindowsSlug: $(AppCenterWindowsSlug_Production)
appCenteriOSSlug: $(AppCenteriOSSlug_Production)
appCenterAndroidSlug: $(AppCenterAndroidSlug_Production)
androidKeyStoreFile: $(GooglePlayKeystore)
deploymentEnvironment: Firebase App Distribution
androidVariableGroup: 'ApplicationTemplate.Distribution.GooglePlay'
appCenterServiceConnectionName: $(AppCenterServiceConnection)
appCenterDistributionGroup: $(AppCenterDistributionGroup)
serviceConnectionKeyFileName: $(FirebaseAppDistributionServiceConnection)
artifactFileName: 'com.nventive.applicationtemplate-Signed.apk'

- stage: AppStore
condition: and(succeeded(), eq(variables['IsLightBuild'], 'false'))
Expand Down
4 changes: 2 additions & 2 deletions APP_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ TODO: Fill the following table with your own pipelines.
| Link | Code Entry Point | Goal | Triggers |
|-|-|-|-|
| [Name of Main Pipeline](link-to-pipeline)| [`.azure-pipelines.yml`](.azure-pipelines.yml)| Build validation during pull request.| Pull requests.
| [Name of Main Pipeline](link-to-pipeline)| [`.azure-pipelines.yml`](.azure-pipelines.yml)| Build and deploy the application to AppCenter, TestFlight, and GooglePlay. | Changes on the `main` branch.<br/>Manual trigger.
| [Name of Main Pipeline](link-to-pipeline)| [`.azure-pipelines.yml`](.azure-pipelines.yml)| Build and deploy the application to Firebase App Distribution, TestFlight, and GooglePlay. | Changes on the `main` branch.<br/>Manual trigger.
| [Name of API Integration Tests Pipeline](link-to-pipeline)| [`.azure-pipelines-api-integration-tests.yml`](.azure-pipelines.yml)| Run all tests, including APIs integration tests. | Daily cron job.<br/>Manual trigger.
| [Name of Canary Merge Pipeline](link-to-pipeline)| [`build/canary-merge.yml`](.azure-pipelines.yml)| Creation of canary branches (`canary/build/*`). | Daily cron job.
| [Name of Canary Pipeline](link-to-pipeline)| [`.azure-pipelines-canary.yml`](.azure-pipelines.yml)| Build and deploy canary versions of the app to AppCenter and TestFlight. | Upon creation of branches with the `canary/build/*` pattern.
| [Name of Canary Pipeline](link-to-pipeline)| [`.azure-pipelines-canary.yml`](.azure-pipelines.yml)| Build and deploy canary versions of the app to Firebase App Distribution and TestFlight. | Upon creation of branches with the `canary/build/*` pattern.


## Additional Information
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Prefix your items with `(Template)` if the change is about the template and not

## 3.6.X
- Added conventional commit validation stage `stage-commit-validation.yml`
- Replacing Appcenter with Firebase app distribution for android.

## 3.5.X
- Bump Uno packages to 5.2.121 to fix a crash on iOS.
Expand Down
110 changes: 0 additions & 110 deletions build/stage-release-appcenter.yml

This file was deleted.

2 changes: 1 addition & 1 deletion build/stage-release-appstore.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
parameters:
applicationEnvironment: '' # e.g. "Staging", "Production"
deploymentEnvironment: '' # e.g. "GooglePlay", "AppStore", "AppCenter"
deploymentEnvironment: '' # e.g. "GooglePlay", "AppStore", "Firebase App Distribution"

jobs:
- deployment: AppStore_iOS_${{ parameters.deploymentEnvironment}}
Expand Down
42 changes: 42 additions & 0 deletions build/stage-release-firebase-app-distribution.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
parameters:
applicationEnvironment: '' # e.g. "Staging", "Production"
deploymentEnvironment: '' # e.g. "GooglePlay", "AppStore", "Firebase App Distribution"
androidVariableGroup: ''
artifactFileName: ''
serviceConnectionKeyFileName: ""

jobs:
- deployment: Firebase_Android
pool:
vmImage: $(windowsHostedAgentImage)
variables:
- group: ${{ parameters.androidVariableGroup }}
- name: pathToAab
value: '$(Pipeline.Workspace)/$(AndroidArtifactName)_${{ parameters.applicationEnvironment }}/${{ parameters.artifactFileName }}'
environment: ${{ parameters.deploymentEnvironment }}
strategy:
runOnce:
deploy:
steps:
# Step 1: Install Firebase tools
- script: "npm install -g firebase-tools"
displayName: "Install Firebase Tools"

# Step 2: Download the service connection key file
- task: DownloadSecureFile@1
inputs:
secureFile: ${{ parameters.serviceConnectionKeyFileName }}
name: DistributionServiceConnection
displayName: "Download Firebase Service Connection"

# Step 3: Deploy to Firebase App Distribution
- script: |
echo "Deploying to Firebase App Distribution..."
echo "App ID: $(FirebaseAppId)"
echo "Path to AAB: $(pathToAab)"
$pathWithBackslash = $(pathToAab -replace '/', '\')
echo "Path with backslash: $pathWithBackslash"
firebase appdistribution:distribute $(pathToAab) --app $(FirebaseAppId) --release-notes "UnoApplicationTemplate" --groups "nventive" --debug
env:
GOOGLE_APPLICATION_CREDENTIALS: $(DistributionServiceConnection.secureFilePath)
displayName: "Deploy to Firebase"
2 changes: 1 addition & 1 deletion build/stage-release-googleplay.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
parameters:
applicationEnvironment: '' # e.g. "Staging", "Production"
deploymentEnvironment: '' # e.g. "GooglePlay", "AppStore", "AppCenter"
deploymentEnvironment: '' # e.g. "GooglePlay", "AppStore", "Firebase App Distribution"

jobs:
- deployment: GooglePlay_Android
Expand Down
24 changes: 3 additions & 21 deletions build/variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Make sure you have the following variable groups in your Azure pipeline library:
#
# ApplicationTemplate.Distribution.Internal.Android
# ApplicationIdentifier: This is the internal application id of the app for AppCenter releases. Note that this variable is used by Nimue to automatically change the package name.
# ApplicationIdentifier: This is the internal application id of the app for iOS releases.
# AndroidSigningKeyAlias: This is the keystore alias.
# AndroidSigningKeyPass: This is the keystore keypass (secured).
# AndroidSigningStorePass: This is the keystore storepass (secured).
Expand All @@ -15,7 +15,7 @@
# AndroidSigningStorePass: This is the keystore storepass (secured).
#
# ApplicationTemplate.Distribution.Internal.iOS
# ApplicationIdentifier: This is the internal application id of the app for AppCenter releases. Note that this variable is used by Nimue to automatically change the bundle id.
# ApplicationIdentifier: This is the internal application id of the app for iOS releases.
# AppleCertificatePassword: The certificate password (secured).
#
# ApplicationTemplate.Distribution.AppStore
Expand All @@ -39,26 +39,8 @@
# Prerequisites - Service connections
# Make sure you have the following service connections in your Azure pipeline library.
GooglePlayServiceConnection: GooglePlay-nventive-ApplicationTemplate
AppCenterServiceConnection: AppCenter-nventive-framework
AppStoreServiceConnection: AppStore-nventive
AppCenterCanaryServiceConnection: AppCenter-nventive-framework

# AppCenter slugs
# The "app slug" corresponds to the identifiers of the app in AppCenter; to find it, navigate to the app in a browser and;
# the URL should look like this: https://appcenter.ms/orgs/{orgId}/apps/{appId}; the slug is simply: "{orgId}/{appId}".
AppCenterAndroidSlug: 'nventive-framework/Application-Template-1'
AppCenteriOSSlug: 'nventive-framework/Application-Template'
AppCenterWindowsSlug: 'nventive-framework/Application-Template-2'
AppCenterAndroidSlug_Production: 'nventive-framework/ApplicationTemplate-Production-1'
AppCenteriOSSlug_Production: 'nventive-framework/ApplicationTemplate-Production'
AppCenterWindowsSlug_Production: 'nventive-framework/ApplicationTemplate-Production-2'
AppCenterAndroidSlug_Canary: 'nventive-framework/Application-Template-Canary-1'
AppCenteriOSSlug_Canary: 'nventive-framework/Application-Template-Canary'
AppCenterWindowsSlug_Canary: 'nventive-framework/Application-Template-Canary-2'

# AppCenter Distribution Groups
AppCenterDistributionGroup: '00000000-0000-0000-0000-000000000000'
AppCenterCanaryDistributionGroup: '00000000-0000-0000-0000-000000000000'
FirebaseAppDistributionServiceConnection: com.nventive.applicationtemplate.firebaseappdistribution.json

# Azure subscription
# AzureSubscriptionName:
Expand Down
2 changes: 1 addition & 1 deletion doc/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ This application uses [FluentValidation](https://www.nuget.org/packages/FluentVa
See [Validation.md](Validation.md) for more details.

### Analytics
This application has a built-in analytics base that can be used to track events and errors with potentially any analytics service (e.g. AppCenter, Firebase, Segment, etc.). This base is built around the [IAnalyticsSink](../src/app/ApplicationTemplate.Presentation/Framework/Analytics/IAnalyticsSink.cs) interface.
This application has a built-in analytics base that can be used to track events and errors with potentially any analytics service (e.g. Firebase, Segment, etc.). This base is built around the [IAnalyticsSink](../src/app/ApplicationTemplate.Presentation/Framework/Analytics/IAnalyticsSink.cs) interface.

See [DefaultAnalytics.md](DefaultAnalytics.md) for more details.

Expand Down
10 changes: 5 additions & 5 deletions doc/AzurePipelines.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Azure Pipelines
# Azure Pipelines

## Pipeline Code
This project uses CI/CD pipelines that are implemented as yaml code.
Expand All @@ -18,7 +18,7 @@ These pipelines rely on a few variable groups and secrets in order to fully work

At high level, the CI/CD pipelines do the following:
- **Build** the app in **staging**.
- **Deploy** the staging app (to AppCenter and/or TestFlight and GooglePlay).
- **Deploy** the staging app (to Firebase app distribution, TestFlight and Google Play).
- **Build** the app in **production**.
- **Deploy** the production app (to TestFlight and GooglePlay).

Expand Down Expand Up @@ -68,8 +68,8 @@ This is where the exact build steps are defined. These vary depending on the pla

The release stages are even more straigtforward than the build ones. One thing to note is that, for the same reason as it is done at the end of the build steps, a clean-up step is included in every stage.

### AppCenter Release Stage ([stage-release-appcenter.yml](../build/stage-release-appcenter.yml))
This stage is in charge of pushing the application to AppCenter. It's divided into 2 jobs, one for each platform.
### Firebase app distribution Release Stage ([stage-release-firebase-app-distribution.yml](../build/stage-release-firebase-app-distribution.yml))
This stage is in charge of pushing the application to Firebase app distribution. Only for Android.

### Apple AppStore Release Stage ([stage-release-appstore.yml](../build/stage-release-appstore.yml))
This stage is in charge of pushing the iOS version to the Apple AppStore. Given that the build stage signs the application, this is as simple as using the proper task and pushing the **IPA** file. This should only be run for configurations that properly sign the application.
Expand Down Expand Up @@ -102,4 +102,4 @@ This pipelines creates a branch on which it commits a version of the latest code
### Canary Deployment
This pipelines triggers automatically when a new branch is created and pushed by the previous pipeline. It takes the new code, builds it, and deploys so that it can be manually tested.

This pipeline uses the same build and release stages as the main CI/CD pipeline of the app.
This pipeline uses the same build and release stages as the main CI/CD pipeline of the app.
2 changes: 1 addition & 1 deletion doc/DefaultAnalytics.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This application comes with a few default tracked events.
They can be found in the [IAnalyticsSink](../src/app/ApplicationTemplate.Presentation/Framework/Analytics/IAnalyticsSink.cs) interface.
The idea is that you would change the implementation of this interface to send the events to an analytics service (such as AppCenter, Firebase, Segment, etc.).
The idea is that you would change the implementation of this interface to send the events to an analytics service (such as Firebase, Segment, etc.).

> 💡 The default events are meant to be a starting point for your application's analytics. Because they are automatic, they are more generic than custom events. If you want to track more specific events, you can adjust this recipe by adding new members to the `IAnalyticsSink` interface (or changing the existing ones) to better suit your needs.
Expand Down
2 changes: 1 addition & 1 deletion src/ApplicationTemplate.sln
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6E8378CB
..\build\canary-merge.yml = ..\build\canary-merge.yml
..\build\gitversion-config.yml = ..\build\gitversion-config.yml
..\build\stage-build.yml = ..\build\stage-build.yml
..\build\stage-release-appcenter.yml = ..\build\stage-release-appcenter.yml
..\build\stage-release-firebase-app-distribution.yml = ..\build\stage-release-firebase-app-distribution.yml
..\build\stage-release-appstore.yml = ..\build\stage-release-appstore.yml
..\build\stage-release-googleplay.yml = ..\build\stage-release-googleplay.yml
..\build\steps-build-android.yml = ..\build\steps-build-android.yml
Expand Down
Loading
Loading