Permalink
Browse files

A git-only SBCL workflow

 This updates the SBCL build and release process to be more compatible
 with distributed development -- to facilitate moving the upstream
 repository into Git.

 A detailed description of what is going on here is in
 doc/GIT-WORKFLOW.md.

 Some highlights:

  * Drop version.lisp-expr and branch-version.lisp-expr.

  * Auto-generate the version at build time using information
    from Git, incorporating:
    - Last release number.
    - Number of commits on origin/master since last release.
    - Current branch, if there are commits not on origin/master.
    - Number of commits not on origin/master.
    - SHA1 id of the last commit.
    - Optional -dirty marker.

  * Update release.sh to work with Git.

  * Make source-distribution.sh exclude the .git directory from tarballs.

  * Release tags contain NEWS for that release.
  • Loading branch information...
1 parent 34ac026 commit bf5163e4f07f0666b53b32b6232a4bd81d0d548e @sb-studio sb-studio committed Jun 6, 2011
Showing with 328 additions and 72 deletions.
  1. +1 −0 .gitignore
  2. +92 −0 doc/GIT-WORKFLOW.md
  3. +13 −8 doc/PACKAGING-SBCL.txt
  4. +72 −0 generate-version.sh
  5. +3 −0 make.sh
  6. +145 −35 release.sh
  7. +1 −1 source-distribution.sh
  8. +1 −5 src/code/misc.lisp
  9. +0 −23 version.lisp-expr
