Docs feedback: It's not obvious how script/before_script behave with extends

Problem to solve

It's currently extremely unclear how script and before_script are merged or replaced when using the extends keyword in GitLab CI.

Further details

The whole extends feature is kinda tricky with regard to what's merged and what's replaced. It looks like only certain types of "keys" are actually merged? The rest of the properties seem to follow some kind of replacement rules?

The algorithm used for merge is “closest scope wins”, so keys from the last member will always shadow anything defined on other levels.

Proposal

I was trying to separate and organize base jobs to provide info before the "real" job script.

.linux:
    tags: linux
    before_script:
        - uname -a

.docker:
    extends: .linux
    tags: docker
    image: docker:stable
    services:
        - docker:stable-dind
    before_script:
        - docker --version
        - docker info
        - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"

build:
    extends: .docker
    stage: build
    script:
        - docker build --tag "$CI_REGISTRY_IMAGE" .
        - docker push "$CI_REGISTRY_IMAGE"

The problem is, the .linux before script gets replaced. And I can never add a before script to the build job. This seems kind of limiting to me and surprising until I had deeply experimented and read the docs a couple of times.

I guess I can still use anchors, but that feels hard 😬

Who can address the issue

I'm sure you made the merge/replace rules for a reason, but are they better than simply merging all properties all the time?

Other links/references

Edited by Anthony Mastrean