|
| 1 | +name: CI/CD |
| 2 | + |
| 3 | +on: |
| 4 | + push: |
| 5 | + branches: |
| 6 | + - main |
| 7 | + - '*\@[0-9]+.[0-9]+.[0-9]+*' # package development branch |
| 8 | + |
| 9 | +jobs: |
| 10 | + build: |
| 11 | + if: ${{ !contains(github.event.head_commit.message, '[no ci]') }} |
| 12 | + runs-on: ubuntu-latest |
| 13 | + outputs: |
| 14 | + branch: ${{ steps.get_pkg_info.outputs.branch }} |
| 15 | + pkg_name: ${{ steps.get_pkg_info.outputs.pkg_name }} |
| 16 | + pkg_ver: ${{ steps.get_pkg_info.outputs.pkg_ver }} |
| 17 | + docker_file: ${{ steps.get_pkg_info.outputs.docker_file }} |
| 18 | + repo_lowercase: ${{ steps.repo_lowercase.outputs.lowercase }} |
| 19 | + steps: |
| 20 | + - uses: actions/checkout@v2 |
| 21 | + |
| 22 | + - name: Set up Python 3.6 |
| 23 | + uses: actions/setup-python@v2 |
| 24 | + with: |
| 25 | + python-version: 3.6 |
| 26 | + |
| 27 | + - name: Extract package name and version from branch name |
| 28 | + id: get_pkg_info |
| 29 | + shell: bash |
| 30 | + run: | |
| 31 | + echo "::set-output name=branch::$(echo ${GITHUB_REF#refs/heads/})" |
| 32 | + PKG_NAME=$(echo ${GITHUB_REF#refs/heads/} | awk -F'@' '{print $1}') |
| 33 | + PKG_VER=$(echo ${GITHUB_REF#refs/heads/} | awk -F'@' '{print $2}') |
| 34 | + echo "::set-output name=pkg_name::$(echo $PKG_NAME)" |
| 35 | + echo "::set-output name=pkg_ver::$(echo $PKG_VER)" |
| 36 | + if [[ -f "./$PKG_NAME/Dockerfile" ]]; then |
| 37 | + echo "::set-output name=docker_file::$(echo ./$PKG_NAME/Dockerfile)" |
| 38 | + else |
| 39 | + echo "::set-output name=docker_file::" |
| 40 | + fi |
| 41 | +
|
| 42 | + - name: Login to GitHub Container Registry |
| 43 | + if: ${{ steps.get_pkg_info.outputs.branch != 'main' && steps.get_pkg_info.outputs.docker_file != ''}} |
| 44 | + uses: docker/login-action@v1 |
| 45 | + with: |
| 46 | + registry: ghcr.io |
| 47 | + username: ${{ github.repository_owner }} |
| 48 | + password: ${{ secrets.CR_PAT }} |
| 49 | + |
| 50 | + - id: repo_lowercase |
| 51 | + uses: ASzc/change-string-case-action@v1 |
| 52 | + with: |
| 53 | + string: ${{ github.repository }} |
| 54 | + |
| 55 | + - name: Build image |
| 56 | + if: ${{ steps.get_pkg_info.outputs.branch != 'main' && steps.get_pkg_info.outputs.docker_file != ''}} |
| 57 | + uses: docker/build-push-action@v2 |
| 58 | + with: |
| 59 | + context: "./${{steps.get_pkg_info.outputs.pkg_name}}" |
| 60 | + file: "${{steps.get_pkg_info.outputs.docker_file}}" |
| 61 | + platforms: linux/amd64 |
| 62 | + load: true |
| 63 | + tags: | |
| 64 | + ghcr.io/${{ steps.repo_lowercase.outputs.lowercase }}.${{ steps.get_pkg_info.outputs.pkg_name }}:${{ steps.get_pkg_info.outputs.pkg_ver }} |
| 65 | +
|
| 66 | + - name: Push image to ghcr.io |
| 67 | + id: push_to_ghcr |
| 68 | + if: ${{ steps.get_pkg_info.outputs.branch != 'main' && steps.get_pkg_info.outputs.docker_file != ''}} |
| 69 | + shell: bash |
| 70 | + run: | |
| 71 | + docker push ghcr.io/${{ steps.repo_lowercase.outputs.lowercase }}.${{ steps.get_pkg_info.outputs.pkg_name }}:${{ steps.get_pkg_info.outputs.pkg_ver }} | tee ./ghcr.io.stdout |
| 72 | + IMAGE_SHA=$(cat ./ghcr.io.stdout | tr ' ' '\n' | grep 'sha256:' | awk -F':' '{print $2}') |
| 73 | + echo "::set-output name=image_sha256::$(echo ${IMAGE_SHA})" |
| 74 | + echo "::set-output name=created_at::$(date -u +%FT%TZ)" |
| 75 | +
|
| 76 | +
|
| 77 | + test-and-release: |
| 78 | + runs-on: ubuntu-latest |
| 79 | + needs: [build] |
| 80 | + steps: |
| 81 | + - uses: actions/checkout@v2 |
| 82 | + |
| 83 | + - name: Set up Python 3.6 |
| 84 | + uses: actions/setup-python@v2 |
| 85 | + with: |
| 86 | + python-version: 3.6 |
| 87 | + |
| 88 | + - name: Install dependencies |
| 89 | + run: | |
| 90 | + python -m pip install --upgrade pip |
| 91 | + pip install wfpm |
| 92 | + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi |
| 93 | + if [ -f requirements-test.txt ]; then pip install -r requirements-test.txt; fi |
| 94 | + if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi |
| 95 | +
|
| 96 | + - name: Install Nextflow |
| 97 | + run: | |
| 98 | + wget --tries=10 -qO- https://get.nextflow.io | bash |
| 99 | + sudo chmod 755 nextflow |
| 100 | + sudo mv nextflow /usr/local/bin/ |
| 101 | +
|
| 102 | + - name: "Login to GitHub Container Registry" # normally shouldn't need to login, but new image when just created is private |
| 103 | + uses: docker/login-action@v1 |
| 104 | + with: |
| 105 | + registry: ghcr.io |
| 106 | + username: ${{ github.repository_owner }} |
| 107 | + password: ${{ secrets.CR_PAT }} |
| 108 | + |
| 109 | + - name: Run tests for all packages |
| 110 | + if: ${{ needs.build.outputs.branch == 'main' }} |
| 111 | + run: | |
| 112 | + wfpm test |
| 113 | +
|
| 114 | + - name: Run tests for the current package only |
| 115 | + if: ${{ needs.build.outputs.branch != 'main' }} |
| 116 | + run: | |
| 117 | + cd ./${{needs.build.outputs.pkg_name}} |
| 118 | + wfpm test |
| 119 | +
|
| 120 | + - name: Check whether to proceed with release |
| 121 | + id: to_release |
| 122 | + run: | |
| 123 | + if [[ \ |
| 124 | + "${{ github.event.head_commit.message }}" = "Merge"[[:space:]]"pull"[[:space:]]"request"* && \ |
| 125 | + "${{ github.event.head_commit.message }}" = *"@"* && \ |
| 126 | + "${{ github.event.head_commit.message }}" = *"[release]"* && \ |
| 127 | + "${{ needs.build.outputs.branch }}" = 'main' |
| 128 | + ]]; then |
| 129 | + echo "::set-output name=release::$(echo Y)" |
| 130 | + else |
| 131 | + echo "::set-output name=release::$(echo N)" |
| 132 | + fi |
| 133 | +
|
| 134 | + - name: Extract package name and version from commit message |
| 135 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 136 | + id: get_pkg_info |
| 137 | + shell: bash |
| 138 | + run: | |
| 139 | + MERGED_BR=$(echo -e '${{ github.event.head_commit.message }}' | \ |
| 140 | + { grep '^Merge pull request'||:; } | tr ' ' '\n' |{ grep '@'||:; } | awk -F'/' '{print $2}') |
| 141 | + PKG_NAME=$(echo $MERGED_BR | awk -F'@' '{print $1}') |
| 142 | + PKG_VER=$(echo $MERGED_BR | awk -F'@' '{print $2}') |
| 143 | + echo "::set-output name=pkg_name::$(echo ${PKG_NAME})" |
| 144 | + echo "::set-output name=pkg_ver::$(echo ${PKG_VER})" |
| 145 | + if [[ -f "./$PKG_NAME/Dockerfile" ]]; then |
| 146 | + echo "::set-output name=docker_file::$(echo ./$PKG_NAME/Dockerfile)" |
| 147 | + echo "::set-output name=docker_image::$(echo ghcr.io/${{ needs.build.outputs.repo_lowercase }}.$PKG_NAME:$PKG_VER)" |
| 148 | + else |
| 149 | + echo "::set-output name=docker_file::" |
| 150 | + echo "::set-output name=docker_image::" |
| 151 | + fi |
| 152 | +
|
| 153 | + - name: Prepare package release tarball |
| 154 | + id: prep_assets |
| 155 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 156 | + shell: bash |
| 157 | + run: | |
| 158 | + ./scripts/cleanup_temp_files.sh # just in case |
| 159 | + PKG_TAR=${{ steps.get_pkg_info.outputs.pkg_name }}.v${{ steps.get_pkg_info.outputs.pkg_ver }}.tar.gz |
| 160 | + pushd ${{ steps.get_pkg_info.outputs.pkg_name }} |
| 161 | + tar --exclude=wfpr_modules --dereference -czvf ../$PKG_TAR . |
| 162 | + popd |
| 163 | + echo "::set-output name=pkg_tar::$(echo ${PKG_TAR})" |
| 164 | + echo "::set-output name=pkg_tar_sha::$(sha256sum ${PKG_TAR} |awk '{print $1}')" |
| 165 | + echo "::set-output name=pkg_tar_size::$(ls -l ${PKG_TAR} |awk '{print $5}')" |
| 166 | + echo "::set-output name=created_at::$(date -u +%FT%TZ)" |
| 167 | +
|
| 168 | + - name: Create release |
| 169 | + id: create_release |
| 170 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 171 | + uses: actions/create-release@v1 |
| 172 | + env: |
| 173 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 174 | + with: |
| 175 | + tag_name: ${{ steps.get_pkg_info.outputs.pkg_name }}.v${{ steps.get_pkg_info.outputs.pkg_ver }} |
| 176 | + release_name: ${{ steps.get_pkg_info.outputs.pkg_name }}.v${{ steps.get_pkg_info.outputs.pkg_ver }} |
| 177 | + body: | |
| 178 | + * Release `${{ steps.get_pkg_info.outputs.pkg_name }}.v${{ steps.get_pkg_info.outputs.pkg_ver }}` (${{ github.sha }}) |
| 179 | + * Package `${{ steps.prep_assets.outputs.pkg_tar }}` (sha256: `${{ steps.prep_assets.outputs.pkg_tar_sha }}`) |
| 180 | + draft: false |
| 181 | + prerelease: false |
| 182 | + |
| 183 | + - name: Prepare in pkg-release.json |
| 184 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 185 | + shell: bash |
| 186 | + run: | |
| 187 | + WFPM_VER=$(wfpm -v | cut -d ' ' -f 2) |
| 188 | + if [[ '${{ steps.get_pkg_info.outputs.docker_file }}' != '' ]]; then |
| 189 | + docker pull ${{ steps.get_pkg_info.outputs.docker_image }} | tee image.info |
| 190 | + IMAGE_SHA=$(cat ./image.info | tr ' ' '\n' | grep 'sha256:' | awk -F':' '{print $2}') |
| 191 | + else |
| 192 | + IMAGE_SHA=$(echo) |
| 193 | + fi |
| 194 | +
|
| 195 | + # temporary solution |
| 196 | + TAG="${{ steps.get_pkg_info.outputs.pkg_name }}.v${{ steps.get_pkg_info.outputs.pkg_ver }}" |
| 197 | + ./scripts/prepare_package_release_json.py -p ${{ steps.get_pkg_info.outputs.pkg_name }}/pkg.json -d \ |
| 198 | + " |
| 199 | + { |
| 200 | + \"_release\": { |
| 201 | + \"created\": \"${{ steps.prep_assets.outputs.created_at }}\", |
| 202 | + \"hash\": { |
| 203 | + \"checksum_type\": \"sha1\", |
| 204 | + \"checksume\": \"${{ github.sha }}\" |
| 205 | + }, |
| 206 | + \"tag\": \"$TAG\", |
| 207 | + \"assets\": [ |
| 208 | + { |
| 209 | + \"filename\": \"$TAG.tar.gz\", |
| 210 | + \"download_url\": \"https://github.com/${{ github.repository }}/releases/download/$TAG/$TAG.tar.gz\", |
| 211 | + \"checksum\": \"${{ steps.prep_assets.outputs.pkg_tar_sha }}\", |
| 212 | + \"checksum_type\": \"sha256\", |
| 213 | + \"size\": ${{ steps.prep_assets.outputs.pkg_tar_size }} |
| 214 | + }, |
| 215 | + { |
| 216 | + \"_NOTE_\": \"this file\", |
| 217 | + \"filename\": \"pkg-release.json\", |
| 218 | + \"download_url\": \"https://github.com/${{ github.repository }}/releases/download/$TAG/pkg-release.json\", |
| 219 | + \"checksum\": null, |
| 220 | + \"checksum_type\": null, |
| 221 | + \"size\": null |
| 222 | + } |
| 223 | + ] |
| 224 | + }, |
| 225 | + \"_image_digest\": { |
| 226 | + \"checksum\": \"$IMAGE_SHA\", |
| 227 | + \"checksum_type\": \"sha256\" |
| 228 | + }, |
| 229 | + \"_wfpm_ver\": \"$WFPM_VER\" |
| 230 | + } |
| 231 | + " > pkg-release.json |
| 232 | +
|
| 233 | + - name: Upload package release tarball |
| 234 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 235 | + uses: actions/upload-release-asset@v1 |
| 236 | + env: |
| 237 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 238 | + with: |
| 239 | + upload_url: ${{ steps.create_release.outputs.upload_url }} |
| 240 | + asset_path: ./${{ steps.prep_assets.outputs.pkg_tar }} |
| 241 | + asset_name: ${{ steps.prep_assets.outputs.pkg_tar }} |
| 242 | + asset_content_type: application/zip |
| 243 | + |
| 244 | + - name: Upload package release json |
| 245 | + if: ${{ steps.to_release.outputs.release == 'Y' }} |
| 246 | + uses: actions/upload-release-asset@v1 |
| 247 | + env: |
| 248 | + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| 249 | + with: |
| 250 | + upload_url: ${{ steps.create_release.outputs.upload_url }} |
| 251 | + asset_path: ./pkg-release.json |
| 252 | + asset_name: pkg-release.json |
| 253 | + asset_content_type: application/json |
0 commit comments