Merge "Tagging IPv6 stable/fraser branch for Fraser 6.1.0"
authorAric Gardner <agardner@linuxfoundation.org>
Sat, 26 May 2018 19:31:43 +0000 (19:31 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Sat, 26 May 2018 19:31:43 +0000 (19:31 +0000)
21 files changed:
jjb/apex/apex-deploy.sh
jjb/apex/apex-verify-jobs.yaml
jjb/apex/apex.yaml
jjb/apex/apex.yaml.j2
jjb/armband/armband-ci-jobs.yaml
jjb/functest/functest-daily-jobs.yaml
jjb/releng/releng-release-create-venv.sh [moved from jjb/releng/releng-release-verify.sh with 51% similarity]
jjb/releng/releng-release-jobs.yaml
jjb/releng/releng-release-tagging.sh [new file with mode: 0644]
releases/fraser/apex.yaml
releases/fraser/armband.yaml [moved from releases/fraser/armband.yml with 90% similarity]
releases/fraser/clover.yaml
releases/fraser/compass4nfv.yaml
releases/fraser/fuel.yaml
releases/fraser/functest.yaml
releases/fraser/joid.yaml
releases/fraser/samplevnf.yaml
releases/fraser/sfc.yaml
releases/fraser/yardstick.yaml
releases/scripts/release-status.sh [new file with mode: 0644]
releases/scripts/repos.py [new file with mode: 0644]

index 35c2b85..dfaf2a8 100755 (executable)
@@ -118,11 +118,8 @@ if [[ "$JOB_NAME" =~ "virtual" ]]; then
   if [[ "${DEPLOY_SCENARIO}" =~ fdio|ovs ]]; then
     DEPLOY_CMD="${DEPLOY_CMD} --virtual-default-ram 12 --virtual-compute-ram 7"
   fi
-  if [[ "$JOB_NAME" == *csit* ]]; then
-    DEPLOY_CMD="${DEPLOY_CMD} -e csit-environment.yaml"
-  fi
   if [[ "$PROMOTE" == "True" ]]; then
-    DEPLOY_CMD="${DEPLOY_CMD} --virtual-computes 1"
+    DEPLOY_CMD="${DEPLOY_CMD} --virtual-computes 2 -e csit-environment.yaml"
   fi
 else
   # settings for bare metal deployment
@@ -144,6 +141,8 @@ fi
 
 if [ "$IPV6_FLAG" == "True" ]; then
   NETWORK_FILE="${NETWORK_SETTINGS_DIR}/network_settings_v6.yaml"
+elif [[ "$PROMOTE" == "True" ]]; then
+  NETWORK_FILE="${NETWORK_SETTINGS_DIR}/network_settings_csit.yaml"
 else
   NETWORK_FILE="${NETWORK_SETTINGS_DIR}/network_settings.yaml"
 fi
@@ -157,7 +156,7 @@ fi
 # start deployment
 sudo ${DEPLOY_CMD} -d ${DEPLOY_FILE} -n ${NETWORK_FILE} --debug
 
-if [[ "$JOB_NAME" == *csit* ]]; then
+if [[ "$PROMOTE" == 'True' ]]; then
   echo "CSIT job: setting host route for floating ip routing"
   # csit route to allow docker container to reach floating ips
   UNDERCLOUD=$(sudo virsh domifaddr undercloud | grep -Eo "[0-9\.]+{3}[0-9]+")
index 7dbd670..f8e967b 100644 (file)
           blocking-jobs:
             - 'apex-verify.*'
             - 'apex-virtual.*'
+            - 'apex-.*-promote.*'
       - throttle:
           max-per-node: 1
           max-total: 10
index 0b64c93..15ab7e8 100644 (file)
           block-level: 'NODE'
           blocking-jobs:
             - 'apex-runner.*'
-            - 'apex-.*-promote.*'
             - 'apex-run.*'
             - 'apex-virtual-.*'
             - 'apex-verify-gate-.*'
                 GERRIT_REFSPEC=$GERRIT_REFSPEC
                 GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
                 GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
+                PROMOTE=$PROMOTE
               node-parameters: true
               kill-phase-on: FAILURE
               abort-all-job: true
           blocking-jobs:
             - 'apex-verify.*'
             - 'apex-runner.*'
-            - 'apex-.*-promote.*'
             - 'apex-run.*'
             - 'apex-testsuite-.+-baremetal-.+'
       - throttle:
           branch: '{branch}'
       - apex-parameter:
           gs-pathname: '{gs-pathname}'
+      - string:
+          name: ARTIFACT_VERSION
+          default: dev
+          description: "Used for overriding the ARTIFACT_VERSION"
+      - string:
+          name: PROMOTE
+          default: 'True'
+          description: "Used for overriding the PROMOTE"
 
     properties:
       - build-blocker:
           block-level: 'NODE'
           blocking-jobs:
             - 'apex-verify.*'
-            - 'apex-deploy.*'
             - 'apex-runner.*'
             - 'apex-daily.*'
 
 
     builders:
       - multijob:
-          name: deploy-virtual
+          name: apex-virtual-deploy-test
           condition: SUCCESSFUL
           projects:
-            - name: 'apex-deploy-virtual-{stream}'
-              current-parameters: false
+            - name: 'apex-virtual-{stream}'
+              current-parameters: true
               predefined-parameters: |
                 DEPLOY_SCENARIO=os-odl-{os_scenario}-noha
                 OPNFV_CLEAN=yes
                 GERRIT_REFSPEC=$GERRIT_REFSPEC
                 GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
                 GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
-                PROMOTE=True
-              node-parameters: true
-              kill-phase-on: FAILURE
-              abort-all-job: true
-              git-revision: false
-      - multijob:
-          name: functest-smoke
-          condition: SUCCESSFUL
-          projects:
-            - name: 'functest-apex-virtual-suite-{stream}'
-              current-parameters: false
-              predefined-parameters: |
-                DEPLOY_SCENARIO=os-odl-{os_scenario}-noha
-                FUNCTEST_SUITE_NAME=tempest_smoke_serial
-                GERRIT_BRANCH=$GERRIT_BRANCH
-                GERRIT_REFSPEC=$GERRIT_REFSPEC
-                GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
-                GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
               node-parameters: true
               kill-phase-on: FAILURE
               abort-all-job: true
-              git-revision: false
+              git-revision: true
       - multijob:
           name: create snapshot
           condition: SUCCESSFUL
index 35228e7..533781e 100644 (file)
           block-level: 'NODE'
           blocking-jobs:
             - 'apex-runner.*'
-            - 'apex-.*-promote.*'
             - 'apex-run.*'
             - 'apex-virtual-.*'
             - 'apex-verify-gate-.*'
                 GERRIT_REFSPEC=$GERRIT_REFSPEC
                 GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
                 GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
+                PROMOTE=$PROMOTE
               node-parameters: true
               kill-phase-on: FAILURE
               abort-all-job: true
           blocking-jobs:
             - 'apex-verify.*'
             - 'apex-runner.*'
-            - 'apex-.*-promote.*'
             - 'apex-run.*'
             - 'apex-testsuite-.+-baremetal-.+'
       - throttle:
           branch: '{branch}'
       - apex-parameter:
           gs-pathname: '{gs-pathname}'
+      - string:
+          name: ARTIFACT_VERSION
+          default: dev
+          description: "Used for overriding the ARTIFACT_VERSION"
+      - string:
+          name: PROMOTE
+          default: 'True'
+          description: "Used for overriding the PROMOTE"
 
     properties:
       - build-blocker:
           block-level: 'NODE'
           blocking-jobs:
             - 'apex-verify.*'
-            - 'apex-deploy.*'
             - 'apex-runner.*'
             - 'apex-daily.*'
 
 
     builders:
       - multijob:
-          name: deploy-virtual
+          name: apex-virtual-deploy-test
           condition: SUCCESSFUL
           projects:
-            - name: 'apex-deploy-virtual-{stream}'
-              current-parameters: false
+            - name: 'apex-virtual-{stream}'
+              current-parameters: true
               predefined-parameters: |
                 DEPLOY_SCENARIO=os-odl-{os_scenario}-noha
                 OPNFV_CLEAN=yes
                 GERRIT_REFSPEC=$GERRIT_REFSPEC
                 GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
                 GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
-                PROMOTE=True
-              node-parameters: true
-              kill-phase-on: FAILURE
-              abort-all-job: true
-              git-revision: false
-      - multijob:
-          name: functest-smoke
-          condition: SUCCESSFUL
-          projects:
-            - name: 'functest-apex-virtual-suite-{stream}'
-              current-parameters: false
-              predefined-parameters: |
-                DEPLOY_SCENARIO=os-odl-{os_scenario}-noha
-                FUNCTEST_SUITE_NAME=tempest_smoke_serial
-                GERRIT_BRANCH=$GERRIT_BRANCH
-                GERRIT_REFSPEC=$GERRIT_REFSPEC
-                GERRIT_CHANGE_NUMBER=$GERRIT_CHANGE_NUMBER
-                GERRIT_CHANGE_COMMIT_MESSAGE=$GERRIT_CHANGE_COMMIT_MESSAGE
               node-parameters: true
               kill-phase-on: FAILURE
               abort-all-job: true
-              git-revision: false
+              git-revision: true
       - multijob:
           name: create snapshot
           condition: SUCCESSFUL
index b8ffc16..fe2bbcc 100644 (file)
             same-node: true
             block: true
       - trigger-builds:
-          - project: 'functest-{installer}-{pod}-arm-daily-{stream}'
+          - project: 'functest-{installer}-{pod}-daily-{stream}'
             current-parameters: false
             predefined-parameters:
               DEPLOY_SCENARIO={scenario}
index ae226b6..4fc67e7 100644 (file)
       - 'suite':
           job-timeout: 60
       - 'daily':
-          job-timeout: 360
-      - 'arm-daily':
           job-timeout: 480
 
     jobs:
           default: 'daily'
           description: "Daily suite name to run"
 
-- parameter:
-    name: functest-arm-daily-parameter
-    parameters:
-      - string:
-          name: FUNCTEST_MODE
-          default: 'arm-daily'
-          description: "Daily suite name (Aarch64) to run"
-
 - parameter:
     name: functest-suite-parameter
     parameters:
       - 'functest-store-results'
       - 'functest-exit'
 
-- builder:
-    name: functest-arm-daily-builder
-    builders:
-      - 'functest-cleanup'
-      - 'functest-arm-daily'
-      - 'functest-store-results'
-      - 'functest-exit'
-
 - builder:
     name: functest-suite-builder
     builders:
                     - ../../utils/fetch_k8_conf.sh
                     - ./functest-k8.sh
 
-# yamllint enable rule:indentation
-- builder:
-    name: functest-arm-daily
-    builders:
-      # yamllint disable rule:indentation
-      - shell:
-          !include-raw:
-              - ./functest-env-presetup.sh
-              - ../../utils/fetch_os_creds.sh
-              - ./functest-alpine.sh
-
 # yamllint enable rule:indentation
 - builder:
     name: functest-store-results
similarity index 51%
rename from jjb/releng/releng-release-verify.sh
rename to jjb/releng/releng-release-create-venv.sh
index c1262e2..0d5635b 100644 (file)
@@ -7,21 +7,12 @@
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
-set -xe
+set -e -o pipefail
+echo "---> Create virtualenv"
 
-# Activate virtualenv, supressing shellcheck warning
-# shellcheck source=/dev/null
-. $WORKSPACE/venv/bin/activate
+sudo pip install virtualenv
+virtualenv $WORKSPACE/venv
+# shellcheck source=$WORKSPACE/venv/bin/activate disable=SC1091
+source $WORKSPACE/venv/bin/activate
+pip install --upgrade pip
 pip install -r releases/scripts/requirements.txt
-
-STREAM=${STREAM:-'nostream'}
-RELEASE_FILES=$(git diff HEAD^1 --name-only -- "releases/$STREAM")
-
-# TODO: The create_branch.py should be refactored so it can be used here
-# to verify the commit exists that is being added, along with
-# jjb/<project>
-for release_file in $RELEASE_FILES; do
-    python releases/scripts/verify_schema.py \
-    -s releases/schema.yaml \
-    -y $release_file
-done
index e31320b..0c059ee 100644 (file)
@@ -10,6 +10,8 @@
 - project:
     name: releng-release-jobs
 
+    build-node: 'opnfv-build'
+
     stream:
       - fraser
 
@@ -23,6 +25,7 @@
     name: 'releng-release-{stream}-verify'
 
     parameters:
+      - '{build-node}-defaults'
       - stream-parameter:
           stream: '{stream}'
       - project-parameter:
@@ -59,9 +62,9 @@
                   pattern: 'releases/scripts/verify_schema.py'
 
     builders:
-      - create-virtualenv
-      - shell:
-          !include-raw-escape: releng-release-verify.sh
+      - shell: !include-raw-escape:
+          - releng-release-create-venv.sh
+          - releng-release-tagging.sh
 
     publishers:
       - email-jenkins-admins-on-failure
       - project-parameter:
           project: '{project}'
           branch: 'master'
+      # Override GIT_BASE so we can send patches back to Gerrit and
+      # modify repos
+      - string:
+          name: GIT_BASE
+          default: ssh://$USER@gerrit.opnfv.org:29418/$PROJECT
+          description: 'Git URL to use on this Jenkins Slave'
 
     scm:
       - git-scm-gerrit
           files: 'releases/{stream}/*'
 
     builders:
-      - create-virtualenv
-      - shell:
-          !include-raw-escape: releng-release-create-branch.sh
+      - shell: !include-raw-escape:
+          - releng-release-create-venv.sh
+          - releng-release-tagging.sh
+          # - releng-release-create-branch.sh
 
     publishers:
       - email-jenkins-admins-on-failure
           name: STREAM
           default: '{stream}'
           description: "OPNFV Stable Stream"
-
-- builder:
-    name: create-virtualenv
-    builders:
-      - shell: |
-          #!/bin/bash
-          sudo pip install virtualenv
-          virtualenv $WORKSPACE/venv
-          . $WORKSPACE/venv/bin/activate
-          pip install --upgrade pip
diff --git a/jjb/releng/releng-release-tagging.sh b/jjb/releng/releng-release-tagging.sh
new file mode 100644 (file)
index 0000000..10c0cc8
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+# SPDX-License-Identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018 The Linux Foundation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+set -e -o pipefail
+
+GIT_URL=${GIT_URL:-https://gerrit.opnfv.org/gerrit}
+STREAM=${STREAM:-'nostream'}
+RELEASE_FILES=$(git diff HEAD^1 --name-only -- "releases/$STREAM")
+
+echo "--> Verifying $RELEASE_FILES."
+for release_file in $RELEASE_FILES; do
+    # Verify the release file schema
+    python releases/scripts/verify_schema.py \
+    -s releases/schema.yaml \
+    -y $release_file
+
+    # Verify tag for each repo exist and are attached to commits on stable-branch
+    while read -r repo tag ref
+    do
+      echo "--> Cloning $repo"
+      if [ ! -d $repo ]; then
+          git clone $GIT_URL/$repo.git $repo
+      fi
+      pushd $repo &> /dev/null
+
+      echo "--> Checking for tag: $tag"
+      if ! (git tag -l | grep $tag &> /dev/null); then
+          echo "$tag does not exist"
+          TAG_EXISTS=false
+      else
+          git cat-file tag $tag
+          TAG_EXISTS=true
+      fi
+
+      echo "--> Checking if $ref is on stable/$STREAM"
+      if ! (git branch -a --contains $ref | grep "stable/$STREAM"); then
+          echo "--> ERROR: $ref for $repo is not on stable/$STREAM!"
+          # If the tag exists but is on the wrong ref, there's nothing
+          # we can do. But if the tag neither exists nor is on the
+          # correct branch we need to fail the verification.
+          if [ $TAG_EXISTS = false ]; then
+              exit 1
+          fi
+      else
+          if [[ $TAG_EXISTS = false && "$JOB_NAME" =~ "merge" ]]; then
+              # If the tag doesn't exist and we're in a merge job,
+              # everything has been verified up to this point and we
+              # are ready to create the tag.
+              git config --global user.name "jenkins-ci"
+              git config --global user.email "jenkins-opnfv-ci@opnfv.org"
+              echo "--> Creating $tag tag for $repo at $ref"
+              git tag -am "$tag" $tag $ref
+              echo "--> Pushing tag"
+              echo "[noop] git push origin $tag"
+          else
+              # For non-merge jobs just output the ref info.
+              git show -s --format="%h %s %d" $ref
+          fi
+      fi
+
+      popd &> /dev/null
+      echo "--> Done verifing $repo"
+    done < <(python releases/scripts/repos.py -f $release_file)
+done
index c097d06..5d0f569 100644 (file)
@@ -25,6 +25,18 @@ releases:
   - version: opnfv-6.0.0
     location:
       apex-os-net-config: e09d110d7b58d26424c28a128cdfd8c766636461
+  - version: opnfv-6.1.0
+    location:
+      apex: a1f2e922d18430e064c9c8311f01ac2a0df19414
+  - version: opnfv-6.1.0
+    location:
+      apex-tripleo-heat-templates: 7f1cc97bcd6f267b11a251de3204edf0e8ec79c0
+  - version: opnfv-6.1.0
+    location:
+      apex-puppet-tripleo: bebd15efe40498c272577c563bc113ec3849dcc6
+  - version: opnfv-6.1.0
+    location:
+      apex-os-net-config: e09d110d7b58d26424c28a128cdfd8c766636461
 
 branches:
   - name: stable/fraser
similarity index 90%
rename from releases/fraser/armband.yml
rename to releases/fraser/armband.yaml
index 66afd10..3a2b260 100644 (file)
@@ -15,6 +15,9 @@ releases:
   - version: opnfv-6.0.0
     location:
       armband: 2b0ac4026a3acf3b10ab2f4c416636d80ab559f0
+  - version: opnfv-6.1.0
+    location:
+      armband: 0de669e26d14794ab117e915abaa6bf6b1dd878d
 
 branches:
   - name: stable/fraser
index c731d2a..ba3e7d6 100644 (file)
@@ -10,6 +10,9 @@ releases:
   - version: opnfv-6.0.1
     location:
       clover: be5f20bbe91f1ae3138a1e338eea5b45e89bda82
+  - version: opnfv-6.1.0
+    location:
+      clover: 596a3573b2622a5d314349592088b6b737f5e126
 
 branches:
   - name: stable/fraser
index 5c44336..c01ca9f 100644 (file)
@@ -4,6 +4,13 @@ project-type: installer
 release-model: stable
 
 releases:
+  - version: opnfv-6.1.0
+    location:
+      compass4nfv: 499d95cdea092ea9eb76a939b6ea832601d41b7f
+  - version: opnfv-6.1.0
+    location:
+      compass-containers: 15a7cbc925bed896c3c09a5635454c33dbffbadc
+
   - version: opnfv-6.0.0
     location:
       compass4nfv: ab73374e424a679cc42b9812e6bd39a49fcea07d
index 226ba58..dd45d30 100644 (file)
@@ -15,6 +15,9 @@ releases:
   - version: opnfv-6.0.0
     location:
       fuel: d45841926790df8313912697d31753c120e2c4aa
+  - version: opnfv-6.1.0
+    location:
+      fuel: e29220a401a5ad0607453d6a82de9b61d1c02aca
 
 branches:
   - name: stable/fraser
index d1837b8..e127588 100644 (file)
@@ -10,6 +10,12 @@ releases:
   - version: opnfv-6.0.0
     location:
       functest-kubernetes: 770bd295031af2e12da3472b9ed2763bfdc4deaf
+  - version: opnfv-6.1.0
+    location:
+      functest: 7be15936ba4fd0f624200ae6b587081ab292077c
+  - version: opnfv-6.1.0
+    location:
+      functest-kubernetes: c3e48ccef64acc6ba31823e1c8d6138eebbffb8c
 
 branches:
   - name: stable/fraser
index 6c230c3..fcb6d37 100644 (file)
@@ -16,6 +16,10 @@ releases:
     location:
       joid: 266a4fd08bef19fca930cbbb1d45f5639b87d3c0
 
+  - version: opnfv-6.1.0
+    location:
+      joid: ff656d6b0fa60241c76709a41c023b76ba4def8f
+
 branches:
   - name: stable/fraser
     location:
index 3c30f72..984ca8c 100644 (file)
@@ -7,6 +7,9 @@ releases:
   - version: opnfv-6.0.0
     location:
       samplevnf: 4685c59ec97927af559b4bf10001d0e07de34702
+  - version: opnfv-6.1.0
+    location:
+      samplevnf: 95e9ab89f6d8f9911a9fdb625e8721f3d2e20b1a
 
 branches:
   - name: stable/fraser
index 83850d7..8da8287 100644 (file)
@@ -7,6 +7,10 @@ releases:
   - version: opnfv-6.0.0
     location:
       sfc: 084446656bf2794a11de56b782f589af1f703487
+  - version: opnfv-6.1.0
+    location:
+      sfc: 7f8a775dec72e03d6cae2400b7a49d7a097c8957
+
 
 branches:
   - name: stable/fraser
index 59f6c10..25ab64c 100644 (file)
@@ -7,6 +7,9 @@ releases:
   - version: opnfv-6.0.0
     location:
       yardstick: a4c8f2a99f56dd4c9fbac4021706aa9186d23ed8
+  - version: opnfv-6.1.0
+    location:
+      yardstick: 7dc30d54a77249d95d2a89770393cee98ff63c8c
 
 branches:
   - name: stable/fraser
diff --git a/releases/scripts/release-status.sh b/releases/scripts/release-status.sh
new file mode 100644 (file)
index 0000000..da66bc9
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/bash
+# SPDX-License-Identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018 The Linux Foundation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+set -o pipefail
+
+TAG="${TAG:-opnfv-6.0.0}"
+RELEASE="${RELEASE:-fraser}"
+
+for project in releases/$RELEASE/*; do
+    python releases/scripts/repos.py -n -f $project >> repos.txt
+done
+
+while read -r repo
+do
+    tag="$(git ls-remote "https://gerrit.opnfv.org/gerrit/$repo.git" "refs/tags/$TAG")"
+    echo "$repo $tag"
+done < repos.txt
+
+# rm repos.txt
diff --git a/releases/scripts/repos.py b/releases/scripts/repos.py
new file mode 100644 (file)
index 0000000..0ded020
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/env python2
+# SPDX-License-Identifier: Apache-2.0
+##############################################################################
+# Copyright (c) 2018 The Linux Foundation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+"""
+List Release Repos
+"""
+
+import argparse
+import yaml
+
+
+def main():
+    """Given a release yamlfile list the repos it contains"""
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--file', '-f',
+                        type=argparse.FileType('r'),
+                        required=True)
+    parser.add_argument('--names', '-n',
+                        action='store_true',
+                        default=False,
+                        help="Only print the names of repos, "
+                             "not their SHAs")
+    parser.add_argument('--release', '-r',
+                        type=str,
+                        help="Only print"
+                             "SHAs for the specified release")
+    args = parser.parse_args()
+
+    project = yaml.safe_load(args.file)
+
+    list_repos(project, args)
+
+
+def list_repos(project, args):
+    """List repositories in the project file"""
+
+    lookup = project.get('releases', [])
+    if 'releases' not in project:
+        exit(0)
+
+    for item in lookup:
+        repo, ref = next(iter(item['location'].items()))
+        if args.names:
+            print(repo)
+        elif args.release and item['version'] == args.release:
+            print("%s %s" % (repo, ref))
+        elif not args.release:
+            # Print all releases
+            print("%s %s %s" % (repo, item['version'], ref))
+
+
+if __name__ == "__main__":
+    main()