Skip to content

Commit 9cdd11b

Browse files
committed
updated CI/CD
1 parent a75d62e commit 9cdd11b

File tree

3 files changed

+111
-85
lines changed

3 files changed

+111
-85
lines changed

.github/workflows/ci.yml

Lines changed: 109 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# - on push and PR: run pytest
55
# - on push to main: build and push container images as ":latest"
66
# - on push to semver tag: build and push container image with tag and
7-
# upload plugin description to https://chrisstore.co
7+
# upload plugin description to https://cube.chrisproject.org/api/v1/
88

99
name: build
1010

@@ -19,28 +19,21 @@ on:
1919
jobs:
2020
test:
2121
name: Unit tests
22-
if: false # delete this line to enable automatic testing
22+
if: False
2323
runs-on: ubuntu-22.04
2424
steps:
25-
- uses: actions/checkout@v3
26-
- uses: docker/setup-buildx-action@v2
27-
- name: Cache Docker layers
28-
uses: actions/cache@v2
29-
with:
30-
path: /tmp/.buildx-cache
31-
key: ${{ runner.os }}-buildx-${{ github.sha }}
32-
restore-keys: |
33-
${{ runner.os }}-buildx-
25+
- uses: actions/checkout@v4
26+
- uses: docker/setup-buildx-action@v3
3427
- name: Build
35-
uses: docker/build-push-action@v3
28+
uses: docker/build-push-action@v5
3629
with:
3730
build-args: extras_require=dev
3831
context: .
3932
load: true
4033
push: false
4134
tags: "localhost/local/app:dev"
42-
cache-from: type=local,src=/tmp/.buildx-cache
43-
cache-to: type=local,dest=/tmp/.buildx-cache
35+
cache-from: type=gha
36+
cache-to: type=gha,mode=max
4437
- name: Run pytest
4538
run: |
4639
docker run -v "$GITHUB_WORKSPACE:/app:ro" -w /app localhost/local/app:dev \
@@ -52,105 +45,138 @@ jobs:
5245
# needs: [ test ] # uncomment to require passing tests
5346
runs-on: ubuntu-22.04
5447

55-
# A local registry helps us reuse the built image between steps
56-
services:
57-
registry:
58-
image: registry:2
59-
ports:
60-
- 5000:5000
61-
6248
steps:
63-
- name: Get git tag
64-
id: git_info
65-
if: startsWith(github.ref, 'refs/tags/')
66-
run: echo "::set-output name=tag::${GITHUB_REF##*/}"
67-
- name: Get project info
68-
id: determine
69-
env:
70-
git_tag: ${{ steps.git_info.outputs.tag }}
49+
- name: Decide image tags
50+
id: info
51+
shell: python
7152
run: |
72-
repo="${GITHUB_REPOSITORY,,}" # to lower case
73-
# if build triggered by tag, use tag name
74-
tag="${git_tag:-latest}"
53+
import os
54+
import itertools
7555
76-
# if tag is a version number prefixed by 'v', remove the 'v'
77-
if [[ "$tag" =~ ^v[0-9].* ]]; then
78-
tag="${tag:1}"
79-
fi
56+
def join_tag(t):
57+
registry, repo, tag = t
58+
return f'{registry}/{repo}:{tag}'.lower()
59+
60+
registries = ['docker.io', 'ghcr.io']
61+
repos = ['${{ github.repository }}']
62+
if '${{ github.ref_type }}' == 'branch':
63+
tags = ['latest']
64+
elif '${{ github.ref_type }}' == 'tag':
65+
tag = '${{ github.ref_name }}'
66+
version = tag[1:] if tag.startswith('v') else tag
67+
tags = ['latest', version]
68+
else:
69+
tags = []
70+
71+
if '${{ github.ref_type }}' == 'tag':
72+
local_tag = join_tag(('ghcr.io', '${{ github.repository }}', version))
73+
else:
74+
local_tag = join_tag(('localhost', '${{ github.repository }}', 'latest'))
8075
81-
dock_image=$repo:$tag
82-
echo $dock_image
83-
echo "::set-output name=dock_image::$dock_image"
84-
echo "::set-output name=repo::$repo"
76+
product = itertools.product(registries, repos, tags)
77+
tags_csv = ','.join(map(join_tag, product))
78+
outputs = {
79+
'tags_csv' : tags_csv,
80+
'push' : 'true' if tags_csv else 'false',
81+
'local_tag': local_tag
82+
}
83+
with open(os.environ['GITHUB_OUTPUT'], 'a') as out:
84+
for k, v in outputs.items():
85+
out.write(f'{k}={v}\n')
8586
86-
- uses: actions/checkout@v3
87+
- uses: actions/checkout@v4
8788
# QEMU is used for non-x86_64 builds
88-
- uses: docker/setup-qemu-action@v2
89+
- uses: docker/setup-qemu-action@v3
8990
# buildx adds additional features to docker build
90-
- uses: docker/setup-buildx-action@v2
91+
- uses: docker/setup-buildx-action@v3
9192
with:
9293
driver-opts: network=host
93-
# cache slightly improves rebuild time
94-
- name: Cache Docker layers
95-
uses: actions/cache@v2
94+
95+
# Here, we want to do the docker build twice:
96+
# The first build pushes to our local registry for testing.
97+
# The second build pushes to Docker Hub and ghcr.io
98+
- name: Build (local only)
99+
uses: docker/build-push-action@v3
100+
id: docker_build
96101
with:
97-
path: /tmp/.buildx-cache
98-
key: ${{ runner.os }}-buildx-${{ github.sha }}
99-
restore-keys: |
100-
${{ runner.os }}-buildx-
102+
context: .
103+
file: ./Dockerfile
104+
tags: ${{ steps.info.outputs.local_tag }}
105+
load: true
106+
cache-from: type=gha
107+
# If you have a directory called examples/incoming/ and examples/outgoing/, then
108+
# run your ChRIS plugin with no parameters, and assert that it creates all the files
109+
# which are expected. File contents are not compared.
110+
- name: Run examples
111+
id: run_examples
112+
run: |
113+
if ! [ -d 'examples/incoming/' ] || ! [ -d 'examples/outgoing/' ]; then
114+
echo "No examples."
115+
exit 0
116+
fi
117+
118+
dock_image=${{ steps.info.outputs.local_tag }}
119+
output_dir=$(mktemp -d)
120+
cmd=$(docker image inspect -f '{{ (index .Config.Cmd 0) }}' $dock_image)
121+
docker run --rm -u "$(id -u):$(id -g)" \
122+
-v "$PWD/examples/incoming:/incoming:ro" \
123+
-v "$output_dir:/outgoing:rw" \
124+
$dock_image $cmd /incoming /outgoing
125+
126+
for expected_file in $(find examples/outgoing -type f); do
127+
fname="${expected_file##*/}"
128+
out_path="$output_dir/$fname"
129+
printf "Checking output %s exists..." "$out_path"
130+
if [ -f "$out_path" ]; then
131+
echo "ok"
132+
else
133+
echo "not found"
134+
exit 1
135+
fi
136+
done
101137
102138
- name: Login to DockerHub
103-
id: dockerhub_login
104-
uses: docker/login-action@v2
139+
if: (github.event_name == 'push' || github.event_name == 'release') && contains(steps.info.outputs.tags_csv, 'docker.io')
140+
uses: docker/login-action@v3
105141
with:
106142
username: ${{ secrets.DOCKERHUB_USERNAME }}
107143
password: ${{ secrets.DOCKERHUB_PASSWORD }}
108-
109144
- name: Login to GitHub Container Registry
110-
uses: docker/login-action@v2
145+
if: (github.event_name == 'push' || github.event_name == 'release') && contains(steps.info.outputs.tags_csv, 'ghcr.io')
146+
uses: docker/login-action@v3
111147
with:
112148
registry: ghcr.io
113149
username: ${{ github.repository_owner }}
114150
password: ${{ secrets.GITHUB_TOKEN }}
115-
116151
- name: Build and push
117-
uses: docker/build-push-action@v3
118-
id: docker_build
152+
uses: docker/build-push-action@v5
153+
if: (github.event_name == 'push' || github.event_name == 'release')
119154
with:
120155
context: .
121156
file: ./Dockerfile
122-
tags: |
123-
localhost:5000/${{ steps.determine.outputs.dock_image }}
124-
docker.io/${{ steps.determine.outputs.dock_image }}
125-
ghcr.io/${{ steps.determine.outputs.dock_image }}
157+
tags: ${{ steps.info.outputs.tags_csv }}
126158
# if non-x86_84 architectures are supported, add them here
127159
platforms: linux/amd64 #,linux/arm64,linux/ppc64le
128-
push: true
129-
cache-from: type=local,src=/tmp/.buildx-cache
130-
cache-to: type=local,dest=/tmp/.buildx-cache
160+
push: ${{ steps.info.outputs.push }}
161+
cache-to: type=gha,mode=max
131162

