Branch deploy is not working at all

Hi team,

So my problem is simply that Branch Deploy just doesn’t seem to work, like… at all :man_shrugging:

My production branch is deploying fine whenever I push to it which is awesome :+1:

My staging branch however, despite being selected in Settings | Branches | Branch Deploys, just never builds and I simply don’t know why. There’s no messaging or information that tells me why that I know of. And yes I’m new to Netlify.

I have scoured the support forum for Branch Deploy issues but they all seem to be around Subdomain, DNS, SSL, etc. issues and not that it simply isn’t working.

The one significant difference that I suspect may be the cause is my use of Azure DevOps for the repo. I have set up a Build Hook to get my Production branch to auto deploy and I’m wondering if my Staging branch won’t work because either Azure DevOps isn’t supported or my Staging branch simply needs it’s own build hook?

Actually my guess is I might need to create a separate staging site rather than using Branch Deploy but hey that’s why I’m asking here right :upside_down_face:

Any help is greatly appreciated.

https://gastro-public.netlify.app

Cheers,
Jeremy.

Hi, @JeremyW. The repo is private so I cannot see it. The error message in the build logs is this:

8:59:41 PM: Failed during stage 'Reading and parsing configuration files': 
When resolving config file /opt/build/repo/<redacted repo name>/netlify.toml:
Base directory does not exist: /opt/build/repo/staging

: exit status 1

To paraphrase that error it says you have made the base directory “staging” and that directory doesn’t exist in the base of the clone repo.

If you tell use the directory structure for your repo and post the netlify.toml file here we can tell you what the correct setting should be. You might also be able to resolve this on your own with this information by changing the base directory in the staging branch’s netlify.toml file to match the site settings here (or just remove that line so the defaults below will be used):

https://app.netlify.com/sites/gastro-public/settings/deploys#build-settings

If there are other questions or concerns, please let us know.

Thanks @luke ,

I have commented out the ‘base’ setting here;

# Specific branch context: all deploys from 
# this specific branch will inherit these settings.
[context.staging] # “staging” is a branch name
  command = "echo 'staging'"
#  base = "staging"

One other thing of important note, my staging branch does not auto deploy when I push a change to it as the documentation suggests;

Once you select some or all of your branches for branch deploys, Netlify will start watching those branches for new commits and pull/merge requests. As soon as you start pushing changes to those branches, you’ll find new deploys for those branches.

I pushed a commit to my Staging branch a few minutes ago and nothing happened.

ps. The build you did find was when I changed the production branch to staging as a way to trigger it so I could look at setting up a new Build Hook as a possible work-a-round (need to build a branch before you can set up a hook for it).

So my assumption is that - because the only way I can deploy is via a Build Hook with Azure DevOps - branch deploy is not a feature that I can leverage as a Azure DevOps user?

At least that seems to be the case from the last comment of this thread.

Hi, @JeremyW. Actually, the branch deploys feature should work for Azure DevOps. As long as you are using a Git based deploy, branch deploys will work for any Git host.

This is interesting:

Based on this, it sounds like the webhook isn’t always sent. I can check this our database to see if we are receiving the webhooks when commits happen for staging. To do this I would need to know the date, time, and timezone of a push to upstream for that branch and repo. However, I think you can check the webhook configuration to determine this without me looking at the database I recommend trying that first.

What was interesting to me was that the webhook was received when you made staging the production branch at Netlify. I’m guessing that there was also a change made in Azure at that time. Is that correct?

I mention this because there are only two requirements to trigger a build at Netlify:

  • the repo and branch are configured for a site at Netlify with the required permissions for the repo
  • there is a webhook sent to Netlify that a new commit has been pushed to the upstream repo

I’m curious why we received the webhook for staging once but never again. Did you create and remove a new webhook?

To summarize, my best guess is that the webhooks in Azure are configured to only trigger when certain branches are pushed. There appears to be documentation about the webhook settings here:

Would you please confirm that you are sending commits for all branches and not just specific branches in the webhook configuration?

