Skip to content

Commit

Permalink
document qi's "continuous deployment" development practice
Browse files Browse the repository at this point in the history
  • Loading branch information
countvajhula committed Jan 19, 2025
1 parent cd19566 commit ec898d5
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions qi-doc/scribblings/intro.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ Qi is a hosted language on the @hyperlink["https://racket-lang.org/"]{Racket pla

Additionally, Qi itself uses few and carefully benchmarked dependencies, so that the load-time overhead of @racket[(require qi)] is minimal.

@subsection{About Qi's Release Practices}

Qi follows the @hyperlink["http://timothyfitz.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/"]{continuous deployment} model of development. This means that fresh changes are immediately pushed to the main branch of development after they pass a rigorous and comprehensive suite of tests.

Furthermore, Qi packages on the Racket package index point to this main branch on the source host, so that running @racket[raco pkg install qi] or @racket[raco pkg update qi] will always get the version on the @racket[main] branch, reflecting the latest improvements.

This doesn't mean that you must use this version, however. The expressiveness of modern version control systems allows us to define diverse versioning protocols directly on the versioning backend to best support diverse usage needs. Towards this end, Qi follows these conventions:

@itemlist[#:style 'ordered
@item{Each significant new release has a tagged version, which is static and immutable.}
@item{Each legacy release has a "maintenance" branch that will be stable without any backwards incompatible changes or new features, and will be supported with bug fixes as needed.}
]

Together, these practices decouple development from use, thus eliminating the problem of backwards compatibility. Specifically, Qi may occasionally change in a way that might traditionally be labeled "backwards-incompatible," but by relying on a version tag with either of the above semantics, such a change would not affect your application unless you are interested in the new features and until such a time as you are ready to upgrade. Thus, it gives users flexibility and stability without compromising the freedom to innovate and remedy past missteps for developers of Qi.

In case you need to rely on a version with either of the above semantics, we recommend declaring a Git @tech{package source} in your @racket[info.rkt], instead of a Racket @tech{package source}. Like this:

@codeblock{
(define deps '("git://github.com/drym-org/qi.git#v5.0"))
}

Now, traditionally, we may have grown accustomed to depending on a certain version of a package "or newer" (as are the semantics of using a Racket, rather than Git, @tech{package source}), so that we never have to update the dependency specification to get the latest improvements. We believe that this is a fragile convention that simultaneously overburdens development while threatening application stability. It's inadvisable for the same reason that mutability in programs is inadvisable, that is, introducing superfluous coupling and incurring the attendant risks. After all, any introduced bug is technically backwards-incompatible, as, indeed, is the fix for the bug! On the other hand, the branch strategy above supports these semantics to a sensible extent -- that of receiving necessary bug fixes, but not gratuitous "improvements" that may unwittingly break your application, even if they aren't intended to be backwards-incompatible.

@section{Relationship to the Threading Macro}

The usual threading macro in @seclink["top" #:indirect? #t #:doc '(lib "scribblings/threading.scrbl")]{Threading Macros} is a purely syntactic transformation that does not make any assumptions about the expressions being threaded through, so that it works out of the box for threading values through both functions as well as macros. On the other hand, Qi is primarily oriented around @emph{functions}, and @tech{flows} are expected to be @seclink["What_is_a_Flow_"]{function-valued}. Threading values through macros using Qi requires special handling.
Expand Down

0 comments on commit ec898d5

Please sign in to comment.