Illustration of a gear with the GitHub logo connected by orange pipes, labeled AL:GO for AppSource.

Make AL:Go pipelines for your AppSource Application

5 min read

In this second part of the blog series about AL:Go pipelines we will cover pipelines for your AppSource extensions.

If you have missed previous part, we have covered AL:Go pipelines for PTE Extensions: Make AL:Go pipelines for your PTE Application – Stefan’s BC Blog


AL:Go PTE GitHub Template

AL:Go GitHub template for AppSource application can be found here:

GitHub – microsoft/AL-Go-AppSource: Template for Business Central AppSource projects. Click the link below to create a new repository.

Of course you could use this repository as template:

The AL-Go-AppSource template repository on GitHub, with Use this template open

But I think in most cases you already have an extension for which you would need pipelines.

Start by cloning AL-Go-AppSource repository:

The cloned AL-Go-AppSource repository in VS Code, showing its .AL-Go and .github contents

You would need folders:

  • .AL-Go
  • .github

Copy those folders to your extension repository.

Clean project:

An existing AppSource project in VS Code before the template files are copied in

After pasting new folders:

The same project after copying, the new template files marked as untracked

This time, different to PTE pipeline, AppSource pipeline will run AppSourceCop and validate that your code is ready to be published to AppSource.

Well done, this is the first step! 🚀

💡 This can be also done by running pipeline workflow called: Add existing app or test app


Basic settings in new copied files

The next step is to change settings.json in .AL-Go folder:

The .AL-Go settings.json with country, the mandatory AppSourceCop affix and appFolders set

Depending on which code base container you would like to run you would define country, in this case, I am using w1, but you can run on specific localization.

Since this is AppSource extension, it’s mandatory to have registered affix defined for your application which you are publishing.

An important part is to change “appFolders” settings, initially, it comes with the default which is [], but running with this setting doesn’t work. This setting depends on your project structure.


Adding access token to pipeline

This has been covered in previous part, here is the link:

Adding access token to pipeline


Code signing of extension for AppSource

AppSource apps need to be code-signed. To achieve this, you must create two secrets in the GitHub repo or in your KeyVault. CodeSignCertificateUrl should be a secure download URL to your <Code Signing Certificate>.pfx file and CodeSignCertificatePassword should be the password for this .pfx file. Adding these secrets will cause the CI workflow and the Create Release workflow to sign the .app files. In the pipeline, you will see a new step.

If your secrets are called something else than CodesignCertificateUrl and CodesignCertificatePassword, you can add an indirection to the .AL-Go\settings.json file:

JSON
"CodeSignCertificateUrlSecretName": "myCodeSignCertUrl",
"CodeSignCertificatePasswordSecretName": "myCodeSignCertPassword",

Next step is to get our signing certificate to Azure Key Valut or any other storage app.

  1. Import your certificate into the Key Vault.

How you do this might depend on which Certificate Authority you are getting your certificate from. DigiCert and GlobalSign have integrations with Azure Key Vault. You can follow this guide on how to set up that integration if you are using one of those CAs. Once you have set up the integration, you can request a certificate from within your Azure Key Vault. If you are using another CA you can try following this guide to Generate a CSR and Install a Certificate in Microsoft Azure Key Vault. If neither of those options work for you, please engage with your CA to get the certificate into the Key Vault.

An Azure Key Vault certificate list with the code signing certificate enabled

Add then to AL-Go-Setting.json keyVaultCodesignCertificateName

AL-Go-Settings.json naming that key vault certificate for code signing

Without this settings, it would just skip Signing part of your application:

A build run where the Sign step is skipped because no certificate is configured

Note: For this to work, you would need Azure credentials to add as a secret also.

2. Using any other storage, for example, Storage account on Azure.

Azure Storage Explorer showing the signing pfx uploaded to a blob container

And get uploaded certificate URL put it into Git Secrets:

The repository secrets holding the code signing certificate URL and password

or AL-Go-Settings.json:

AL-Go-Settings.json pointing at those two secrets instead of the key vault

Result:

A successful build with the Sign step completed and the signed app artifact uploaded


Deploying to AppSource from Pipeline

First, you need to add Authentication to AppSource. In order to get started, you need a way to authenticate to the Partner Center ingestion API. This can be done using Service 2 Service authentication (which is recommended for workflows and pipelines) or you can use User Impersonation.

To get started with S2S, you need to complete Step 1 from here. After this, you should have a ClientID and a of your Microsoft Entra Application and the actual authentication is done using the New-BcAuthContext function from BcContainerHelper:

PowerShell
$authcontext = New-BcAuthContext `
    -clientID $PublisherAppClientId `
    -clientSecret (ConvertTo-SecureString -String $PublisherAppClientSecret -AsPlainText -Force) `
    -Scopes "https://api.partner.microsoft.com/.default" `
    -TenantID "<your AAD tenant>"
New-ALGoAppSourceContext -authContext $authContext | Set-Clipboard

Add AppSourceContext secret to AL-Go for GitHub
After running one of the code snippets above, you should now have the AuthContext in the Clipboard and you can create a secret by navigating to Settings -> Secrets and variables -> Actions, click New repository secret. Create a secret called AppSourceContext and paste the value into the secret.

The repository secrets with the AppSource context secret added

Beside the AppSourceContext secret, you will need to add a DeliverToAppSource structure to your project settings file.

In your project configuration, you will need the AppSource Product Id (not your app id). You can find your AppSource Product Id in the address bar of the browser in partner center when looking at your AppSource offering:

Microsoft Partner Center, with the AppSource product id highlighted in the offer URL

The productId GUID is mandatory and must be specified in deliverToAppSource like this:

AL-Go-Settings.json with deliverToAppSource carrying that product id and continuous delivery off

The workflow run showing the Deliver to AppSource job completing

If you have set ContinuousDelivery to true, every app will be delivered to AppSource and taken through validation and made available in AppSource as preview. You then need to press Go Live in partner center or run the Publish To AppSource workflow in AL-Go for GitHub in order to publish the app to production.


Releases

This one is same as for PTE applications, I will point you to my previous blog post about AL:Go PTE pipelines where this is covered:
https://ssosic.com/wp-admin/post.php?post=1897&action=edit#h-release-pipeline


Deploy extension to cloud environment

This one is same as for PTE applications, I will point you to my previous blog post about AL:Go PTE pipelines where this is covered:

https://ssosic.com/algo-pipelines/make-algo-pipelines-for-your-pte-application/#h-deploy-extension-to-cloud-environment


This blog post covered AppSource pipelines differences from PTE. Definitely as said, you should check the previous blog post if you don’t understand. Due to not wanting to repeat content that is same for both pipelines. So, we have covered basics for both type of pipelines PTE and AppSource. In next part of this AL:Go blog series you can expect to learn more advance things, I won’t reveal too much, keep following it! 🚀

Related posts

Comments

    Leave a comment

    Reviewed before it appears.