As much as I can, I'm following the fundamental principles of Continuous Delivery: "Build Once, Deploy Anywhere."
TL;DR:
In Azure Devops Release Pipeline's SWA step: is there a way to have Oryx either not build the api or recognize that it is a dotnet project?
I prefer Azure Devops for deployment over any other product out there today because of the Release Pipeline's ease of use for product owners or project managers to approve and control when deployments happen in different environments. Also, these approvers can just get a "Stakeholder" license which costs nothing. Even if GitHub actions graduates with this feature, I'd still have to issue the user an Enterprise license.
I would rather have a workflow for Azure Static Web App (SWA) as I do for everything else:
- push code to the "main" branch in GitHub repository
- Azure Devops CI Pipeline kicks off a build
- Build Angular front end code and save it to directory $(Build.ArtifactStagingDirectory)/web
- Build dotnet function back end code and save it to directory $(Build.ArtifactStagingDirectory)/api
- Publish the build artifacts to be available for the release pipeline
- Release Pipeline (CD) SWA step would get the artifacts and deploy them to Azure SWA environment
I know SWA Release step in Azure DevOps is still in version 0.X, and have noticed it evolving over time. Let me describe my experience and how it evolved:
- A month ago or so it wouldn't work because of the Azure SWA Token not being available
- That got fixed and I noticed it would only work on a Linux host (no big deal there)
- The docker container that runs the SWA step would have this error:
docker: Error response from daemon: OCI runtime create failed: invalid mount {Destination::/working_dir Type:bind Source:/var/lib/docker/volumes/3b6743ba34608e986186d5057ae6cd4ed36a773d5ca9c9f2cb5fa8894f411c6d/_data Options:[rbind]}: mount destination :/working_dir not absolute: unknown.
- To resolve this issue simply add a Bash step before the SWA step with this code: (credit Claire Novotny here: https://github.com/microsoft/azure-pipelines-tasks/pull/14807#issuecomment-868593099)
# Set this variable as the AzureStaticWebApp task is hard coded to read it.
echo '##vso[task.setvariable variable=BUILD_SOURCESDIRECTORY]$(System.DefaultWorkingDirectory)'
- The last issue I believe is that Microsoft Oryx (the build engine behind the SWA step in Release Pipeline) wants to either build the api or recognize the language already compiled. No matter what I do, I can't get Oryx to recognize it's a dotnet project and it defaults to node:
Oryx was unable to determine the build steps. Continuing assuming the assets in this folder are already built. If this is an unexpected behavior please contact support.
The function language could not be detected. The language will be defaulted to node.
There is documentation for Oryx here: https://github.com/microsoft/Oryx/blob/master/doc/configuration.md#oryx-configuration that does point to the posibility that Oryx can be told what project type it is (in my case dotnet) see the PLATFORM_NAME and PLATFORM_VERSION settings. I am assuming I'd put this in the "Api Build Command" field in the release pipeline and it seems Oryx recognizes it, but still goes into wanting to recognize mode and defaults back to node.
--platform dotnet --platform-version 3.1
The work around for me right now is to not build the dotnet function app in the CI pipeline and instead let Oryx build it every time I need it to deploy to an environment as part of the CD pipeline. That breaks the "Build Once, Deploy Anywhere" principle of Continuous Delivery I am achieving with any other Azure resource deployment and would like to know how to make Oryx not build it, instead reusing the already built and compiled artifacts.