Auto-versioning builds for PHP & Bower


Change PHP and Bower package creation behavior to follow the Gemfury standard of always building a single package from the tip of the git push-ed master branch. Customers will still have the option to version packages explicitly or tag-based, where the package version will be created based on the SemVer-compatible Git tags.


Since implementing support for PHP and Bower, we and our customers have identified the following deficiencies with the current implementation of the Composer and Bower package builder:

  1. Lack of control over versions created when pushing a repo into Gemfury. This leads to confusion, and possibly undesired behavior, such as rebuilding existing versions, or versions that have been purposefully deleted.
  2. Building all tagged versions requires a deep/full clone and multiple build iteration. This is both time and resource consuming, and in many cases it triggers unnecessary or undesired builds.
  3. No ability to rebuild a specific tagged version if a version has been deleted from your account.
  4. If no new tags are pushed, git push --tags results in an error.

We believe the current behavior is confusing, error-prone, and inconsistent with how all other packages are built on Gemfury (one-build ⇒ one-package).

Detailed design

To address these problem, we plan to replace the current build-all-tags behavior of the builder with the standard build-HEAD behavior, where we will create a package for the incoming commit of the master branch:

git push --tags fury master

If you would like to build a specific tag, you would have to push that tag into the master branch. Please note that you may need to append ~0 to the tag name to dereference annotated tags:

git push --tags fury +v1.5.0~0:refs/heads/master

We also support an optional --revision argument to git:rebuild CLI command that enables building specific tags from an existing repo. This can be scripted to replicate the deprecated build-all-tags functionality.

fury git:rebuild repo-name --revision v1.5.0

Explicit versioning changes

Versioning of PHP and Bower packages will still support two modes: explicit and tag-based. As before, explicit versioning will be based on the version field in the respective package config files. However, this mode will now ignore Git tags and build directly from the tip of the pushed master branch. Subsequent pushes will result in a duplicate-version error until the version is incremented in the config file. This behavior is consistent will all other Gemfury builders.

Tag-based versioning changes

Tag-based versioning behavior will remain the same for tagged commits: if an incoming HEAD commit is tagged with a Semantic Version (with or without a v prefix), this version will be built and pushed into your account. Subsequent pushes of that version will result in duplicate-version errors.

Where as the current builder would ignore or generate an error for an untagged commit pushed to master branch, the new builder will always create a package version. For this, we will implement auto-versioning.

Untagged commits will be auto-versioned as follows based on the closest tagged upstream commit. If no SemVer tags are found in a commit's history, we assume initial version of 0.1.0.

[Incremented tagged version]-dev.[distance to tag]+g[short-SHA1]

Here's an example of how commits of a master branch may be versioned:

├── [Untagged: a3e434b] Version: 1.5.1-dev.3+ga3e434b
├── [Untagged: fce57b5] Version: 1.5.1-dev.2+gfce57b5
├── [Untagged: 1489d75] Version: 1.5.1-dev.1+g1489d75
├── [Tagged: v1.5.0]    Version: 1.5.0
├── ...
├── [Untagged: 1489d75] Version: 0.1.0-dev.2+g1489d75
└── [Initial:  ff9a20b] Version: 0.1.0-dev.1+gff9a20b

For those following along, this is closely based on the git describe --tags algorithm adjusted for SemVer compatibility and rules of precedence.

Tags that are not compatible with SemVer will be ignored. For commits with multiple tags, annotated tags will always be preferred over lightweight tags, and tags with newer dates will always be preferred over tags with older dates.

Migration plan and schedule

We are looking to smoothly go through this transition, while not limiting the capabilities and features that customers have come to expect from Gemfury.

☑ May 19, 2017 (Phase 1)

We will enable auto-versioining for the tip of master branch in cases where no new tags are available, and version is not specified in the package configuration file. This functionality will replace the "No new Git tags found to build" error.

☑ June 9, 2017 (Phase 2)

At this time, we will disable automatically building all tags when a repository is pushed. We will only build the tip of master either using the version specified in the package config file or via auto-versioining described above.

During this phase, if you'd like to revert to the old functionality, you can enable it via LEGACY_BUILD_TAGS flag in your .fury.yml:

# Example .fury.yml for legacy build
- pack: auto
  env: ["LEGACY_BUILD_TAGS=true"]

☐ August 1, 2017 (Phase 3)

We will remove LEGACY_BUILD_TAGS functionality and only support building from tip of master branch.