Skip to content

Commit c7fbf2c

Browse files
author
David Zuckerman
committed
adding license file
adding license file migrating from gitlab to github removed image to containers in compose, removed tests for usernames adding compose override file for actions need to keep container alive for tests overriding entrypoint to keep container alive for testing mocking test filename for lnbl file for tests syntax error in compose.ci file adding rubocop, also removing rails env for rspec since rails is not used fixed syntax error in build.yml
1 parent eb833db commit c7fbf2c

File tree

10 files changed

+307
-14
lines changed

10 files changed

+307
-14
lines changed

.github/workflows/build.yml

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
name: Build / Test / Push
2+
3+
on:
4+
push:
5+
branches:
6+
- '**'
7+
workflow_dispatch:
8+
9+
env:
10+
BUILD_SUFFIX: -build-${{ github.run_id }}_${{ github.run_attempt }}
11+
DOCKER_METADATA_SET_OUTPUT_ENV: 'true'
12+
13+
jobs:
14+
build:
15+
runs-on: ${{ matrix.runner }}
16+
outputs:
17+
image-arm64: ${{ steps.gen-output.outputs.image-arm64 }}
18+
image-x64: ${{ steps.gen-output.outputs.image-x64 }}
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
runner:
23+
- ubuntu-24.04
24+
- ubuntu-24.04-arm
25+
steps:
26+
- name: Checkout code
27+
uses: actions/checkout@v4
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Login to GitHub Container Registry
33+
uses: docker/login-action@v3
34+
with:
35+
registry: ghcr.io
36+
username: ${{ github.actor }}
37+
password: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- id: build-meta
40+
name: Docker meta
41+
uses: docker/metadata-action@v5
42+
with:
43+
images: ghcr.io/${{ github.repository }}
44+
tags: type=sha,suffix=${{ env.BUILD_SUFFIX }}
45+
46+
# Build cache is shared among all builds of the same architecture
47+
- id: cache-meta
48+
name: Docker meta
49+
uses: docker/metadata-action@v5
50+
with:
51+
images: ghcr.io/${{ github.repository }}
52+
tags: type=raw,value=buildcache-${{ runner.arch }}
53+
54+
- id: get-registry
55+
name: Get the sanitized registry name
56+
run: |
57+
echo "registry=$(echo '${{ steps.build-meta.outputs.tags }}' | cut -f1 -d:)" | tee -a "$GITHUB_OUTPUT"
58+
59+
- id: build
60+
name: Build/push the arch-specific image
61+
uses: docker/build-push-action@v6
62+
with:
63+
cache-from: type=registry,ref=${{ steps.cache-meta.outputs.tags }}
64+
cache-to: type=registry,ref=${{ steps.cache-meta.outputs.tags }},mode=max
65+
labels: ${{ steps.build-meta.outputs.labels }}
66+
provenance: mode=max
67+
sbom: true
68+
tags: ${{ steps.get-registry.outputs.registry }}
69+
outputs: type=image,push-by-digest=true,push=true
70+
71+
- id: gen-output
72+
name: Write arch-specific image digest to outputs
73+
run: |
74+
echo "image-${RUNNER_ARCH,,}=${{ steps.get-registry.outputs.registry }}@${{ steps.build.outputs.digest }}" | tee -a "$GITHUB_OUTPUT"
75+
76+
merge:
77+
runs-on: ubuntu-24.04
78+
needs: build
79+
env:
80+
DOCKER_APP_IMAGE_ARM64: ${{ needs.build.outputs.image-arm64 }}
81+
DOCKER_APP_IMAGE_X64: ${{ needs.build.outputs.image-x64 }}
82+
outputs:
83+
image: ${{ steps.meta.outputs.tags }}
84+
steps:
85+
- name: Checkout code
86+
uses: actions/checkout@v4
87+
88+
- name: Set up Docker Buildx
89+
uses: docker/setup-buildx-action@v3
90+
91+
- name: Login to GitHub Container Registry
92+
uses: docker/login-action@v3
93+
with:
94+
registry: ghcr.io
95+
username: ${{ github.actor }}
96+
password: ${{ secrets.GITHUB_TOKEN }}
97+
98+
- id: meta
99+
name: Generate tag for the app image
100+
uses: docker/metadata-action@v5
101+
with:
102+
images: ghcr.io/${{ github.repository }}
103+
tags: type=sha,suffix=${{ env.BUILD_SUFFIX }}
104+
105+
- name: Push the multi-platform app image
106+
run: |
107+
docker buildx imagetools create \
108+
--tag "$DOCKER_METADATA_OUTPUT_TAGS" \
109+
"$DOCKER_APP_IMAGE_ARM64" "$DOCKER_APP_IMAGE_X64"
110+
111+
test:
112+
runs-on: ubuntu-24.04
113+
needs: merge
114+
env:
115+
COMPOSE_FILE: docker-compose.yml:docker-compose.ci.yml
116+
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.image }}
117+
steps:
118+
- name: Checkout code
119+
uses: actions/checkout@v4
120+
121+
- name: Set up Docker Compose
122+
uses: docker/setup-compose-action@v1
123+
124+
- name: Login to GitHub Container Registry
125+
uses: docker/login-action@v3
126+
with:
127+
registry: ghcr.io
128+
username: ${{ github.actor }}
129+
password: ${{ secrets.GITHUB_TOKEN }}
130+
131+
- name: Setup the stack
132+
run: |
133+
docker compose build --quiet
134+
docker compose pull --quiet
135+
docker compose up --wait
136+
docker compose exec -u root app chown -R alma:alma artifacts
137+
138+
- name: Run RSpec
139+
if: ${{ always() }}
140+
run: |
141+
docker compose exec app rspec --format progress --format html --out artifacts/rspec.html
142+
143+
- name: Run Rubocop
144+
if: ${{ always() }}
145+
run: |
146+
docker compose exec app rubocop --format progress --format html --out artifacts/rubocop.html
147+
148+
- name: Copy out artifacts
149+
if: ${{ always() }}
150+
run: |
151+
docker compose cp app:/opt/app/artifacts ./
152+
docker compose logs > artifacts/docker-compose-services.log
153+
docker compose config > artifacts/docker-compose.merged.yml
154+
155+
- name: Upload the test report
156+
if: ${{ always() }}
157+
uses: actions/upload-artifact@v4
158+
with:
159+
name: SFTP_HANDLER Build Report (${{ github.run_id }}_${{ github.run_attempt }})
160+
path: artifacts/*
161+
if-no-files-found: error
162+
163+
push:
164+
runs-on: ubuntu-24.04
165+
needs:
166+
- merge
167+
# - test
168+
env:
169+
DOCKER_APP_IMAGE: ${{ needs.merge.outputs.image }}
170+
steps:
171+
- name: Checkout code
172+
uses: actions/checkout@v4
173+
174+
- name: Login to GitHub Container Registry
175+
uses: docker/login-action@v3
176+
with:
177+
registry: ghcr.io
178+
username: ${{ github.actor }}
179+
password: ${{ secrets.GITHUB_TOKEN }}
180+
181+
- name: Produce permanent image tags
182+
uses: docker/metadata-action@v5
183+
with:
184+
images: ghcr.io/${{ github.repository }}
185+
tags: |
186+
type=sha
187+
type=ref,event=branch
188+
type=raw,value=latest,enable={{is_default_branch}}
189+
190+
- name: Retag and push the image
191+
run: |
192+
docker pull "$DOCKER_APP_IMAGE"
193+
echo "$DOCKER_METADATA_OUTPUT_TAGS" | tr ' ' '\n' | xargs -n1 docker tag "$DOCKER_APP_IMAGE"
194+
docker push --all-tags "$(echo "$DOCKER_APP_IMAGE" | cut -f1 -d:)"

.github/workflows/release.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Push Release Tags
2+
3+
on:
4+
push:
5+
tags:
6+
- '**'
7+
workflow_dispatch:
8+
9+
env:
10+
DOCKER_METADATA_SET_OUTPUT_ENV: 'true'
11+
12+
jobs:
13+
retag:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v4
18+
19+
- name: Set up Docker Buildx
20+
uses: docker/setup-buildx-action@v3
21+
22+
- name: Login to GitHub Container Registry
23+
uses: docker/login-action@v3
24+
with:
25+
registry: ghcr.io
26+
username: ${{ github.actor }}
27+
password: ${{ secrets.GITHUB_TOKEN }}
28+
29+
- name: Determine the sha-based image tag to retag
30+
id: get-base-image
31+
uses: docker/metadata-action@v5
32+
with:
33+
images: ghcr.io/${{ github.repository }}
34+
tags: type=sha
35+
36+
- name: Verify that the image was previously built
37+
env:
38+
BASE_IMAGE: ${{ steps.get-base-image.outputs.tags }}
39+
run: |
40+
docker pull "$BASE_IMAGE"
41+
42+
- name: Produce release tags
43+
id: tag-meta
44+
uses: docker/metadata-action@v5
45+
with:
46+
images: ghcr.io/${{ github.repository }}
47+
flavor: latest=false
48+
tags: |
49+
type=ref,event=tag
50+
type=semver,pattern={{major}}
51+
type=semver,pattern={{major}}.{{minor}}
52+
type=semver,pattern={{version}}
53+
54+
- name: Retag the pulled image
55+
env:
56+
BASE_IMAGE: ${{ steps.get-base-image.outputs.tags }}
57+
run: |
58+
echo "$DOCKER_METADATA_OUTPUT_TAGS" | tr ' ' '\n' | xargs -n1 docker tag "$BASE_IMAGE"
59+
docker push --all-tags "$(echo "$BASE_IMAGE" | cut -f1 -d:)"

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ GEM
6262
hashdiff (>= 0.4.0, < 2.0.0)
6363

6464
PLATFORMS
65+
aarch64-linux
6566
x86_64-darwin-19
6667
x86_64-linux
6768

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 The Regents of the University of California
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

docker-compose.ci.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
services:
2+
app:
3+
build: !reset
4+
image: ${DOCKER_APP_IMAGE}
5+
environment: !override
6+
LBNL_FILENAME: "test"
7+
entrypoint: ["tail", "-f", "/dev/null"]
8+
volumes: !override
9+
- artifacts:/opt/app/artifacts
10+
11+
volumes:
12+
artifacts:
13+

docker-compose.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ services:
55
target: development
66
environment:
77
LIT_GOBI_PASSWORD: "${LIT_GOBI_PASSWORD}"
8+
LIT_GOBI_USERNAME: "${LIT_GOBI_USERNAME}"
89
LIT_LBNL_KEY_DATA: "${LIT_LBNL_KEY_DATA}"
9-
image: containers.lib.berkeley.edu/lap/sftp_handler/${USER:-development}:latest
10-
init: yes
10+
LIT_LBNL_USERNAME: "${LIT_LBNL_USERNAME}"
11+
LBNL_FILENAME: "${LBNL_FILENAME}"
12+
init: true
1113
volumes:
1214
- ./:/opt/app
13-
14-
version: "3.8"

env.sample

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
LIT_GOBI_PASSWORD='password'
2+
LIT_GOBI_USERNAME='username'
3+
LIT_LBNL_KEY_DATA='ssh key'
4+
LIT_LBNL_USERNAME='username'
5+
LBNL_FILENAME='the base name for the lbnl file'

lib/berkeley_library/sftp_handler/downloader/gobi.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def default_host
4343
end
4444

4545
def default_username
46-
ENV['LIT_GOBI_USERNAME]'
46+
ENV['LIT_GOBI_USERNAME']
4747
end
4848

4949
def ssh_options

lib/berkeley_library/sftp_handler/downloader/lbnl.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
module BerkeleyLibrary
66
module SftpHandler
77
module Downloader
8-
# Downloads the latest lbnl_people_yyyymmdd.zip patron file.
8+
# Downloads the latest ${LBNL_FILENAME}_yyyymmdd.zip patron file.
99
#
1010
# LBNL seems to populate this every Monday, so by default the class looks for the file
1111
# that would've been added on the most recent Monday. If today is Monday, it uses today's
@@ -35,7 +35,7 @@ def default_host
3535
end
3636

3737
def default_username
38-
ENV['LIT_LBNL_USERNAME']
38+
ENV['LIT_LBNL_USERNAME']
3939
end
4040

4141
def default_filename

0 commit comments

Comments
 (0)