Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/FoxxMD/multi-scrobbler. Scrobble plays from multiple sources to multiple clients docs.multi-scrobbler.app
deezer docker jellyfin koito lastfm listenbrainz maloja mopidy mpris music music-assistant plex scrobble self-hosted spotify subsonic tautulli youtube-music
Something went wrong. Try again.
7.0 kB · 183 lines
YAML
at debugDirs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184name: CI
# Runs for every PR (including forks) and for pushes to master/tags.## build installs, tests, builds and runs code from the PR so it must never use secrets or a write token.# PR code is only ever executed inside BuildKit (Dockerfile RUN steps, including the test stage) and the smoke test# container, never directly on the runner. Code running on the runner could use the run's runtime token to# upload or replace the image artifacts that publishing trusts.## publish only runs for trusted code (pushes and PRs from branches in this repository). It does not build or run# anything, it only pushes the image artifacts uploaded by build.
on: pull_request: branches: - 'master' push: branches: - 'master' tags: - '*.*.*' # don't trigger if just updating docs paths-ignore: - 'README.md' - 'flatpak/**' workflow_dispatch:
concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true
permissions: contents: read
jobs: build: name: Test, Build and Smoke Test (${{ matrix.arch }}) runs-on: ${{ matrix.os }} timeout-minutes: 15 strategy: matrix: include: - os: ubuntu-latest arch: amd64 platform: linux/amd64 - os: ubuntu-24.04-arm arch: arm64 platform: linux/arm64 steps: # build the PR's head commit, not the merge commit pull_request checks out by default, # so a published pr-N image is exactly the commit it is labelled with - name: Check out the repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} persist-credentials: false
- name: Get App Version id: appversion # untrusted values (branch names) are only passed through env, never interpolated into the script env: EVENT_NAME: ${{ github.event_name }} REF_TYPE: ${{ github.ref_type }} REF_NAME: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.pull_request.number }} SHA: ${{ github.event.pull_request.head.sha || github.sha }} run: | short="${SHA:0:7}" if [[ "$REF_TYPE" == "tag" ]]; then version="$REF_NAME" elif [[ "$EVENT_NAME" == "pull_request" ]]; then version="pr${PR_NUMBER}-${short}" else version="${REF_NAME}-${short}" fi echo "appversion=$version" >> "$GITHUB_OUTPUT" echo "builddate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 #v3.11.1
# runs `npm run test` inside the Dockerfile's test stage. The dependency and source layers it builds # are reused from the builder's cache by the image build below so they are not built twice - name: Test uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: context: . target: test platforms: ${{ matrix.platform }} outputs: type=cacheonly
# type=docker archives can be loaded with `docker load` for the smoke test and are also an OCI layout # that the publish workflow pushes as-is (digest is preserved) - name: Build image uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: context: . target: app build-args: | APP_BUILD_VERSION=${{ steps.appversion.outputs.appversion }} BUILD_DATE=${{ steps.appversion.outputs.builddate }} platforms: ${{ matrix.platform }} outputs: type=docker,dest=/tmp/images/app.tar,name=multi-scrobbler-ci:app
# debug variant only adds layers on top of the app target so everything else comes from the build cache above - name: Build debug image uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0 with: context: . target: app-debug build-args: | APP_BUILD_VERSION=${{ steps.appversion.outputs.appversion }} BUILD_DATE=${{ steps.appversion.outputs.builddate }} platforms: ${{ matrix.platform }} outputs: type=docker,dest=/tmp/images/app-debug.tar,name=multi-scrobbler-ci:app-debug
- name: Load images run: | docker load -i /tmp/images/app.tar docker load -i /tmp/images/app-debug.tar
# start the image like a user would and wait for it to report healthy - name: Smoke test run: | docker run -d --name ms -p 9078:9078 multi-scrobbler-ci:app healthy=false for i in $(seq 1 60); do if [[ "$(docker inspect -f '{{.State.Running}}' ms)" != "true" ]]; then echo "::error::Container exited before becoming healthy" break fi if curl -fs -o /dev/null http://localhost:9078/api/health; then healthy=true echo "Healthy after ${i}s" break fi sleep 1 done echo "::group::Container logs" docker logs ms echo "::endgroup::" docker rm -f ms > /dev/null if [[ "$healthy" != "true" ]]; then echo "::error::Image did not become healthy" exit 1 fi
- name: Smoke test debug image tools run: docker run --rm --entrypoint sh multi-scrobbler-ci:app-debug -c 'curl --version'
- name: Upload images uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f #7.0.0 with: name: images-linux-${{ matrix.arch }} path: /tmp/images/*.tar # image layers are already compressed compression-level: 0 if-no-files-found: error retention-days: 7
publish: name: Publish needs: - build # fork PRs are published on request by a separate workflow # dependabot PRs are treated like forks (no secrets) even though their branches are in this repository if: >- (vars.DOCKERHUB_SLUG != '' || vars.GHCR_SLUG != '') && (github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]')) permissions: contents: read packages: write actions: read pull-requests: write uses: ./.github/workflows/_publish.yml with: run-id: ${{ github.run_id }} pr-number: ${{ github.event.pull_request.number && format('{0}', github.event.pull_request.number) || '' }} sha: ${{ github.event.pull_request.head.sha || github.sha }} secrets: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}