For macOS, this particular detail can usually be ignored for apps using multi-architectural binaries:
… https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary
That link includes building such binaries, as well as conditional compilations for Swift and Objective C, as well as conditional compilations for iOS, iPadOS, and macOS targets.
Other programming languages with Apple hardware targets usually have similar conditional support.
This approach—rather than run-time checks—can greatly simplify packaging and distribution of these apps.
Or use uname or similar run-time architectural sniffing, and your own cross-platform support for whatever language and app and targets you’re using. (Your question and your follow-up question are really open-ended, here.)
If you do decide to use a shell script, use a shebang and select either bash or (probably preferably) zsh explicitly, so that you don't run into problems with different default shells, as older logins can have bash and newer logins will have zsh.
As for the other platforms, best check with them. Microsoft Windows does not presently have a supported version for Apple silicon; there’s no purchasable product available (as yet?). What Windows for ARM64 is available is an unsupported insider’s beta, via a virtual machine. Linux is also just getting going on Apple silicon. Either of these can likely use uname via WSL (if/as that’s available), or via the Linux shell. Microsoft seems to prefer folks use .NET, and the CLR deals with most architectural baggage.
Again, you’ll want to check with Microsoft folks around how to differentiate x86-64, x86-64, AArch64, Alpha, Itanium, or whatever other Windows targets you might need. Most of those have been de-supported, but Windows has been multi-architecture for a while, so this should not be hard to find from a Windows-focused resource.
And Java can ignore pretty much all of this stuff most everywhere, outside of code using JNI or whatever that’s now called.