If you configure it to send for all branches (or at least all branches you are using at Netlify) then branch deploys should work normally.

If that doesn’t fix it or if there are other questions, please let us know.

Thanks again @luke ,

I only changed the production branch to Staging here in Netlify, nothing else;
image

The plot thickens however :stuck_out_tongue:

You are correct, the hook configuration in Azure was set to “main” and not [Any]. I have changed it to [Any] and when I pushed a commit to the Staging branch it auto deployed. Sounds good… but it deployed Main again :joy:

What I do notice is this hook config in Netlify specifying that the “main” branch will be deployed;

image

When you try to add a hook in Netlify you can only select a single branch, not ‘any’. So it kinda feels like Azures happy to trigger on anything but the Netlify hook only handles a specified branch. That would explain the push to “staging” still deploying something.

I set this up by following the video in that Support item I shared earlier. That’s probably why the Azure hook wasn’t quite right… a - “we’ll just do this for now” scenario. I’ll review the configs and rewatch that video to see if I missed something on Netlify’s end.

I don’t think I missed anything, I’m also not convinced Branch deploy is supported from Azure DevOps like other providers given this reply in that support thread;

Scott was referring to Deploy Previews but it kinda sounds similar.

I am curious however if I just need to create a hook in Netlify for the “staging” branch to wire it up.

Some interesting outcomes since…

Hey there, @JeremyW :wave:

Thanks for following up. In terms of next troubleshooting steps, can you please try to create a new hook in Netlify for the staging branch? Does this resolve the issue for you?

If that doesn’t do the trick, can you please share the following information:

  1. The date, time, and timezone of a push to upstream for that branch and repo.
  2. The contents of your netlify.toml file.

Thank you!

1 Like

Thanks @hillary,

I cannot create a build hook until I’ve successfully deployed my Staging branch at least once.

EDIT: I noticed after a failed build that the branch became available to create a hook from, and did.
Earlier I had noticed the same thing but when I closed the branch deploy setting panel (or refreshed the page) and tried again, the staging branch was not selectable. Possible issue with Netlify UI?

Right now I’m getting a missing dist folder issue when Netlify tries to deploy the Staging branch and frankly - I don’t really understand why - it should be the default for all branches and just work. At least I thought so.

I suspect the issue is that - to get the Staging branch to start building at all - I had set it to the Production branch in my deploy settings but that just tries to build it in the wrong context. Still doesn’t explain the missing dist folder through.

Is there a way for me to just force a deploy of my Staging branch without having to set it as the Production branch in my deploy settings? Haven’t found a way to do that via UI.

EDIT: After managing to create a hook for my Staging branch the error below still occurs.

Interestingly too, the first attempt for Staging detected no changes so stopped.
I committed a change to the Staging branch and that triggered a build however in Netlify that started a build of Main (as defined in the trigger for Azure DevOps) but also a build for Staging (as per Netlify deploy settings).

Once Main was deployed, Staging kicked in but failed with that missing dist folder error.

EDIT: This still happens. If I commit a change to my Staging branch it appears that BOTH hooks get triggered. Ugh :roll_eyes:

EDIT: So now I have a hook for each branch AND the correct Netlify context appears in my deployments, but that Dist folder and both Hooks triggering issue are still mysterious (to me) blockers :stuck_out_tongue:

Latest attempt

I pushed the change to my Staging branch at 12.05pm on 30th April (NZT).

The contents of my .toml file is;

# example netlify.toml
[build]
  command = "npm run generate"
  functions = "netlify\functions"
  publish = "dist"

# Specific branch context: all deploys from 
# this specific branch will inherit these settings.
[context.staging] # “staging” is a branch name
  command = "echo 'staging'"
#  base = "staging"

