That's a lot of steps in your bootstrap chain. I think tying it to releases can make it easier, but it's good your process is automated.
Rust has a long chain too, but rustc only uses features itself, that the previous release supports. Releases are every 6 weeks.
Go had been bootstrapping from 1.4 (the last C compiler release), until the release of 1.20 this year, when the bootstrap compiler was bumped to 1.17.13 and will be bumped yearly [0]. That meant go1.4 had to be able to compile new versions, keeping the compiler from using new features in itself for 8 years. Notably, this now allows for generics to be used in the compiler.
Rust has a long chain too, but rustc only uses features itself, that the previous release supports. Releases are every 6 weeks.
Go had been bootstrapping from 1.4 (the last C compiler release), until the release of 1.20 this year, when the bootstrap compiler was bumped to 1.17.13 and will be bumped yearly [0]. That meant go1.4 had to be able to compile new versions, keeping the compiler from using new features in itself for 8 years. Notably, this now allows for generics to be used in the compiler.
[0]: https://github.com/golang/go/issues/54265