Lint + build update and retooling #8771
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| - master | |
| pull_request: | |
| release: | |
| types: [ published ] | |
| concurrency: | |
| group: ${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| COMPILER_IMAGE: ghcr.io/feederbox826/stash-compiler | |
| jobs: | |
| # Job 1: Generate code and build UI | |
| # Runs natively (no Docker) — go generate/gqlgen and node don't need cross-compilers. | |
| # Produces artifacts (generated Go files + UI build) consumed by test and build jobs. | |
| generate: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Go | |
| uses: actions/setup-go@v6 | |
| # pnpm version is read from the packageManager field in package.json | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| package_json_file: ui/v2.5/package.json | |
| # https://github.com/pnpm/action-setup/issues/201 | |
| cache: true | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| cache: 'pnpm' | |
| cache-dependency-path: ui/v2.5/pnpm-lock.yaml | |
| - name: Install UI dependencies | |
| run: cd ui/v2.5 && pnpm install --frozen-lockfile | |
| - name: Generate | |
| run: make generate | |
| - name: Cache UI build | |
| uses: actions/cache@v5 | |
| id: cache-ui | |
| with: | |
| path: ui/v2.5/build | |
| key: ${{ runner.os }}-ui-build-${{ hashFiles('ui/v2.5/pnpm-lock.yaml', 'ui/v2.5/public/**', 'ui/v2.5/src/**', 'graphql/**/*.graphql') }} | |
| - name: Validate UI | |
| # skip UI validation for pull requests if UI is unchanged | |
| if: ${{ github.event_name != 'pull_request' || steps.cache-ui.outputs.cache-hit != 'true' }} | |
| run: make validate-ui | |
| - name: Build UI | |
| # skip UI build for pull requests if UI is unchanged (UI was cached) | |
| if: ${{ github.event_name != 'pull_request' || steps.cache-ui.outputs.cache-hit != 'true' }} | |
| run: make ui | |
| # Bundle generated Go files + UI build for downstream jobs (test + build) | |
| - name: Upload generated artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: generated | |
| retention-days: 1 | |
| path: | | |
| internal/api/generated_exec.go | |
| internal/api/generated_models.go | |
| ui/v2.5/build/ | |
| ui/login/locales/ | |
| # Job 2: Integration tests | |
| # Runs natively (no Docker) — only needs Go + GCC (for CGO/SQLite), both on ubuntu-22.04. | |
| # Runs in parallel with the build matrix jobs. | |
| test: | |
| needs: generate | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: 'go.mod' | |
| # Places generated Go files + UI build into the working tree so the build compiles | |
| - name: Download generated artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: generated | |
| - name: Test Backend | |
| run: make it | |
| # Job 3: Cross-compile for all platforms | |
| # Each platform gets its own runner and Docker container (stashapp/compiler:12). | |
| # Each build-cc-* make target is self-contained (sets its own GOOS/GOARCH/CC), | |
| # so running them in separate containers is functionally identical to one container. | |
| # Runs in parallel with the test job. | |
| build: | |
| needs: generate | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: windows | |
| make-target: build-cc-windows | |
| artifact-paths: | | |
| dist/stash-win.exe | |
| tag: win | |
| - platform: macos | |
| make-target: build-cc-macos | |
| artifact-paths: | | |
| dist/stash-macos | |
| dist/Stash.app.zip | |
| tag: osx | |
| - platform: linux | |
| make-target: build-cc-linux | |
| artifact-paths: | | |
| dist/stash-linux | |
| tag: linux | |
| - platform: linux-arm64v8 | |
| make-target: build-cc-linux-arm64v8 | |
| artifact-paths: | | |
| dist/stash-linux-arm64v8 | |
| tag: arm | |
| - platform: linux-arm32v7 | |
| make-target: build-cc-linux-arm32v7 | |
| artifact-paths: | | |
| dist/stash-linux-arm32v7 | |
| tag: arm | |
| - platform: linux-arm32v6 | |
| make-target: build-cc-linux-arm32v6 | |
| artifact-paths: | | |
| dist/stash-linux-arm32v6 | |
| tag: arm | |
| - platform: freebsd | |
| make-target: build-cc-freebsd | |
| artifact-paths: | | |
| dist/stash-freebsd | |
| tag: freebsd | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 1 | |
| fetch-tags: true | |
| - name: Download generated artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: generated | |
| - name: Cache Go build | |
| uses: actions/cache@v5 | |
| with: | |
| path: .go-cache | |
| key: ${{ runner.os }}-go-cache-${{ matrix.platform }}-${{ hashFiles('go.mod', '**/go.sum') }} | |
| # kept seperate to test timings | |
| - name: pull compiler image | |
| run: docker pull $COMPILER_IMAGE | |
| - name: Start build container | |
| env: | |
| official-build: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/develop') || (github.event_name == 'release' && github.ref != 'refs/tags/latest_develop') }} | |
| run: | | |
| mkdir -p .go-cache | |
| docker run -d --name build --mount type=bind,source="$(pwd)",target=/stash,consistency=delegated --mount type=bind,source="$(pwd)/.go-cache",target=/root/.cache/go-build,consistency=delegated --env OFFICIAL_BUILD=${{ env.official-build }} -w /stash $COMPILER_IMAGE tail -f /dev/null | |
| - name: Build (${{ matrix.platform }}) | |
| run: docker exec -t build /bin/bash -c "make ${{ matrix.make-target }}" | |
| - name: Cleanup build container | |
| run: docker rm -f -v build | |
| - name: Upload build artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: build-${{ matrix.platform }} | |
| retention-days: 1 | |
| path: ${{ matrix.artifact-paths }} | |
| # Job 4: Release | |
| # Waits for both test and build to pass, then collects all platform artifacts | |
| # into dist/ for checksums, GitHub releases, and multi-arch Docker push. | |
| release: | |
| needs: [test, build] | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| fetch-tags: true | |
| # Downloads all artifacts (generated + 7 platform builds) into artifacts/ subdirectories | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: artifacts | |
| # Reassemble platform binaries from matrix job artifacts into a single dist/ directory | |
| # upload-artifact@v4 strips the common path prefix (dist/), so files are at the artifact root | |
| - name: Collect binaries | |
| run: | | |
| mkdir -p dist | |
| cp artifacts/build-*/* dist/ | |
| - name: Zip UI | |
| run: | | |
| cd artifacts/generated/ui/v2.5/build && zip -r ../../../../../dist/stash-ui.zip . | |
| - name: Generate checksums | |
| run: | | |
| git describe --tags --exclude latest_develop | tee CHECKSUMS_SHA1 | |
| sha1sum dist/Stash.app.zip dist/stash-* dist/stash-ui.zip | sed 's/dist\///g' | tee -a CHECKSUMS_SHA1 | |
| echo "STASH_VERSION=$(git describe --tags --exclude latest_develop)" >> $GITHUB_ENV | |
| echo "RELEASE_DATE=$(date +'%Y-%m-%d %H:%M:%S %Z')" >> $GITHUB_ENV | |
| - name: Upload Windows binary | |
| # only upload binaries for pull requests not targeting develop or master | |
| if: ${{ github.event_name == 'pull_request' && github.base_ref != 'refs/heads/develop' && github.base_ref != 'refs/heads/master'}} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stash-win.exe | |
| path: dist/stash-win.exe | |
| - name: Upload macOS binary | |
| # only upload binaries for pull requests not targeting develop or master | |
| if: ${{ github.event_name == 'pull_request' && github.base_ref != 'refs/heads/develop' && github.base_ref != 'refs/heads/master'}} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stash-macos | |
| path: dist/stash-macos | |
| - name: Upload Linux binary | |
| # only upload binaries for pull requests not targeting develop or master | |
| if: ${{ github.event_name == 'pull_request' && github.base_ref != 'refs/heads/develop' && github.base_ref != 'refs/heads/master'}} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stash-linux | |
| path: dist/stash-linux | |
| - name: Upload UI | |
| # only upload for pull requests not targeting develop or master | |
| if: ${{ github.event_name == 'pull_request' && github.base_ref != 'refs/heads/develop' && github.base_ref != 'refs/heads/master'}} | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: stash-ui.zip | |
| path: dist/stash-ui.zip | |
| - name: Update latest_develop tag | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }} | |
| run: git tag -f latest_develop; git push -f --tags | |
| - name: Development Release | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' }} | |
| uses: marvinpinto/action-automatic-releases@v1.1.2 | |
| with: | |
| repo_token: "${{ secrets.GITHUB_TOKEN }}" | |
| prerelease: true | |
| automatic_release_tag: latest_develop | |
| title: "${{ env.STASH_VERSION }}: Latest development build" | |
| files: | | |
| dist/Stash.app.zip | |
| dist/stash-macos | |
| dist/stash-win.exe | |
| dist/stash-linux | |
| dist/stash-linux-arm64v8 | |
| dist/stash-linux-arm32v7 | |
| dist/stash-linux-arm32v6 | |
| dist/stash-freebsd | |
| dist/stash-ui.zip | |
| CHECKSUMS_SHA1 | |
| - name: Master release | |
| # NOTE: this isn't perfect, but should cover most scenarios | |
| # DON'T create tag names starting with "v" if they are not stable releases | |
| if: ${{ github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v') }} | |
| uses: WithoutPants/github-release@v2.0.4 | |
| with: | |
| token: "${{ secrets.GITHUB_TOKEN }}" | |
| allow_override: true | |
| files: | | |
| dist/Stash.app.zip | |
| dist/stash-macos | |
| dist/stash-win.exe | |
| dist/stash-linux | |
| dist/stash-linux-arm64v8 | |
| dist/stash-linux-arm32v7 | |
| dist/stash-linux-arm32v6 | |
| dist/stash-freebsd | |
| dist/stash-ui.zip | |
| CHECKSUMS_SHA1 | |
| gzip: false | |
| - name: Development Docker | |
| if: ${{ github.repository == 'stashapp/stash' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }} | |
| env: | |
| DOCKER_CLI_EXPERIMENTAL: enabled | |
| DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | |
| DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} | |
| run: | | |
| docker run --rm --privileged tonistiigi/binfmt | |
| docker info | |
| docker buildx create --name builder --use | |
| docker buildx inspect --bootstrap | |
| docker buildx ls | |
| bash ./docker/ci/x86_64/docker_push.sh development | |
| - name: Release Docker | |
| # NOTE: this isn't perfect, but should cover most scenarios | |
| # DON'T create tag names starting with "v" if they are not stable releases | |
| if: ${{ github.repository == 'stashapp/stash' && github.event_name == 'release' && startsWith(github.ref, 'refs/tags/v') }} | |
| env: | |
| DOCKER_CLI_EXPERIMENTAL: enabled | |
| DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} | |
| DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} | |
| run: | | |
| docker run --rm --privileged tonistiigi/binfmt | |
| docker info | |
| docker buildx create --name builder --use | |
| docker buildx inspect --bootstrap | |
| docker buildx ls | |
| bash ./docker/ci/x86_64/docker_push.sh latest "${{ github.event.release.tag_name }}" |