Azure / static-web-apps

Azure Static Web Apps. For bugs and feature requests, please create an issue in this repo. For community discussions, latest updates, kindly refer to the Discussions Tab. To know what's new in Static Web Apps, visit https://aka.ms/swa/ThisMonth
https://aka.ms/swa
MIT License
319 stars 53 forks source link

Full support for other CI/CD services, such as GitLab CI, BitBucket, Jenkins, CircleCI (or manual deploy) #964

Open derkoe opened 1 year ago

derkoe commented 1 year ago

Is your feature request related to a problem? Please describe. I am trying to automate deployment of Azure Static Web Apps from GitLab CI and many of the features available in GitHub do not work. I know that GitHub is a part of Microsoft now, but I do not understand why the Static Web Apps tools were only built for GitHub. Basic deployment from other providers works now but it seems that everything is still tight to GitHub (every build is still looking for GitHub's "event info").

The deployment uses the StaticSitesClient (also swa is using it) which has no documentation and is closed source. This makes finding issues quite hard.

Describe the solution you'd like

Support the following features via the CLI (either StaticSitesClient or https://github.com/Azure/static-web-apps-cli/):

Also, provide a documentation to the StaticSitesClient and ideally the source as well.

Describe alternatives you've considered I have tried to use swa and Azure CLI. With swa you can also deploy an app but without any branch decoration. With Azure CLI you cannot deploy in any way, but you can delete an environment.

Additional context

gergan commented 1 year ago

Does someone knows some way to trick StaticSitesClient to close/delete a Preview deployment. It seems that it connects in some way with the Github Event Json, but I didn't find a way to fake this file for upload/close in order to have the pullRequestTitle set or to have the preview deployment undeployed. I mean it is not a stable API or anything like this but just give us some API to work with this, or just document which fields are used or even just give us the Rest API, we don't need no useless task or gargantuan images...

derkoe commented 1 year ago

@gergan I've tried but failed (I even copied a JSON over from GitHub Actions).

The only way to delete an environment outside GitHub Actions is via Azure CLI:

az staticwebapp environment delete --yes --name {webapp-name} --resource-group {resource-group-name} --environment-name {environment-name}
gergan commented 1 year ago

Well thanks for the info. I've tried to rely only on StaticSitesClient, because it does not need special authorization it just uses the deployment token, but for now will implement a workaround with azure functions or something like this to clean the environments.

Yao-C commented 1 year ago

Any updates for this?

stephen-hardy commented 1 year ago

TLDR

Here is my YML for a GitHub Action that creates preview environments on branch creation (and NOT pull request creation), and deletes preview environments when branches are deleted.

Short Version

StaticSitesClient seems to only take environment id from the event JSON. In said JSON, it uses pull_request.number as the environment id - which seems to work for pull request IDs, branch names, or specified environment names. This is the only value it really needs from that JSON, though it expects a few other values to be present. So, create a properly formatted JSON with the correct pull_request.number value (pulled from github.event.ref, in my case), pass that JSON to docker, set it as the --event path, give it the --token value, and you're good to go.

Long Version

Unlike the title/focus of this issue, I'm working with GitHub and not other CI/CD services. One would think there would be no reason for me to run into this, but I wanted an environment-per-branch setup. The automatic creation of preview environments was easy to setup, as this documentation outlines. I removed the pull request triggers, because with a branch-environment setup I have no need for pull request-environments, and the creation side of things was working perfectly. Good to go, right?

Not quite. SWAs have a limit of 3 preview environments for the free plan, and 10 standard (paid) plan. So, that means that the auto-creation of environments per branches will (soon) bring you to the service limit - then you'll need to clean out the old environments manually in the portal. And, that is what I should have lived with. Unfortunately, my time investment continued.

I looked at the Azure CLI, but the authentication requirements on that are (in my opinion) ridiculous. More specifically, the app registration setup is not easily scalable across multiple SWAs. I wanted a solution that I could quickly roll out across my apps. And, my tolerance for setup time (per SWA) was low because this was something I could easily go into the portal to do myself. Yet, that somehow didn't deter me from continuing my search for an automated solution.

The SWA CLI apparently doesn't have the ability to tear down a preview environment.

Azure Logic Apps don't seem to have the ability to touch preview environments.

So... I guess I'm left with the utility that can destroy a preview environment. I mean, I've seen it do it. Pull request was created, preview environment was created, pull request closed, preview environment was destroyed. It can do it. But, it doesn't do it when I put the action on a branch deleted event instead of a pull request event. When I do that, it gives me the error that led me to this issue: Request is missing the pull request id

How do we give it the pull request id, when my use case has nothing to do with pull requests? I found this blog, which seemed to give some insight into working with StaticSitesClient. But, despite following the same format used on that site, I could not get the close action to work. It kept returning an error saying that there was missing content. I tried changing all the environment variables, every combination I could think of, and nothing. Honestly, I'm not sure how the author ever got that to work. But, when I set the DEPLOYMENT_PROVIDER to GitHub, I did get that JSON error again. OK... let's chase that.

First thing would be specifying the JSON. I tried putting a help flag on the command, and it spit out some info. One thing it listed was an --event flag for setting the JSON path. Great! I passed the JSON file into docker with it's -v flag, and got a parse error. Which, was confusing because the JSON I gave it was valid. It was just an object with a "test" property at this point, but valid nonetheless. I assumed the parse was tied to a schema. So, now I need a valid GitHub json file. This post helped me dump the JSON out of the GitHub Action.

I dumped the JSON from the branch delete event, which was the trigger I wanted. I fed that to StaticSitesClient, and still received a parse error. Strange. Well, the largest object in that JSON was the event object. It would make sense that the event JSON is actually the event object from the larger github object. I copied out just the event object, saved that as my event.json file, and received the same 'pull request id missing' error as before. Not everything I hoped, but at least now I can modify the JSON and manipulate StaticSitesClient's behavior in ways I couldn't directly through the built-in YML step. It wanted a pull request id and I didn't have one to give. Let's give it an actual pull request event JSON, and see if that changes the error.

I temporarily changed my YML to dump JSON from a pull request, copied the event object into my event.json file, and it ran! Kinda. Mostly. It told me it couldn't find a matching environment. Well, that makes sense. It is trying to delete the environment created for this pull request, and I'm no longer creating environments for pull requests. So, I need to find what in this (large) event object contains the pull request id. Should be simple, I searched for pull_request_id. Nothing. There was an ID property for pull_request, but it was a long string of numbers that didn't make any sense. It seemed as though StaticSitesClient looks for all the properties it needs up front, and will error quickly if it doesn't find them. It can't possibly need all these properties. Let's start deleting properties until only the required ones are left.

That left me with the property names you see in the JSON of the attached YML file. But, it seemed like some of those properties shouldn't actually be required. Why would they be? What happens if I put a dummy value in one of them. Still works. How about another? Still works. Only one that couldn't be a dummy value? pull_request.number. OK, we found pull request id!

The looking I did online indicated that GitHub integration brought pull request-based environments first, then branch environments, then named environments. Given that they look for the pull request id in the number property, instead of the id property, I'm guessing that technical debt service has been sadly lacking here. The URL format for preview environments seemed to always place the pull request id, the branch name, or the environment name in the same place in the URL. So... what happens if I just feed the number property a string?

pull_request.number is the environment id, regardless of type. The other properties need to be present, likely to pass a schema validation, but they do NOT need to have legitimate values. Empty strings are fine.

Notes

alexrecuenco commented 3 weeks ago

I tried @stephen-hardy script, ~and although it might've worked before, it isn't working now :"(~

EDIT: It is working, I just had deployment provider set to gitlab, when you set --deploymentProvider GitHub, Stephen's solution finally works.

I wonder if with deployment provider set as Gitlab, there is some other magical configuration format to find that pull request id

asbjornu commented 2 weeks ago

To echo @stephen-hardy's remarks regarding SWA being a bit too "clever", its cleverness is even too much for supposedly first-class supported GitHub Action deployments, which are failing spectacularly as well. Read https://github.com/Azure/static-web-apps/issues/632#issuecomment-2179548456 for more information.