~~ Licensed to the Apache Software Foundation (ASF) under one or more
~~ contributor license agreements.  See the NOTICE file distributed with
~~ this work for additional information regarding copyright ownership.
~~ The ASF licenses this file to You under the Apache License, Version 2.0
~~ (the "License"); you may not use this file except in compliance with
~~ the License.  You may obtain a copy of the License at
~~
~~     http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing, software
~~ distributed under the License is distributed on an "AS IS" BASIS,
~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~~ See the License for the specific language governing permissions and
~~ limitations under the License.

Contributing Code

  The following steps outline how to submit code to the VXQuery community for inclusion.
  Please read the Developer {{{http://vxquery.apache.org/developer_get_started.html}Get Started}} Guide
  to answer question about getting start as a developer.
  VXQuery community supports two methods for contributing code to the project.

  [[1]] <<Submit a patch file to an open VXQuery issue.>>

    This method works well for small bug fixes.

  [[1]] <<Create a pull request in github.>>

    The pull request will allow the community to give the developer (you) feedback
    and support in creating a quality submission.
    The following steps outline the github pull request process for the VXQuery community.

* Github Pull Request Process

** Developer

    * Pre-contribution steps to follow.

      * {{{http://vxquery.apache.org/user_get_started.html}Community steps}}.

      * {{{http://vxquery.apache.org/developer_get_started.html}Developer steps}}.

      * Create a {{{https://github.com/}github}} account.


    * Create a github fork of {{{https://github.com/apache/vxquery}Apache VXQuery}} project.

      Go to {{{https://github.com/apache/vxquery}Apache VXQuery}} github mirror.
      Create a fork by clicking on the fork button.
      Then clone the fork to your local machine for development.


    * Create a branch for your changes.

      VXQuery uses the following convention when creating a branch: authors_username/topic_or_issue
      (examples: prestonc/vxquery_142 or tillw/group_by_clause).
      The following branch name helps keep branches separated and keeps it easy to determine the author and topic.


    * Make the change.

      :-)


    * Add new tests. (optional)

      If the change is not covered in the XQTS, please create a new test in the VXQuery test suite
      to cover the code changes made to VXQuery.


    * Test your changes.

      Once the change is ready, test the branch against known passing Apache VXQuery tests.
      The patch must not break any of the existing test suites, either the VXQuery or currently passing XQTS.

      * {{{http://vxquery.apache.org/user_running_tests.html} Run the Test Suites}}

      * {{{http://vxquery.apache.org/development_update_xqts_results.html}Update Passing Tests}}


    * Clean up your code.

      Remove an extra debug code and verify the patch only includes code for the change.


    * Create a github Pull Request.

      Once the work has been tested, a pull request can be created for the change branch.
      Please use the Apache VXQuery master as branch to compare the change branch.
      The branch should be up-to-date with the lastest Apache VXQuery master branch.


    * Post your Pull Request.

      Post the Pull Request to the mailing list or issue to allow the VXQuery community to give feedback on the change.
      At least one other member of the community should review the change.
      If there is any feedback, address this and repeat the posting process.

** Code Reviewer

    * Review the Pull Request.

      Post inline or global comments for the developer.
      Be polite in your suggestions.
      Guide the developer to bring the code up to VXQuery's code standards.

    * Double check the VXQuery and XQTS tests.


** VXQuery Committer (author or sponsor of the change)

  The VXQuery committer will be responsible for the change made to the ASF git repository.
  While they do not need to be the author, the committer should have some understanding of the change
  they are pushing on to the repository.
  Often the committer will also be the reviewer for non-committer changes.

    * Double check the VXQuery and XQTS tests.

    * Merge the change with ASF master.

      When merging the change, do not rebase.
      Instead do a single merge commit into Apache VXQuery master.
