diff --git a/.github/actions/nix/action.yml b/.github/actions/nix/action.yml new file mode 100644 index 00000000..39f0708d --- /dev/null +++ b/.github/actions/nix/action.yml @@ -0,0 +1,14 @@ +name: Nix +description: Install Nix and restore the store cache + +runs: + using: composite + steps: + - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 + with: + extra_nix_config: experimental-features = nix-command flakes + - uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2 + with: + primary-key: nix-v2-${{ hashFiles('flake.lock', '**/*.nix') }} + restore-prefixes-first-match: nix-v2- + gc-max-store-size-linux: 6G diff --git a/.github/workflows/build-next.yml b/.github/workflows/build-next.yml index 4df3b1f7..c9588d60 100644 --- a/.github/workflows/build-next.yml +++ b/.github/workflows/build-next.yml @@ -9,10 +9,18 @@ permissions: jobs: build: + runs-on: ubuntu-26.04 + timeout-minutes: 60 permissions: contents: read - uses: ./.github/workflows/build.yml - with: - gradle-args: ":app:assembleDebug :app:assembleNext --no-daemon" - artifact-name: subtracks-next - artifact-path: app/build/outputs/apk + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - uses: ./.github/actions/build + with: + gradle-args: ":app:assembleDebug :app:assembleNext --no-daemon" + - uses: actions/upload-artifact@v7 + with: + name: subtracks-next + path: app/build/outputs/apk diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 42d9da82..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Build - -on: - workflow_call: - inputs: - gradle-args: - description: Gradle tasks and flags to run - required: true - type: string - sign: - description: Decode and use the store keystore - required: false - type: boolean - default: false - artifact-name: - description: If set, upload the build outputs as an artifact with this name - required: false - type: string - default: "" - artifact-path: - description: Path uploaded when artifact-name is set - required: false - type: string - default: "" - secrets: - KEYSTORE_BASE64: - required: false - KEYPROPERTIES_BASE64: - required: false - KEYSTORE_PASSWORD: - required: false - KEY_PASSWORD: - required: false - outputs: - version-code: - description: versionCode read from app/build.gradle.kts - value: ${{ jobs.build.outputs.version-code }} - -permissions: - contents: read - -env: - NIX_CONFIG: experimental-features = nix-command flakes - -jobs: - build: - runs-on: ubuntu-26.04 - timeout-minutes: 60 - outputs: - version-code: ${{ steps.version.outputs.code }} - steps: - - uses: actions/checkout@v7 - with: - persist-credentials: false - - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - - uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2 - with: - primary-key: nix-v2-${{ hashFiles('flake.lock', '**/*.nix') }} - restore-prefixes-first-match: nix-v2- - gc-max-store-size-linux: 6G - - uses: actions/cache@v6 - with: - path: ~/.gradle/caches - key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle.properties', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }} - restore-keys: gradle- - - name: Decode signing material - if: inputs.sign - id: signing - env: - KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} - KEYPROPERTIES_BASE64: ${{ secrets.KEYPROPERTIES_BASE64 }} - run: | - echo "$KEYSTORE_BASE64" | base64 -d > "$RUNNER_TEMP/release.keystore" - alias=$(printf '%s' "$KEYPROPERTIES_BASE64" | base64 -d | sed -n 's/^keyAlias=//p' | tr -d '\r') - test -n "$alias" || { echo "no keyAlias in KEYPROPERTIES_BASE64" >&2; exit 1; } - echo "alias=$alias" >> "$GITHUB_OUTPUT" - - name: Build - env: - RELEASE_KEYSTORE: ${{ inputs.sign && format('{0}/release.keystore', runner.temp) || '' }} - RELEASE_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} - RELEASE_KEY_ALIAS: ${{ steps.signing.outputs.alias }} - RELEASE_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} - run: nix develop --command gradle ${{ inputs.gradle-args }} - - name: Remove signing keystore - if: always() - run: rm -f "$RUNNER_TEMP/release.keystore" - - name: Read version code - id: version - run: echo "code=$(grep -oP 'versionCode = \K\d+' app/build.gradle.kts)" >> "$GITHUB_OUTPUT" - - name: Upload build outputs - if: inputs.artifact-name != '' - uses: actions/upload-artifact@v7 - with: - name: ${{ inputs.artifact-name }} - path: ${{ inputs.artifact-path }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9809c6b..fb43d6b5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,36 +10,20 @@ concurrency: cancel-in-progress: true jobs: - build: - permissions: - contents: read - uses: ./.github/workflows/build.yml - with: - gradle-args: ":app:ktlintCheck :app:lintDebug :app:testDebugUnitTest --no-configuration-cache --console=plain --no-daemon" - - integration: + ci: runs-on: ubuntu-26.04 timeout-minutes: 90 permissions: contents: read env: GRADLE_OPTS: -Dorg.gradle.daemon=false - NIX_CONFIG: experimental-features = nix-command flakes steps: - uses: actions/checkout@v7 with: persist-credentials: false - - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - - uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2 + - uses: ./.github/actions/build with: - primary-key: nix-v2-${{ hashFiles('flake.lock', '**/*.nix') }} - restore-prefixes-first-match: nix-v2- - gc-max-store-size-linux: 6G - - uses: actions/cache@v6 - with: - path: ~/.gradle/caches - key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle.properties', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }} - restore-keys: gradle- + gradle-args: ":app:ktlintCheck :app:lintDebug :app:testDebugUnitTest --no-configuration-cache --console=plain --no-daemon" - uses: actions/cache@v6 with: path: .integration/music diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6531aa2b..1fd9adc4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,19 +10,29 @@ permissions: jobs: build: + runs-on: ubuntu-26.04 + timeout-minutes: 60 permissions: contents: read - uses: ./.github/workflows/build.yml - with: - gradle-args: ":app:assembleRelease :app:bundleRelease --no-daemon" - sign: true - artifact-name: release - artifact-path: app/build/outputs - secrets: - KEYSTORE_BASE64: ${{ secrets.SUBTRACKS_KEYSTORE_BASE64 }} - KEYPROPERTIES_BASE64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }} - KEYSTORE_PASSWORD: ${{ secrets.SUBTRACKS_UPLOAD_STORE_PASSWORD }} - KEY_PASSWORD: ${{ secrets.SUBTRACKS_UPLOAD_KEY_PASSWORD }} + outputs: + version-code: ${{ steps.build.outputs.version-code }} + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - id: build + uses: ./.github/actions/build + with: + gradle-args: ":app:assembleRelease :app:bundleRelease --no-daemon" + sign: "true" + keystore-base64: ${{ secrets.SUBTRACKS_KEYSTORE_BASE64 }} + keyproperties-base64: ${{ secrets.SUBTRACKS_KEYPROPERTIES_BASE64 }} + keystore-password: ${{ secrets.SUBTRACKS_UPLOAD_STORE_PASSWORD }} + key-password: ${{ secrets.SUBTRACKS_UPLOAD_KEY_PASSWORD }} + - uses: actions/upload-artifact@v7 + with: + name: release + path: app/build/outputs publish: needs: build @@ -30,8 +40,6 @@ jobs: timeout-minutes: 60 permissions: contents: write - env: - NIX_CONFIG: experimental-features = nix-command flakes steps: - uses: actions/checkout@v7 with: @@ -40,12 +48,7 @@ jobs: with: name: release path: dist - - uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31.11.1 - - uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2 - with: - primary-key: nix-v2-${{ hashFiles('flake.lock', '**/*.nix') }} - restore-prefixes-first-match: nix-v2- - gc-max-store-size-linux: 6G + - uses: ./.github/actions/nix - name: Upload to Google Play env: PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 94ffdd1a..f00b8610 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -87,7 +87,7 @@ android { keyAlias = "androiddebugkey" keyPassword = "android" } - val keystorePath = providers.environmentVariable("RELEASE_KEYSTORE").orNull?.takeIf { it.isNotBlank() } + val keystorePath = providers.environmentVariable("RELEASE_KEYSTORE").orNull if (keystorePath != null) { create("release") { storeFile = file(keystorePath)