I don't understand (or remember) why https://github.com/apple/swift-markdown follows the branch versioning as well, since it has nothing to do with the toolchain, but let's assume there is a valid reason for it.
My question is — I want to version my own package much like any other open source package out there with semantic versioning. My package depends on https://github.com/apple/swift-markdown an so it seems to be that, with SwiftPM, I can't use semantic versioning at all?
Is my understanding correct? What is the recommended way to version packages depending on some of the apple packages — is the only working solution to avoid semantic versioning altogether?
Without having tried it, I seem to recall that this error can be worked around by pinning your dependencies to specific commits by using .package(url:revision:). It's more of a pain to update those since you'll have to do it manually, but it means the dependency won't change out from under you and break your users either.
swift-markdown is used by the DocC stack, which is part of the toolchain, so swift-markdown by necessity must evolve with the toolchain.
your understanding and conclusion is correct. a package that depends on a package that evolves with the toolchain must also evolve with the toolchain. evolving with the toolchain is contagious.
for example, swift-json does not depend on any packages that evolve with the toolchain, so it evolves independently, and can use semantic versioning. swift-package-factory depends on swift-syntax, so SPF evolves with the toolchain.
the recommended way to distribute a package that evolves with the toolchain is to use toolchain tags like you described: this is exactly what SPF does. that the SPM cannot understand and resolve toolchain tags is, in my opinion a problem with SPM, not a problem with swift-markdown.
DocC does not depend on the toolchain, DocC is part of the toolchain. (whether or not DocC should be part of the toolchain is a valid question to ask but out of scope for this thread.)
swift-markdown doesn’t depend on the toolchain, but the toolchain depends on swift-markdown, and the toolchain developers have political control over swift-markdown, so swift-markdown releases for the toolchain, and the easiest way to release for the toolchain is to tag by nightly snapshot.
if swift-markdown were to release with semvers instead of toolchain tags, that would slow down toolchain development.
Sadly, there really isn't much you can do. As soon as you start depending on a package that doesn't follow SemVer you shouldn't adopt SemVer yourself, because as @taylorswift said "it is contagious". If you would adopt SemVer nevertheless you are somewhat lying because you are forcing your adopters to lock your version since other packages might depended on a different swift-markdown version.
One way out of this is vendoring the code of the package that doesn't support SemVer yourself. You can do this by copying the code over. You might also be able to do this with git submodules and a local package dependency; however, I haven't tried this out and there might be other downsides with that approach.
Fork and tag 0‐prefixed versions of your own where necessary. Your package graph becomes irreconcilable with the toolchain packages, but they are already irreconcilable with the rest of the world anyway.
I have a dozen or so already set up here, (but not swift-markdown yet). Others, like SwiftSyntax, vend 0‐prefixed versions directly.
The package manager is available as part the Swift toolchains available on Swift.org) including snapshots for the latest versions built from main branch. For installation instructions for downloaded snapshots, please see the Getting Started section of Swift.org.
It seems that forking and tagging swift-markdown might be the only option for my case.