CI limit stages by branch and tag

I am using gitlab CI to build and deploy an app. I would like to control the test and build based on the tag’s and branches of the commits. What I would like is:

On master, when tagged with a tag that matches /^release.*&/ - execute 3 stages; build, test, deploy.

On any other branch - execute stages; build + test.

I have tried a lot of scenarios and I have read the docs but I think I am missing how some of this works.

One version of what I have is below. The issue with this setup is that when a commit is made to master, whether it has a tag or not. It executes build and test. If the commit was tagged, then it also runs build, test, deploy. What I would like is for it to only run build, test, deploy on a tagged commit here.

Any ideas?

build:
  type: build
  script:
    - scripts/build.sh
  only:
    - branches
    - /^release-.*$/
test:
  type: test
  script:
    - scripts/test.sh
  only:
    - branches
    - /^release-.*$/
release:
  type: deploy
  script:
    - scripts/deploy.sh
  only:
    - /^release-.*$/
  except:
    - branches