[context.staging.environment]
  BUILD_ENV = "staging"

  ## Uncomment to use this redirect for Single Page Applications like create-react-app.
  ## Not needed for static site generators.
  #[[redirects]]
  #  from = "/*"
  #  to = "/index.html"
  #  status = 200

  ## (optional) Settings for Netlify Dev
  ## https://github.com/netlify/cli/blob/main/docs/netlify-dev.md#project-detection
  #[dev]
  #  command = "yarn start" # Command to start your dev server
  #  port = 3000 # Port that the dev server will be listening on
  #  publish = "dist" # Folder with the static content for _redirect file

  ## more info on configuring this file: https://www.netlify.com/docs/netlify-toml-reference/

Also note that the Staging environment settings are currently identical to Production environment settings since the site and obviously deployment is still being tested.

I’ve tried to keep this setup real simple and just get SSG working first so I know the SEO support is in place.

Cheers,
Jeremy

Hi, @JeremyW. The error there is saying that there is no such directory:

5:03:41 PM:   Deploy did not succeed: Deploy directory 'GastroInfo.Public/dist' does not exist

Based on this, I would ask you to you look at the remote repo for that branch. If you do so, you should see there is no such directory.

Note, their could be such a directory in your local working copy of the repo. However, this error says that this directory doesn’t exist in the upstream repo Netlify is cloning for this branch. (I do see that directory working on a different branch.)

If so, creating the missing directory for the other branch and pushing it to the upstream repo, should resolve the issue. If not, please let us know.

Thanks @luke , it appears I misunderstood how the build process works, I figured it would create the folder if it was missing. That makes sense locally but I see how in this scenario that might not be possible. Doh! I’ll give that a try.

So this makes sense in my head… Netlify clones my repo locally (with it’s nominated output folder), builds the app and outputs the deploy files into said folder locally, then deploys the site from that?

Ok @luke I had a look at things and I’m not convinced that simply adding the folder to my repo’s staging branch is the answer here.

In the build definition we nominate a publish branch, in my case the default /dist.

  1. The publish folder is specified in .gitignore by default for good reason, it’s to prevent locally built code during dev testing being constantly uploaded to ones repo

  2. My Main branch does NOT have this publish folder (the one you observed) and yet it builds fine in Netlify. During the build process I’m confident the publish folder should be created, populated - and once that code is deployed - cleaned up and removed along with any other build artifacts

  3. So I’m fairly confident that this is the whole point, Netlify grabs ones repo, builds a fresh copy of the project within, creates the appropriate publish folder and the deployment code within, then deploys that code.

The mystery I need to solve is why - even though it seems like /dist is defined as my publish folder globally - said folder is not being created when building my Staging branch.

Man this modern build/deploy process is a right pain in the ass. Nothing ever works like it says on the box! Actually it did, for my Main branch, but no one ever mentions why ones other branch might not work! :joy:

I’ll keep digging for a solution.

That is correct.

Exactly. If the SSG is configured to output to dist (or build or out, etc.) then that is the value you set as the publish directory.

If the command is as set in one of your previous posts (command = "echo 'staging'") then that is, as far as I know, exacly what is run. The command npm run generate under [build] doesn’t run as you have overridden it for that context, so no dist directory would ever get created because nothing is running that would create it.

Oh my gawd, the coincidence of it all @coelmay … I was just re reading the File-based configuration details - thinking I could ‘force’ things how I expect - when I noticed the command setting against my staging context and started thinking “hang on a minute?”. Then I noticed your reply and it was “EUREKA” :rofl:

Annoyingly I remember replicating that command from the docs a while back and stupidly didn’t click to the context of it. Now I realise it was simply demonstrating that one had configured their context correctly and that the echo should be be replaced with ones build command like you highlighted.

I feel so duuuhhhh right now :melting_face:

Thanks peeps for the assist, it is very much appreciated. Lemme make some changes and try this again :slight_smile:

Alrighty the builds are working in both environments now, yay! :partying_face:

Only a couple of issues left to figure out;

  1. The expected branch deploy URL fails to work with the message;

Your connection isn’t private. Attackers might be trying to steal your information from staging.gastro-public.netlify.app (for example, passwords, messages, or credit cards).

NET::ERR_CERT_COMMON_NAME_INVALID