132-
- name: Get plugin meta
133-
id: pluginmeta
134-
run: |
135-
repo=${{ steps.determine.outputs.repo }}
136-
dock_image=${{ steps.determine.outputs.dock_image }}
137-
docker run --rm localhost:5000/$dock_image chris_plugin_info > /tmp/description.json
138-
jq < /tmp/description.json # pretty print in log
139-
echo "::set-output name=title::$(jq -r '.title' < /tmp/description.json)"
163+
- name: Upload ChRIS Plugin
164+
id: upload
165+
if: github.ref_type == 'tag'
166+
uses: FNNDSC/upload-chris-plugin@v1
167+
with:
168+
dock_image: ${{ steps.info.outputs.local_tag }}
169+
username: ${{ secrets.CHRISPROJECT_USERNAME }}
170+
password: ${{ secrets.CHRISPROJECT_PASSWORD }}
171+
chris_url: https://cube.chrisproject.org/api/v1/
172+
compute_names: NERC
140173

141174
- name: Update DockerHub description
142-
uses: peter-evans/dockerhub-description@v2
175+
if: steps.upload.outcome == 'success'
176+
uses: peter-evans/dockerhub-description@v3
143177
continue-on-error: true # it is not crucial that this works
144178
with:
145179
username: ${{ secrets.DOCKERHUB_USERNAME }}
146180
password: ${{ secrets.DOCKERHUB_PASSWORD }}
147-
short-description: ${{ steps.pluginmeta.outputs.title }}
148-
readme-filepath: ./README.md
149-
repository: ${{ steps.determine.outputs.repo }}
150-
151-
- name: Upload to ChRIS Store
152-
if: steps.git_info.outcome != 'skipped'
153-
uses: FNNDSC/chrisstore-action@master
154-
with:
155-
descriptor_file: /tmp/description.json
156-
auth: ${{ secrets.CHRIS_STORE_USER }}
181+
short-description: ${{ steps.upload.outputs.title }}
182+
readme-filepath: ./README.md

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
chris_plugin==0.1.2
1+
chris_plugin>=0.3.0
22
Faker==6.4.1
33
pfdo==5.0.0
44
pfdo-run==3.2.6

shexec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from chris_plugin import chris_plugin, PathMapper
88

99
__pkg = Distribution.from_name(__package__)
10-
__version__ = '1.2.16'
10+
__version__ = '1.2.17'
1111

1212
import os, sys
1313
os.environ['XDG_CONFIG_HOME'] = '/tmp'

0 commit comments

Comments
 (0)