View
@@ -44,3 +44,4 @@ contrib/*/a.exe
contrib/asdf/asdf-upstream
contrib/sb-cover/test-output
doc/manual/*.html
+version.lisp-expr
View
@@ -0,0 +1,92 @@
+# Git workflow for SBCL
+
+## Version numbering
+
+Historically each SBCL commit incremented the number in
+version.lisp-expr, and prepended that version number to the first line
+of the commit message. For CVS this served us well, but since Git
+makes it easier for anyone to create branches that run in parallel to
+the current "master" timeline, it destroys the illusion of a single
+official timeline defined through version.lisp-expr.
+
+In Git workflow, version.lisp-expr no longer exists in the repository,
+nor is the version number prepended to commit messages.
+
+Instead, we construct a version number as follows when building SBCL
+or generating a source tarball:
+
+For branch master:
+
+ release.commits-on-master-since-release.sha1
+
+ Eg. 1.0.48.20-152c97d
+
+ Last release: 1.0.48
+ Commits on master after release: 20
+ SHA1 abbrev for current HEAD: 152c97d
+
+ If there are no commits on master since the last release, both the
+ count and the SHA1 are dropped.
+
+For other branches:
+
+ release.commits-on-branch-and-master-since-release.branch.commits-on-branch.sha1
+
+ Eg. 1.0.44.26.wip-pretty-backtraces.4-674f875
+
+ Last release: 1.0.44
+ Commits on master after release: 26
+ Branch: wip-pretty-backtraces
+ Commits on branch but not on master: 4
+ SHA1 abbrev for current HEAD: 674f875
+
+In both cases -dirty is appended to the version number if the tree
+isn't clean when building.
+
+Anyone who publishes binaries built using an altered version, should
+do so on a branch named appropriately, so that the binaries identify
+themselves as 1.0.50.debian.2 or whatever. If they wish to use a
+source release instead working from Git, they should identify their
+changes with an appropriate edit to version.lisp-expr.
+
+To cater for those whose existing processes really don't like the
+SHA1s part in version numbers, setting NO_GIT_HASH_IN_VERSION=t in the
+environment for make.sh will make the version number generator leave
+out the hash.
+
+## Making a release (release.sh)
+
+Short story: use `release.sh`.
+
+`release.sh` makes a release *locally.* This means it will perform all
+actions required for the release in the local git checkout, and will
+then instruct you how to proceed in order to push the release to the
+outside world.
+
+###Synopsis:
+
+ ./release.sh VERSION [-s]
+
+**VERSION** is the version to make a release for. Example: `1.0.46`.
+
+**-s** instructs `git tag` to create a gpg-signed tag for this
+release. Highly recommended.
+
+###Description:
+
+`release.sh` will perform these actions:
+
+* Check that the local checkout is clean.
+* Update NEWS and make a commit stating the release version number
+* Make an sbcl.<VERSION> tag and optionally sign it.
+* Build SBCL
+* Run tests
+* Build SBCL with the SBCL that just had tests pass
+* Build docs
+* Create source, binary, documentation tarballs
+* Sign these tarballs
+* Give you further instructions.
+
+After release.sh is done, you can inspect the results, and commence
+struggling with the SF.net file release system from hell. You are very
+brave.
View
@@ -1,19 +1,24 @@
Packaging SBCL
==============
-If you package SBCL for a distribution, please edit version.lisp-expr,
-and append ".packaging-target-or-patch[.version]".
+If you package SBCL for distribution, we ask that you to take steps to
+make the version number reflect this. Our users often report bugs that
+are intimately tied up with configuration issues, and much confusion
+can result from mistaking a packaged SBCL for the upstream one.
+
+If you are working from a Git branch, all you need to do is make sure
+the branch name reflects the situation -- the build system will
+incorporate the it in the version string.
+
+If you are working from a release tarball, please edit
+version.lisp-expr, and append ".packaging-target-or-patch[.version]".
Examples:
- "1.0.7.gentoo"
- "1.0.7.mikes-rpms.2"
+ "1.0.50.gentoo"
+ "1.0.50.mikes-rpms.2"
This will make the startup banner, --version, and
(lisp-implementation-version) all identify the packaged version
correctly.
-We ask you to do this because users report bugs that are intimately
-tied up with configuration issues at regular intervals, and much
-confusion can result from mistaking a packaged SBCL for the upstream
-one.
View
@@ -0,0 +1,72 @@
+#!/bin/sh
+# Not a shell script, but something intended to be sourced from shell scripts
+git_available_p() {
+ # Check that (1) we have git (2) this is a git tree.
+ (which git >/dev/null 2>/dev/null && git describe >/dev/null 2>/dev/null)
+}
+
+generate_version() {
+ if ([ -f version.lisp-expr ] && ! git_available_p)
+ then
+ # Relase tarball, leave version.lisp-expr alone.
+ return
+ elif ! git_available_p
+ then
+ echo "Can't run 'git describe' and version.lisp-expr is missing." >&2
+ echo "To fix this, either install git or create a fake version.lisp-expr file." >&2
+ echo "You can create a fake version.lisp-expr file like this:" >&2
+ echo " \$ echo '\"1.0.99.999\"' > version.lisp-expr" >&2
+ exit 1
+ fi
+ # Build it.
+ version_head=$(git rev-parse HEAD)
+ if [ -z "$SBCL_BUILDING_RELEASE_FROM" ]
+ then
+ version_root="origin/master"
+ else
+ version_root="$SBCL_BUILDING_RELEASE_FROM"
+ fi
+ version_base=$(git rev-parse "$version_root")
+ version_tag=`git describe --tags --match="sbcl*" --abbrev=0 $version_base`
+ version_release=`echo $version_tag | sed -e 's/sbcl[_-]//' | sed -e 's/_/\./g'`
+ version_n_root=`git rev-list $version_base --not $version_tag --count`
+ version_n_branch=`git rev-list HEAD --not $version_base --count`
+ if [ -z "$NO_GIT_HASH_IN_VERSION" ]
+ then
+ version_hash="-`git rev-parse --short $version_head`"
+ else
+ version_hash=""
+ fi
+ if git diff HEAD --no-ext-diff --quiet --exit-code
+ then
+ version_dirty=""
+ else
+ version_dirty="-dirty"
+ fi
+ # Now that we have all the pieces, put them together.
+ cat >version.lisp-expr <<EOF
+;;; This file is auto-generated using generate-version.sh. Every time
+;;; you re-run make.sh, this file will be overwritten if you are
+;;; working from a Git checkout.
+EOF
+ if [ "$version_base" = "$version_head" ]
+ then
+ if [ "0" = "$version_n_root" ]
+ then
+ printf "\"%s%s\"\n" \
+ $version_release $version_dirty >>version.lisp-expr
+ else
+ printf "\"%s.%s%s%s\"\n" \
+ $version_release $version_n_root \
+ $version_hash $version_dirty >>version.lisp-expr
+ fi
+ else
+ echo "base=$version_base"
+ echo "head=$version_head"
+ version_branchname=`git describe --contains --all HEAD`
+ printf "\"%s.%s.%s.%s%s%s\"\n" \
+ $version_release $version_n_root \
+ $version_branchname $version_n_branch \
+ $version_hash $version_dirty >>version.lisp-expr
+ fi
+}
View
@@ -192,6 +192,9 @@ export DEVNULL
. ./find-gnumake.sh
find_gnumake
+. ./generate-version.sh
+generate_version
+
# If you're cross-compiling, you should probably just walk through the
# make-config.sh script by hand doing the right thing on both the host
# and target machines.
Oops, something went wrong.

0 comments on commit bf5163e

Please sign in to comment.