Which repo should own the integration tests? How do I synchronize the releases of matching front and back ends?
Which repo should own the integration tests? How do I synchronize the releases of matching front and back ends?
If it were in a true client/server environment, where you had a variety of different client versions rolled out, then I expect you would have already found the obvious answer: the server has to support multiple versions of clients and clients use a mechanism like feature switches or capability detection to enable functionality as it becomes available server side. Both repos have their own integration tests: the server's make sure the server supports multiple client versions, and the client's make sure that the client degrades gracefully in the face of server variation.
From the way you talk, though, it sounds to me like you expect client and server to always be released at the same time (e.g., where it's a web front end and web back end). If that's really the case, then I'd just have everybody work as one team, working off a common set of features switches.
Is that helpful?
It is helpful, but certainly doesn't sound simple. Feature switches would require the messages to already be designed, which is most of the work already done. It also sounds like an edge-case nightmare.
I usually put integration tests in the client repo but it doesn't matter. The key is that you put in a trigger so they get run by changes to any of the projects.
You don't want a lot of half-baked stuff hanging around, so you should definitely limit WIP and be aggressive about removing switches once you're sure you won't be switching something off. Without that, it could indeed be nightmareish. But branching can also get nightmareish. Either way, the trick is to minimize complexity.
For REST apis, use semantic versioning, and you can embed specific versions in the request headers. The server should be able to respond correctly to a range of different versions (an api call to say what range of versions the server speaks isn't a bad idea). Coarse-grained api revisions can be embedded in the url (the ever popular /v1 and /v2, etc).
- app-backend
- app-frontend
- app-bundle (or simply "app")
Your backend and frontend can be independently developed and use semantic versioning, they could run their independent checks like linting and unit tests.
The bundle repo could consist of a docker compose file that uses image versions of backend and frontend that are compatible with one another. You can choose to anchor the version to the minor, or revision etc. This way you can bump your versions when they are ready.
Also, pushes to your backend or frontend could trigger a build of the bundle repo. I would run there the integration tests.
That being said, if the app is relatively simple, I would probably pack everything up in one repo to avoid the overhead.