apache tinkerpop logo

Developer Documentation

This document contains information for TinkerPop developers, contributors, and community members. It focuses on technical information and other internal processes related to the project.


Contributions via GitHub pull requests are gladly accepted from their original author. By submitting any copyrighted material via pull request, email, or other means you agree to license the material under the project’s open source license and warrant that you have the legal authority to do so.

Getting Started

gremlin-apache New contributors can start development with TinkerPop by first forking then cloning the Apache TinkerPop GitHub repository. Generally speaking it is best to tie any work done to an issue in JIRA. Either scan through JIRA for an existing open issue to work on or create a new one.

After making changes, submit a pull request through GitHub, where the name of the pull request is prefixed with the JIRA issue number. In this way, the pull request and its comments get tied back to the JIRA issue it references, thus triggering automation that pushes GitHub comments into the JIRA ticket.

Before issuing your pull request, please be sure of the following:

  1. mvn clean install works successfully.

  2. If the change requires modification to the documentation, which can be found in docs/src, please be sure to try to generate the docs. If the changes are minimal and do not include code examples, it might be sufficient to test generate the docs to validate formatting by just doing bin/process-docs.sh --dryRun. If there are code examples, please be sure to have Zookeeper and Hadoop running when doing a bin/process-docs.sh. If no code changes were made, one can also use the --noClean option. This will prevent the processor from cleaning up the local Grapes directory and the Hadoop Gremlin Libs directory in HDFS, resulting in a slightly faster execution time. The documentation is generated to /target/docs/htmlsingle. Once a full run of the documentation is executed, it is possible to run just one file by deleting the file to regenerated from target/postprocess-asciidoc then re-executing bin/process-docs.sh.

  3. If necessary, run the integration tests. For example, if the changes affect serialization or Gremlin Server/Driver operations then running the integration tests assures in addition to unit tests will definitely be necessary. After a successful mvn clean install, do mvn verify -DskipIntegrationTests=false -pl gremlin-server.

Once a pull request is submitted it must go through review and will be merged once three TinkerPop committers offer positive vote and achieve Apache consensus.

For those who are trying to find a place to start to contribute, consider looking at unresolved issues that have the "trivial" priority as these issues are specifically set aside as low-hanging fruit for newcomers.

Building and Testing

TinkerPop requires Java 1.8.0_40+ for proper building and proper operations.

  • Build Project: mvn clean install

    • Specify specific tests in a TinkerPop Suite to run with the GREMLIN_TESTS environment variable, along with the Maven project list argument, e.g.:

      export GREMLIN_TESTS='org.apache.tinkerpop.gremlin.process.traversal.step.map.PathTest$Traversals,org.apache.tinkerpop.gremlin.process.traversal.PathTest'
      mvn -Dmaven.javadoc.skip=true --projects tinkergraph-gremlin test
    • Clean the .groovy/grapes/org.apache.tinkerpop directory on build: mvn clean install -DcleanGrapes

    • Turn off "heavy" logging in the "process" tests: mvn clean install -DargLine="-DmuteTestLogs=true"

    • The test suite for neo4j-gremlin is disabled by default - to turn it on: mvn clean install -DincludeNeo4j

  • Regenerate test data (only necessary given changes to IO classes): mvn clean install -Dio from tinkergraph-gremlin directory

    • If there are changes to the Gryo format, it may be necessary to generate the Grateful Dead dataset from GraphSON (see IoDataGenerationTest.shouldWriteGratefulDead)

  • Check license headers are present: mvn apache-rat:check

  • Build AsciiDocs (Hadoop must be running and awk version 4.0.1 is required): bin/process-docs.sh

    • Build AsciiDocs (but don’t evaluate code blocks): bin/process-docs.sh --dryRun

    • Process a single AsciiDoc file: docs/preprocessor/preprocess-file.sh `pwd`/gremlin-console/target/apache-gremlin-console-*-standalone `pwd`/docs/src/xyz.asciidoc

  • Build JavaDocs: mvn process-resources -Djavadoc

  • Check for Apache License headers: mvn apache-rat:check

  • Check for newer dependencies: mvn versions:display-dependency-updates or mvn versions:display-plugin-updates

  • Deploy JavaDocs/AsciiDocs: bin/publish-docs.sh svn-username

  • Integration Tests: mvn verify -DskipIntegrationTests=false

    • Execute with the -DincludeNeo4j option to include transactional tests.

    • Execute with the -DuseEpoll option to try to use Netty native transport (works on Linux, but will fallback to Java NIO on other OS).

  • Performance Tests: mvn verify -DskipPerformanceTests=false

  • Benchmarks: mvn verify -DskipBenchmarks=false

Docker Integration

TinkerPop provides a shell script, that can start several build tasks within a Docker container. The required Docker images will be built automatically if they don’t exist yet. Thus the first invokation of the Docker script is expected to take some time.

The script can be found under PROJECT_HOME/docker/build.sh. The following tasks are currently supported:

  • run standard test suite

  • run integration tests

  • build Java docs

  • build user docs

A list of command line options is provided by docker/build.sh --help. The container will install, configure and start all required dependencies, such as Hadoop.

If the container is used to generate the user docs, it will start a web server and show the URL that is used to host the HTML docs.

After finishing all tasks, the script will immediately destroy the container.

IDE Setup with Intellij

This section refers specifically to setup within Intellij. TinkerPop has a module called gremlin-shaded which contains shaded dependencies for some libraries that are widely used and tend to introduce conflicts. To ensure that Intellij properly interprets this module after importing the Maven pom.xml perform the following steps:

  1. Build gremlin-shaded from the command line with mvn clean install.

  2. Right-click on the gremlin-shaded module in the project viewer of Intellij and select "Remove module".

  3. In the "Maven Projects" Tool window and click the tool button for "Reimport All Maven projects" (go to View | Tool Windows | Maven Projects on the main menu if this panel is not activated).

  4. At this point it should be possible to compile and run the tests within Intellij, but in the worst case, use File | Invalidate Caches/Restart to ensure that indices properly rebuild.