staging.gastro-public.netlify.app uses encryption to protect your information. When Microsoft Edge tried to connect to staging.gastro-public.netlify.app this time, the website sent back unusual and incorrect credentials. You can’t visit staging.gastro-public.netlify.app right now because the website uses HSTS.

  1. When I push a change to my Staging branch, deployments are triggered in Netlify for both Main and Staging branches. Not sure if this is Netlify or Azure DevOps… I assume the latter since it fires the hooks that start Netlify builds. Will research and/or contact MS.

Branch URLs follow the form <branch-name>--<subdomain>.netlify.app e.g. https://staging--gastro-public.netlify.app

I cannot speak for Azure as I don’t use it, but this is the same behaviour as with GitHub.

As mentioned in Branch Deploy Controls documentation

By default, new pull/merge requests against the selected branches generate new Deploy Previews

So if staging is a PR against main, then yes, Netlify will build both. There are settings available in the UI to change this behaviour under Build & Deploy → Deploy Previews in site settings. Your workflow requirements will dictate whether these are useful.

Thanks @coelmay , as I only get to work on this project in weekends I seem to be forgetting details.

I remember the branch url format now… whoops. Thanks for the reminder.

Not sure about the build issue though, Staging is not a PR against Main in my case. I’ll review the site settings and see if there’s anything relevant. For the time being I can disable the relevant hook in DevOps to prevent this behaviour until I sort it out proper :+1:

Actually I have another issue now, a dreaded CORS issue between my site here on Netlify and my API hosted on Azure.

While I have the allowed origins setup as expected, and receive 200 responses from my API requests, these are followed by the CORS error blah blah from blah blah has been blocked by CORS policy. No 'Access-Control-Allow-Origin' header is present on the requested resource.

Curiously the same API is accepting requests from my local machine based on IP, and my Admin app is able to connect to the same API (and endpoints) without issue (although that’s hosted on Azure too).

Are there any gotchas I need to be aware of when trying to perform cross origin requests from Netlify hosted sites to an external API? Do I need to setup proxies or redirects or something. I’ve seen the latter mentioned on some topics but I can’t tell if they’re relevant to my situation. Or does my API actually see a different incoming URL than ‘gastro-public.netlify.app’?

I’m also seeing stuff about folks adding the Access-Control-Allow-Origin header to their Netlify app response. I find this odd because my understanding was that my API is what checks CORS compliance and adds the CORS headers in it’s response to the calling app. So in a situation where a client app is hosted on Netlify why would someone need to add the Access-Control-Allow-Origin header to it when IT’S EXPECTING that from the API response?

Or have I misunderstood how CORS works? Quite possible :man_shrugging:
I’ve been searching for hours and perhaps I’m too tired to see the problem now.

CORS used to do my head in @JeremyW, but it’s not quite so bad after a recent video I found.

In essence, you need the Access-Control-Allow-Origin returned by the API specifying that any origin can access it (e.g. Access-Control-Allow-Origin: *) or that only a specific domain can (e.g Access-Control-Allow-Origin: https://example.com.) As mentioned on MDN you can only specify a single origin, so if you wish multiple origins (e.g. localhost, example.com, dev.example.com) to access it in the API you’ll need to maintain a list of origins and check that the origin requesting is permitted.

Have I lost you yet?

You can find the video here and the relevant code here (it isn’t for Netilfy, but the principal is the same anywhere.)

@coelmay - Good, you know my pain :stuck_out_tongue:

Definitely hadn’t lost me… in fact I think my grasp on the concept is sound. I simply didn’t know why the CORS middleware in my API is not automagically returning the CORS headers as expected.

After your second link and a couple of other stack overflow articles I believe I’ve found the smoking gun;

Specifically;

Dang it! That’s why it worked when I used a global policy but isn’t working with the above. It’s also related to how Authorisation touches the response headers so this wouldn’t be possible anyway. Maaan, now I gotta decide if it’s worth the extra dev :rofl:

As the author of the comment stated himself, he completely missed this note too. Oh well.

Thanks for your help today :slight_smile:

1 Like