Note that it maybe be necessary to re-execute these steps if the gremlin-shaded pom.xml is ever updated.

Developers working on the neo4j-gremlin module should enabled the include-neo4j Maven profile in Intellij. This will ensure that tests will properly execute within the IDE.

If Intellij complains about "duplicate sources" for the Groovy files when attempting to compile/run tests, then install the GMavenPlus Intellij plugin.

For Committers

business gremlin

The guidelines that follow apply to those with commit access to the main repository:


TinkerPop has a user mailing list and a developer mailing list. As a committer, it is a good idea to join both.

It would also be helpful to join the public TinkerPop HipChat room for developer discussion. This helps contributors to communicate in a more real-time way. Anyone can join as a guest, but for regular contributors it may be best to request that an Apache HipChat account be created.

Occasionally, online meetings via video conference are held. These meetings are schedule via the dev mailing list about a week before they are to occur to find a day and time that is available for those interested in attending. On the day of the meeting, the meeting organizer will create a Google Hangout (or similar video conferencing link) to post to the TinkerPop room in HipChat. At that point, all who are interested can attend. Meeting minutes should be taken and added to the Meetings section of this document using the pattern already established.

Release Notes

There is a two-pronged approach to maintaining the change log and preparing the release notes.

  1. For work that is documented in JIRA, run the release notes report to include all of the tickets targeted for a specific release. This report can be included in the release announcement.

  2. The manual change log (CHANGELOG.asciidoc) can be used to highlight large changes, describe themes (e.g. "We focused on performance improvements") or to give voice to undocumented changes.

Given the dependence on the JIRA report for generating additions to the CHANGELOG.asciidoc, which uses the title of the issue as the line presented in the release note report, titles should be edited prior to release to be useful in that context. In other words, an issue title should be understandable as a change in the fewest words possible while still conveying the gist of the change.

Changes that break the public APIs should be marked with a "breaking" label and should be distinguished from other changes in the release notes.


The "master" branch is used for the main line of development and release branches are constructed as needed for ongoing maintenance work. If new to the project or are returning to it after some time away, it may be good to send an email to the developer mailing list (or ask on HipChat) to find out what the current operating branches are.

Other branches may be created for collaborating on features or for RFC’s that other developers may want to inspect. It is suggested that the JIRA issue ID be used as the prefix, since that triggers certain automation, and it provides a way to account for the branch lifecycle, i.e. "Who’s branch is this, and can I delete it?"

For branches that are NOT associated with JIRA issues, developers should utilize their Apache ID as a branch name prefix. This provides a unique namespace, and also a way to account for the branch lifecycle.

Developers should remove their own branches when they are no longer needed.


Tags are used for milestones, release candidates, and approved releases. Please refrain from creating arbitrary tags, as they produce permanent clutter.

Issue Tracker Conventions

TinkerPop uses Apache JIRA as its issue tracker. JIRA is a very robust piece of software with many options and configurations. To simplify usage and ensure consistency across issues, the following conventions should be adhered to:

  • An issue’s "status" should generally be in one of two states: open or closed (reopened is equivalent to open for our purposes).

    • An open issue is newly created, under consideration or otherwise in progress.

    • A closed issue is completed for purposes of release (i.e. code, testing, and documentation complete).

    • Issues in a resolved state should immediately be evaluated for movement to closed - issue become resolved by those who don’t have the permissions to close.

  • An issue’s "type" should be one of two options: bug or improvement.

    • A bug has a very specific meaning, referring to an error that prevents usage of TinkerPop AND does not have a reasonable workaround. Given that definition, a bug should generally have very high priority for a fix.

    • Everything else is an improvement in the sense that any other work is an enhancement to the current codebase.

  • The "component" should be representative of the primary area of code that it applies to and all issues should have this property set.

  • Issues are not assigned "labels" with two exceptions:

    • The "breaking" label which marks an issue as one that is representative of a change in the API that might affect users or vendors. This label is important when organizing release notes.

    • The "deprecation" label which is assigned to an issue that is about removing a deprecated portion of the API.

  • The "affects/fix version(s)" fields should be appropriately set, where the "fix version" implies the version on which that particular issue will completed.

  • The "priority" field can be arbitrarily applied with one exception. The "trivial" option should be reserved for tasks that are "easy" for a potential new contributor to jump into and do not have significant impact to urgently required improvements.

Code Style

Contributors should examine the current code base to determine what the code style patterns are and should match their style to what is already present. Of specific note however, TinkerPop does not use "import wildcards" - IDEs should be adjusted accordingly to not auto-wildcard the imports.

Build Server

TinkerPop uses both Travis and AppVeyor for CI services. Travis validates builds on Ubuntu, while AppVeyor validates builds on Windows. The build statuses can be found here:

Note that the CI process does not run integration tests or include Neo4j-related tests as those tests would likely exceed the allowable times for builds on these servers.


When possible, committers should avoid direct "breaking" change (e.g. removing a method from a class) and favor deprecation. Deprecation should come with sufficient documentation and notice especially when the change involves public APIs that might be utilized by users or implemented by vendors:

  • Mark the code with the @Deprecated annotation.

  • Use javadoc to further document the change with the following content:

    • @deprecated As of release 3.2.0-incubating, replaced by {@link SomeOtherClass#someNewMethod()} - if the method is not replaced then the comment can simply read "not replaced". Additional comments that provide more context are encouraged.

    • @see <a href="https://issues.apache.org/jira/browse/TINKERPOP-XXX">TINKERPOP-XXX</a> - supply a link to the JIRA issue for reference.

  • All deprecation should typically be tied to a JIRA issue with a "breaking" label - the issue itself does not need to specifically or solely be about "deprecation" but it should be documented very clearly in the comments what was deprecated and what the path forward should be.

  • Be sure that deprecated methods are still under test - consider using javadoc/comments in the tests themselves to call out this fact.

  • Create a new JIRA issue to track removal of the deprecation for future evaluation - this issue should have the "breaking" label as well as a "deprecation" label.

  • Update the "upgrade documentation" to reflect the API change and how the reader should resolve it.

The JIRA issues that track removal of deprecated methods should be periodically evaluated to determine if it is prudent to schedule them into a release.

Developing Tests

TinkerPop has a wide variety of test types that help validate its internal code as well as external provider code. There are "unit tests" and "integration tests". Unit tests execute on standard runs of mvn clean install. These tests tend to run quickly and provide a reasonable level of coverage and confidence in the code base. Integration tests are disabled by default and must be explicitly turned on with a special build property by adding -DskipIntegrationTests=false to the mvn execution. Integration tests run slower and may require external components to be running when they are executed. They are "marked" as separate from unit tests by inclusion of the suffix "IntegrateTest".

Here are some other points to consider when developing tests:

  • Avoid use of println in tests and prefer use of a SLF4j Logger instance so that outputs can be controlled in a standard way.

  • If it is necessary to create files on the filesystem, do not hardcode directories - instead, use the TestHelper to create directory structures. TestHelper will properly create file system structure in the appropriate build directory thus allowing proper clean-up between test runs.

  • If writing tests in one of the test suites, like gremlin-test, it is important to remember that if a new Graph instance is constructed within the test manually, that it be closed on exit of that test. Failing to do this cleanup can cause problems for some graph providers.

  • Tests that are designed to use a GraphProvider implementation in conjunction with AbstractGremlinTest and are in the /test directory should not be named with Test as the suffix, as this will cause them to execute in some environments without a GraphProvider being initialized by a suite. These types of tests should be suffixed with Check instead. Please see NativeNeo4jStructureCheck for an example.

Gremlin Language Test Cases

When writing a test case for a Gremlin step, be sure to use the following conventions.

  • The name of the traversal generator should start with get, use X for brackets, _ for space, and the Gremlin-Groovy sugar syntax.

    • get_g_V_hasLabelXpersonX_groupXaX_byXageX_byXsumX_name()

  • When creating a test for a step that has both a barrier and sideEffect form (e.g. group(), groupCount(), etc.), test both representations.

    • get_g_V_groupCount_byXnameX()

    • get_g_V_groupCountXaX_byXnameX_capXaX()

  • The name of the actual test case should be the name of the traversal generator minus the get_ prefix.

  • The Gremlin-Groovy version of the test should use the sugar syntax in order to test sugar (as Gremlin-Java8 tests test standard syntax).

    • g.V.age.sum

  • Avoid using lambdas in the test case unless that is explicitly what is being tested as OLAP systems will typically not be able to execute those tests.

  • AbstractGremlinProcessTest has various static methods to make writing a test case easy.

    • checkResults(Arrays.asList("marko","josh"), traversal)

    • checkMap(new HashMap<String,Long>() {{ put("marko",1l); }}, traversal.next())

Developing Benchmarks

Benchmarks are a useful tool to track performance between TinkerPop versions and also as tools to aid development decision making. TinkerPop uses OpenJDK JMH for benchmark development. The JMH framework provides tools for writing robust benchmarking code that avoid many of the pitfalls inherent in benchmarking JIT compiled code on the JVM. Example JMH benchmarks can be found here.

TinkerPop benchmarks live in the gremlin-benchmark module and can either be run from within your IDE or as a standalone uber-jar. The uber-jar is the JMH recommended approach and also makes it easy to distribute artifacts to various environments to gather benchmarking numbers. Having said that, in most cases it should be sufficient to run it from within the IDE.

Benchmarks will not run by default because they are time consuming. To enable benchmarks during the test phase do -DskipBenchmarks=false. To change the number of warmup iterations, measurement iterations, and forks you can do mvn clean test -DskipBenchmarks=false -DdefaultForks=5 -DmeasureIterations=20 -DwarmupIterations=20. Benchmark results will be output by default to the benchmarks directory in JSON format.

Benchmarks may also be run from the command line using the JMH runner. Build the uber-jar and simply run java -jar gremlin-benchmark-TP-VERSION.jar. To see a list of JMH runner options, add the -h flag.

The JUnit/JMH integration was inspired by the Netty projects microbenchmarking suite. Please refer to the Netty docs for more details. Presently there are 3 abstract benchmark classes that may be used as building blocks for your benchmarks; AbstractBenchmarkBase, AbstractGraphBenchmark, and AbstractGraphMutateBenchmark.

  • AbstractBenchmarkBase - extend when your benchmark does not require a graph instance

  • AbstractGraphBenchmark - extend when you are benchmarking read operations against a graph

  • AbstractGraphMutateBenchmark - extend when you are benchmarking graph mutation operations eg. g.addV(), graph.addVertex()

Review then Commit

Code modifications must go through a review-then-committ (RTC) process before being merged into a release branch. All committers should follow the pattern below, where "you" refers to the committer wanting to put code into a release branch.

  • Make a JIRA ticket for the software problem you want to solve (i.e. a fix).

  • Fork the release branch that the fix will be put into.

    • The branch name should be the JIRA issue identifier (e.g. TINKERPOP-XXX).

  • Develop your fix in your branch.

  • When your fix is complete and ready to merge, issue a pull request.

    • Be certain that the test suite is passing.

    • If you updated documentation, be sure that the process-docs.sh is building the documentation correctly.

  • Before you can merge your branch into the release branch, you must have at least 3 +1 consensus votes.

  • Votes are issued by TinkerPop committers as comments to the pull request.

  • Once 3 +1 votes are received, you are responsible for merging to the release branch and handling any merge conflicts.

    • If there is a higher version release branch that requires your fix (e.g. 3.y-1.z fix going to a 3.y.z release), be sure to merge to that release branch as well.

  • Be conscious of deleting your branch if it is no longer going to be used so stale branches don’t pollute the repository.

These steps also generally apply to external pull requests from those who are not official Apache committers. In this case, the person responsible for the merge after voting is typically the first person available who is knowledgeable in the area that the pull request affects. Any additional coordination on merging can be handled via the pull request comment system.

The following exceptions to the RTC (review-then-commit) model presented above are itemized below. It is up to the committer to self-regulate as the itemization below is not complete and only hints at the types of commits that do not require a review.

  • You are responsible for a release and need to manipulate files accordingly for the release.

    • Gremlin.version(), CHANGELOG dates, pom.xml version bumps, etc.

  • You are doing an minor change and it is obvious that an RTC is not required (would be a pointless burden to the community).

    • The fix is under the commit-then-review (CTR) policy and lazy consensus is sufficient, where a single -1 vote requires you to revert your changes.

    • Adding a test case, fixing spelling/grammar mistakes in the documentation, fixing LICENSE/NOTICE/etc. files, fixing a minor issue in an already merged branch.

When the committer chooses CTR, it is considered good form to include something in the commit message that explains that CTR was invoked and the reason for doing so. For example, "Invoking CTR as this change encompasses minor adjustments to text formatting."

Pull Request Format

When you submit a pull request, be sure it uses the following style.

  • The title of the pull request is the JIRA ticket number + "colon" + the title of the JIRA ticket.

  • The first line of the pull request message should contain a link to the JIRA ticket.

  • Discuss what you did to solve the problem articulated in the JIRA ticket.

  • Discuss any "extra" work done that go beyond the assumed requirements of the JIRA ticket.

  • Be sure to explain what you did to prove that the issue is resolved.

    • Test cases written.

    • Integration tests run (if required for the work accomplished).

    • Documentation building (if required for the work accomplished).

    • Any manual testing (though this should be embodied in a test case).

  • Notes about what you will do when you merge to the respective release branch (e.g. update CHANGELOG).

    • These types of "on merge tweaks" are typically done to extremely dynamic files to combat and merge conflicts.

  • If you are a TinkerPop committer, you can VOTE on your own pull request, so please do so.


There are many dependencies on other open source libraries in TinkerPop modules. When adding dependencies or altering the version of a dependency, developers must consider the implications that may apply to the TinkerPop LICENSE and NOTICE files. There are two implications to consider:

  1. Does the dependency fit an Apache approved license?

  2. Given the addition or modification to a dependency, does it mean any change for TinkerPop LICENSE and NOTICE files?

Understanding these implications is important for insuring that TinkerPop stays compliant with the Apache 2 license that it releases under.

Regarding the first item, refer to the Apache Legal for a list of approved licenses that are compatible with the Apache 2 license.

The second item requires a bit more effort to follow. The Apache website offers a how-to guide on the approach to maintaining appropriate LICENSE and NOTICE files, but this guide is designed to offer some more specific guidance as it pertains to TinkerPop and its distribution.

To get started, TinkerPop has both "source" and "binary" LICENSE/NOTICE files:

  • Source LICENSE/NOTICE relate to files packaged with the released source code distribution: LICENSE / NOTICE

  • Binary LICENSE/NOTICE relate to files packaged with the released binary distributions:


As dependencies are not typically added to the source distribution (i.e. the source zip distribution), there is typically no need to edit source LICENSE/NOTICE when editing a TinkerPop pom.xml. These files only need to be edited if the distribution has a file added to it. Such a situation may arise from several scenarios, but it would most likely come from the addition of a source file from another library.

  • If the file being bundled is Apache licensed, then add an entry to NOTICE.

  • If the file being bundled is under a different approved license, then add an entry to LICENSE and include a copy of that LICENSE in the root /licenses directory of the code repository.


The binary LICENSE/NOTICE is perhaps most impacted by changes to the various pom.xml files. After altering the pom.xml file of any module, build both Gremlin Console and Gremlin Server and examine the contents of both binary distributions, either:

  • target/apache-gremlin-console-3.2.0-incubating-distribution.zip

  • target/apache-gremlin-server-3.2.0-incubating-distribution.zip

Apache licensed software does not need to be included in LICENSE, but if the new dependency is an Apache-approved license (e.g. BSD, MIT) then it should be added in the pattern already defined. A copy of the LICENSE should be added to the <project>/static/licenses directory of the code repository.

To determine if changes are required to the NOTICE, first check if the bundled jar has a NOTICE file in it (typically found in /META-INF directory of the jar).

  • If the bundled file does not have a NOTICE, then no changes to TinkerPop’s NOTICE are required.

  • If the NOTICE of the file being bundled is NOT Apache licensed, then there is no change to TinkerPop’s NOTICE.

  • If the NOTICE of the file being bundled is Apache licensed, then include the copyright notification in TinkerPop’s NOTICE.

  • If the NOTICE of the file being bundled is Apache licensed AND is an Apache Software Foundation project, then ONLY include the portion of that NOTICE in TinkerPop’s NOTICE that is unrelated to the Apache boilerplate NOTICE. If there is no such portion that is different than the boilerplate then this NOTICE can be excluded (i.e. don’t alter TinkerPop’s NOTICE at all).

Please refer to the Modifications to Notice section of the Apache "Licensing How-to" for more information.


The documentation for TinkerPop is stored in the git repository in docs/src/ and are then split into several subdirectories, each representing a "book" (or its own publishable body of work). If a new AsciiDoc file is added to a book, then it should also be included in the index.asciidoc file for that book, otherwise the preprocessor will ignore it. Likewise, if a whole new book (subdirectory) is added, it must include an index.asciidoc file to be recognized by the AsciiDoc preprocessor.

Adding a book also requires a change to the root pom.xml file. Find the "asciidoc" Maven profile and add a new <execution> to the asciidoctor-maven-plugin configuration. For each book in docs/src/, there should be a related <execution> that generates the HTML from the AsciiDoc. Follows the patterns already established by the existing <execution> entries, paying special attention to the pathing of the <sourceDirectory>, <outputDirectory> and <imagesdir>. Note that the <outputDirectory> represents where the book will exist when uploaded to the server and should preserve the directory structure in git as referenced in <sourceDirectory>.

Please see the Building and Testing section for more information on how to generate the documentation.


TinkerPop uses SLF4j for logging and typically leans back on Log4j as the implementation. Configuring log outputs for debugging purposes within tests can be altered by editing the log4j-test.properties file in each module’s test resources. That file gets copied to the target/test-classes on build and surefire and failsafe plugins in maven are then configured to point at that area of the file system for those configuration files. The properties files can be edited to fine tune control of the log output, but generally speaking the current configuration is likely best for everyone’s general purposes, so if changes are made please revert them prior to commit.

For Providers

Graph Providers are those who develop third-party systems and libraries on top of the various TinkerPop APIs and protocols. They manage their projects independently of TinkerPop in separate repositories. Additional details for providers can be found in the Provider Documentation.

Release Process

This document describes the steps required to release a version of TinkerPop. The release is handled by a "release manager" (a committer fulfills this role), who ensures that the steps in this document are executed. The process is multi-phased and can therefore take several weeks to complete given the time needed for Apache voting and community feedback. Once a release point has been identified, the following phases represent the flow of "release":

It might be helpful to use this document as generated from the currently release as opposed to one generate from a previous version or from recent SNAPSHOT. When using one generated for release, all the "versions" in the commands end up being set to the version that is being released, making cut and paste of those commands less labor intensive and error prone.

Pre-flight Check

The "pre-flight check" is a list of things performed by the release manager during the weeks leading up to a scheduled day to release. These checks will help to ensure that that release day goes smoothly by identifying problems up early and communicating with other members of the community.

  1. Fourteen days before release, issue an email to the dev mailing list to remind the community of the pending release.

    1. Note any important issues open in JIRA in that post.

    2. Request review and update of the "upgrade documentation" and CHANGELOG.

  2. Seven days before release, announce the code freeze on the dev mailing list to remind the community that the branch under release is protected. Tweaks to documentation and other odds and ends related to release are still allowed during this period.

  3. At some point during the week:

    1. Run the full integration test suite: mvn clean install -DskipIntegrationTests=false -DincludeNeo4j

    2. Deploy a final SNAPSHOT to the snapshot repository.

    3. Review LICENSE and NOTICE files to make sure that no changes are needed.

    4. Review javadoc filters on the "Core API" docs to be sure nothing needs to change.

    5. Review JIRA tickets in the release and ensure that:

      1. All tickets categorized by having a "Component" assigned.

      2. All tickets are either of type "Bug" or "Enhancement".

  4. When all documentation changes are in place, use bin/publish-docs.sh to deploy a final SNAPSHOT representation of the docs and thus validate that there are no issues with the documentation generation process. Request review of the published documentation on the dev mailing list.

Release Candidate

A release candidate is an unofficial release that is represented by a tagged version in the Git repository. It is offered in cases where there is significant change in a particular version and the potential for upgrades and problems might be high.

  1. mvn clean install -DincludeNeo4j

    1. mvn verify -DskipIntegrationTests=false -DincludeNeo4j

    2. mvn verify -DskipPerformanceTests=false

  2. bin/publish-docs.sh <username> - note that under a release candidate the documentation is published as SNAPSHOT

  3. mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false to update the project files to reference a non-SNAPSHOT version

  4. git diff and review the updated files (expect all pom.xml files and this README)

  5. git commit -a -m "TinkerPop xx.yy.zz release" and git push

  6. git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz and git push --tags

  7. mvn clean install

  8. mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false to go back to SNAPSHOT

  9. git commit -a -m "Returned to xx.yy.zz-SNAPSHOT" and git push

  10. Announce the release candidate to dev mailing list and await feedback

  11. Repeat as required or proceed to the next phase

PMC Vote

A positive vote for a particular release from the TinkerPop PMC is required to move to the following phase.

  1. By this point, the testing performed during the code freeze should have validated the release. If however there are additional tests to perform that the release manager feels are relevant, they should be performed now. In other words, there is no need to rebuild the SNAPSHOT yet another time unless there are circumstances that would call its validity into question.

  2. Update the links in the README.asciidoc to point at the latest version.

  3. Update CHANGELOG.asciidoc:

    1. Update the release date

    2. Generate the JIRA release notes report for the current version and append them to the CHANGELOG.asciidoc.

      1. Use an "advanced" search to filter out JIRA issues already released on other versions. For example: fixVersion = 3.1.0-incubating AND fixVersion not in (3.0.2-incubating, 3.0.1-incubating).

      2. Consider use of an "Excel" export to organize, sort and prepare the JIRA tickets to be pasted to CHANGELOG.asciidoc

      3. Be sure to include a link to other versions in the CHANGELOG.asciidoc that were previously released while the current release was under development as this new release will have those changes included within it. Please see 3.1.0-incubating for an example.

    3. Organize "breaking" changes to be clearly marked (use JIRA and the "breaking" label to identify those)

  4. Update "upgrade documentation":

    1. Update the release date.

    2. Update the link to CHANGELOG.asciidoc

  5. mvn versions:set -DnewVersion=xx.yy.zz -DgenerateBackupPoms=false to update project files to reference the non-SNAPSHOT version

  6. git diff and review the updated files (expect all pom.xml files and this README)

  7. git commit -a -m "TinkerPop xx.yy.zz release" and push

  8. mvn clean install - need to build first so that the right version of the console is used with bin/publish-docs.sh

  9. bin/process-docs.sh and validate the generated documentation locally (don’t rely on "SUCCESS" - scroll up through logs to ensure there were no errors and view the HTML directly)

  10. bin/publish-docs.sh <username> - Note that this step requires no additional processing as the previous step. handled document generation and this step now merely needs to upload what was generated.

  11. mvn deploy -Papache-release -DcreateChecksum=true - deploy signed artifacts with checksums to Apache Nexus. Review (artifacts versions, file sizes, anything that might be out of place - request another committer to review as well) but do NOT close/release the staging repository at this time.

  12. Review generated artifacts to be sure they have both javadocs and asciidocs present then "close" the repo - if the repo is left open it will be automatically dropped after five days and closing the repo will allow it to stay available for a full ninety days which is more than enough time to complete a vote.

  13. Upload artifacts to https://dist.apache.org/repos/dist/dev/incubator/tinkerpop for [VOTE] review.

    1. svn co --depth empty https://dist.apache.org/repos/dist/dev/incubator/tinkerpop/ dev and mkdir dev/xx.yy.zz

    2. cp ~/.m2/repository/org/apache/tinkerpop/gremlin-console/xx.yy.zz/gremlin-console-xx.yy.zz-distribution.zip* dev/xx.yy.zz

    3. cp ~/.m2/repository/org/apache/tinkerpop/gremlin-server/xx.yy.zz/gremlin-server-xx.yy.zz-distribution.zip* dev/xx.yy.zz

    4. cp ~/.m2/repository/org/apache/tinkerpop/tinkerpop/xx.yy.zz/tinkerpop-xx.yy.zz-source-release.zip* dev/xx.yy.zz

    5. cd dev/xx.yy.zz

    6. ls * | xargs -n1 -I {} echo "mv apache-{} {}" | sed -e 's/distribution/bin/' -e 's/source-release/src/' -e s'/^\(.*\) \(.*\) \(.*\)$/\1 \3 \2/' | /bin/bash

    7. cd ..; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"

  14. Execute bin/validate-distribution.sh and any other relevant testing.

  15. git tag -a -m "TinkerPop xx.yy.zz release" xx.yy.zz and git push --tags

  16. Perform JIRA administration tasks:

    1. "Release" the current version and set the "release date"

    2. If there is to be a follow on release in the current line of code, create that new version specifying the "start date"

  17. Prepare Git administration tasks (apply the following steps as needed per release branch):

    1. Make the appropriate branching changes as required by the release and bump the version to SNAPSHOT with mvn versions:set -DnewVersion=xx.yy.zz-SNAPSHOT -DgenerateBackupPoms=false.

    2. mvn clean install - need to build first so that the right version of the console is used with bin/publish-docs.sh

    3. mvn deploy - deploy the new SNAPSHOT

    4. bin/process-docs.sh and validate the generated SNAPSHOT documentation locally

    5. bin/publish-docs.sh <username> to publish the SNAPSHOT docs which enables the README to work properly.

    6. Update the links in the README.asciidoc to point at the SNAPSHOT version.

    7. Commit and push the SNAPSHOT changes to git

  18. Submit for [VOTE] at dev@tinkerpop.apache.org (see email template below)

  19. Wait for vote acceptance (72 hours)

Incubator Vote

A positive vote for a particular release from the Apache Incubator is required to move to the following phase.

  1. Submit for [VOTE] at general@incubator.apache.org (see email template below)

    1. Include the vote tally: "Apache TinkerPop (http://tinkerpop.apache.org/) would like to release TinkerPop xx.yy.zz. We had a dev@ VOTE which resulted in a tally of +1 (3), 0 (0), and -1 (0). We now present our artifacts for vote by Incubator."

  2. Wait for vote acceptance (72 hours)

Release & Promote

  1. Login to Apache Nexus and release the previously closed repository.

  2. svn co --depth empty https://dist.apache.org/repos/dist/dev/incubator/tinkerpop dev; svn up dev/xx.yy.zz

  3. svn co --depth empty https://dist.apache.org/repos/dist/release/incubator/tinkerpop release; mkdir release/xx.yy.zz

  4. Copy release files from dev/xx.yy.zz to release/xx.yy.zz.

  5. cd release; svn add xx.yy.zz/; svn ci -m "TinkerPop xx.yy.zz release"

  6. Update homepage with references to latest distribution and to other internal links elsewhere on the page.

  7. Wait for Apache Central to sync the jars and src (http://repo1.maven.org/maven2/org/apache/tinkerpop/tinkerpop/).

  8. If there is are releases present in SVN that represents lines of code that are no longer under development, then remove those releases. In other words, if 3.1.0-incubating is present and 3.1.1-incubating is released then remove 3.1.0-incubating. However, if 3.0.2-incubating is present and that line of code is still under potential development, it may stay.

  9. Announce release on dev@/gremlin-users@ mailing lists and tweet from @apachetinkerpop

Email Templates

Release VOTE

Subject: [VOTE] TinkerPop xx.yy.zz Release


We are happy to announce that TinkerPop xx.yy.zz is ready for release.

The release artifacts can be found at this location:

The source distribution is provided by:

Two binary distributions are provided for user convenience:

The GPG key used to sign the release artifacts is available at:

The online docs can be found here:
	http://tinkerpop.apache.org/docs/xx.yy.zz/reference/ (user docs)
	http://tinkerpop.apache.org/docs/xx.yy.zz/upgrade/ (upgrade docs)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/core/ (core javadoc)
	http://tinkerpop.apache.org/javadocs/xx.yy.zz/full/ (full javadoc)

The tag in Apache Git can be found here:

The release notes are available here:

The [VOTE] will be open for the next 72 hours --- closing <DayOfTheWeek> (<Month> <Day> <Year>) at <Time> <TimeZone>.

My vote is +1.

Thank you very much,
<TinkerPop Committer Name>

If the above email template is used for the "Incubator Vote", then it should include the following just after the "release notes":

Finally, the dev@tinkerpop [VOTE] thread can be found at this location:


Result summary: +X (Y binding, Z non-binding), 0 (0), -1 (0)

where this link should point to the result of the VOTE.


Subject: [RESULT][VOTE] TinkerPop xx.yy.zz Release

This vote is now closed with a total of X +1s, no +0s and no -1s. The results are:


+1  (X -- list of voters)
0   (0)
-1  (0)


+1 (X -- list of voters)
0  (0)
-1 (0)

Thank you very much,
<TinkerPop Committer Name>

General Release Announcement

Subject: TinkerPop xx.yy.zz Released: [name of release line]


TinkerPop xx.yy.zz has just been released. You can find all the links and goodies on our homepage at http://tinkerpop.apache.org. However, if that is just one click too many, then the respective links are below.


New Committers

When a candidate is identified by a PPMC member as someone who might be a good official committer to TinkerPop, the PPMC member should open a DISCUSS thread on the private TinkerPop mailing list. The thread should provide some background and reasoning for why that member believes the candidate would be a good committer. Given enough time for feedback on the candidate and presuming there is still positive interest in doing so, a VOTE thread on the private TinkerPop mailing list is started to get the official stance. As per usual, the VOTE will be made open for no less than 72 hours.

If the VOTE closes with a successful positive vote to make the candidate a committer, then send the following email to the candidate and copy the private TinkerPop mailing list:

SUBJECT: Invitation to become TinkerPop committer: [candidate name]


The TinkerPop Podling Project Management Committee (PPMC)  hereby offers you committer privileges to the project.
These privileges are offered on the understanding that you'll use them reasonably and with common sense. We like to
work on trust rather than unnecessary constraints.

Being a committer enables you to more easily make changes without needing to go through the patch submission process.

Being a committer does not require you to participate any more than you already do. It does tend to make one even more
committed.  You will probably find that you spend more time here.

Of course, you can decline and instead remain as a contributor, participating as you do now.

A. This personal invitation is a chance for you to accept or decline in private.  Either way, please let us know in
reply to the private@tinkerpop.apache.org address only.

B. If you are accepting, the next step is to register an iCLA with the Apache Software Foundation:
    1. Details of the iCLA and the forms are found through this link: http://www.apache.org/licenses/#clas.

    2. The form (text or PDF version) provides instructions for its completion and return to the Secretary of the ASF.

    3. When you transmit the completed iCLA, request to notify the Apache TinkerPop and choose a unique Apache id.
       Look to see if your preferred id is already taken at http://people.apache.org/committer-index.html   This will
       allow the Secretary to notify the PMC when your iCLA has been recorded.

When recording of your iCLA is noticed, you will receive a follow-up message with the next steps for establishing you
as a committer.

Assuming the individual accepts, the next step is to get their account created. As we are in incubation, we will need to contact a mentor for help with this step.

Upon confirming with the new committer that their account is established, send an announcement email to the developer and user mailing lists:

SUBJECT: New Committer: [committer name]

The Podling Project Management Committee (PPMC) for Apache TinkerPop has asked [committer name] to become a committer
and we are pleased to announce that he has accepted.

[describe the nature of the committers work in the community]

Being a committer enables easier contribution to the project since there is no need to work via the patch submission
process. This should enable better productivity.

Finally, update the TinkerPop incubator project status page by:

  1. Adding to the "News" section

  2. Adding to the "Committers" section


November 23, 2015

The meeting was scheduled for 12:00pm EST, started at 12:05pm when sufficient attendance to constitute a quorum was reached and was held via Google Hangout hosted by Marko Rodriguez. Meeting adjourned at 2:35pm EST.

Committers/PPMC Members

  • Daniel Kuppitz

  • Stephen Mallette

  • Dylan Millikin

  • Jason Plurad

  • Marko Rodriguez

  • Ted Wilmes




  • Performed a full review of the list of unresolved tickets in JIRA. The summary of the changes can be found below. Note that releases and assignments made today are not meant to be set in stone. The assignments could change given community discussion or unforeseen events.

  • Decided to add version 3.2.0-incubating to JIRA. This version was added to help better categorize the available issues. It was explicitly decided that no development was expected to be performed on these issue at this time and that we would wait until 3.1.1-incubating was released before thinking too hard on that body of work. This decision means that the master branch will continue to be the current branch of development for the time being and be bound to 3.1.x line of code.

  • Discussed use of JIRA dependency links to show "blockers" and dependencies among different JIRA tickets.

  • Discussed a target date for upcoming releases:

    • 3.1.1-incubating - February 1, 2016

    • 3.2.0-incubating - May, 1, 2016

The following tickets were assigned to 3.1.1-incubating:

ID Description Type


MessageScope.Local.setStaticMessage(M msg)



GraphConfiguration Class



Automatic Traversal rewriting



IsStep broken when profiling is enabled.



Consider a P.instanceOf()



Do we need runtime BigDecimal in more places?



MapReduceHelper should sort respective of the number of reduce tasks



Provide a more general way to set log levels in plugins



Bindings applied to the PluginAcceptor should appear to Gremlin Server



Develop a less error prone way for rewriting strategies



Allow any GraphReader/Writer to be persistence engine for TinkerGraph



Re-examine Sandboxing Abstractions



Validate dependency grabs that have TinkerPop dependencies



Improve the ability to embed Gremlin Server with Channelizer injection



Test case needed for ensuring same cardinality for key.



bin/publish-docs.sh should only upload diffs.



Tie Alias to Transaction Manager in Gremlin Server



Add ability to cancel script execution associated with a Gremlin Server Session



Move the implementations sections of the primary documentation to "provider tutorials."



Add a "clear SNAPSHOT jars" section to the process-docs.sh.



Neo4jGraph should support HighAvailability (Neo4jHA).



Improve error message for wrong order().by() arguments



Warn if Gremlin Server is running prior to generating docs



Barrier steps provide unexpected results in Gremlin OLAP



Consistent test directory usage



Connection errors tend to force a complete close of the channel



Improve usability of .profile() step.



Test XXXGraphComputer on a Hadoop2 cluster (non-pseudocluster).



Support nested-repeat() structures



BLVP shouldn’t clear configuration properties



Fail earlier if invalid version is supplied in validate-distribution.sh



Native TinkerGraph Serializers for GraphSON



ComputerVerificationStrategy not picking up Order local traversal



Add a service script or daemon mode in the distribution



Deprecate support for credentialsDbLocation in Gremlin Server Config



Provide a way to track open Graph instances in tests



Use GraphProvider for id conversion in Groovy Environment test suite



Manage binary LICENSE/NOTICE files with bin/checkLicenseNotice.sh



SparkGraphComputer.submit shouldn’t use ForkJoinPool.commonPool


The following items were identified for 3.2.0-incubating:

ID Description Type


TraverserConverterStep (proposal)



Commutative Step Marker interface



Consider Required TraversalStrategies



TP3 is too prescriptive in exception



Serializer Handshake



Support "barrier syntax" in step labels.



Some basic mathematical functions / steps



Patterns for DSL Development



Choose then Enforce Semantics for Graph.close()



Implement AutoCloseable on TraversalSource



[Proposal] Domain/Range checking during traversal construction.



[Proposal] Make the Gremlin Graph Traversal Machine and Instruction Set Explicit



Mapping Cardinality Interface



How should OLAP treat Collection<Element> objects? No contract is specified.



PropertyMapStep should reuse PropertiesStep



Operator.mean would be nice.



RuntimeStrategy as the general model for all such execution time rewrites/re-orders



Remove GroupCountStep in favor of new Reduce-based GroupStep



FoldStep should default to using BulkSet for efficiency.



Refactor Gremlin Server integration tests to be Client parameterized



Support for partitioned vertices in GraphComputer



Remove the concept of branch/ package.



Features needs to specify whether 2 vertex properties with same key/value is allowed.



Convert LocalTraversals to MatchSteps in OLAP and Solve the StarGraph Problem



Use EventStrategy to solve OLAP bulk mutation of OLTP.



Consider deprecating or better enforcing Graph.Exceptions.elementNotFound



Traversal respecting Thread.interrupt()



Enforce semantics of threaded transactions as manual



Add a Bulk class which is used by Traverser



Provide "vertex query" selectivity when importing data in OLAP.



SubgraphTraversalAnalyzer to determine what is really required from a traversal.



Support reversible traversals in MatchStep (and respective MatchAlgorithms)






TraversalSource should be fluent like GraphComputer



Saving headless traversals for reuse (clone Iterator Fun)



valuesDecr, valuesIncr, keysDecr, and valuesDecr is lame.


The following issues were simply closed during review - the reasons for closing can be found in the comments of the issues themselves:

ID Description Type


Better Methods for Managing ClassPath for Plugins



User Supplied Ids and IO



Subgraph support for VertexProgram


DetachedEdge.attach(Vertex) is too slow.



Provide Traverser.setPath()



Add a TraversalSourceStrategy that provides "locked" values.



Shorthand for install of TinkerPop dependencies



Check feature requirements before opening graph during tests


October 29, 2015

The meeting was scheduled for 1:00pm EST, started on time and was held via Google Hangout hosted by Stephen Mallette. Meeting adjourned at 1:45pm EST.

Committers/PPMC Members

  • Daniel Kuppitz

  • Stephen Mallette

  • Marko Rodriguez




  • Reviewed the scope of 3.1.0-incubating in JIRA in the context of the upcoming release date on November 16, 2015.

  • It was noted that with the new one week code freeze policy that the real cut-off date for work is November 9, 2015.

  • There was general consensus on the call that work should be accomplished in such a way that the code review process not drag into the code freeze time period. In other words, pull requests to the release branch should be completed well ahead of the 9th.

Upon review of the tickets in JIRA assigned to 3.1.0-incubating, the following were removed from the 3.1.0-incubating roadmap:

ID Description Removal Reasoning


Re-examine Sandboxing Abstractions

Low priority and time limitations.


Remove the concept of branch/ package.

Awaiting step library definition in 3.2.0-incubating.


FoldStep should default to using BulkSet for efficiency.

Awaiting step library definition in 3.2.0-incubating.


Operator.mean would be nice.

Awaiting step library definition in 3.2.0-incubating.


Add a TraversalSourceStrategy that provides "locked" values.

Low priority and time limitations.


Remove PropertyMapStep in favor of multi-instruction construction.

Non-trivial given time limitations.


Choose then Enforce Semantics for Graph.close()

Non-trivial given time limitations.


MatchStep in OLAP should be smart about current vertex.

Non-trivial given time limitations.


Make use of a MemoryRDD instead of Accumulators in SparkGraphComputer?

Non-trivial given time limitations.


GraphConfiguration Class

Non-trivial given time limitations.


More output for OLAP jobs

Not clearly defined given time limitations.


Commutative Step Marker interface

Awaiting step library definition in 3.2.0-incubating


Gremlin IO needs to support both OLTP and OLAP naturally.

Not clearly defined given time limitations.


Consider Providing "getOrCreate" Functionality

Not clearly defined given time limitations.