diff --git a/.github/workflows/reusable-build-workflow.yml b/.github/workflows/reusable-build-workflow.yml index 4fd821a1..5581a092 100644 --- a/.github/workflows/reusable-build-workflow.yml +++ b/.github/workflows/reusable-build-workflow.yml @@ -332,214 +332,214 @@ jobs: path: beta-build-num.zip - # test: - # name: Test SideStore - ${{ inputs.release_tag }} - # needs: serialize - # strategy: - # fail-fast: false - # matrix: - # include: - # - os: 'macos-15' - # version: '16.1' - # runs-on: ${{ matrix.os }} + test: + name: Test SideStore - ${{ inputs.release_tag }} + needs: serialize + strategy: + fail-fast: false + matrix: + include: + - os: 'macos-15' + version: '16.1' + runs-on: ${{ matrix.os }} - # steps: - # - name: Checkout code - # uses: actions/checkout@v4 - # with: - # submodules: recursive + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive - # - name: Boot Simulator for testing - # run: | - # mkdir -p build/logs - # make -B boot-sim-async | tee -a build/logs/test.log - # exit ${PIPESTATUS[0]} + - name: Boot Simulator for testing + run: | + mkdir -p build/logs + make -B boot-sim-async | tee -a build/logs/test.log + exit ${PIPESTATUS[0]} - # - name: Install dependencies - ldid & xcbeautify & xcpretty - # run: | - # brew install ldid xcbeautify - # gem install xcpretty + - name: Install dependencies - ldid & xcbeautify & xcpretty + run: | + brew install ldid xcbeautify + gem install xcpretty - # - name: Setup Xcode - # uses: maxim-lobanov/setup-xcode@v1.6.0 - # with: - # xcode-version: '16.1' + - name: Setup Xcode + uses: maxim-lobanov/setup-xcode@v1.6.0 + with: + xcode-version: '16.1' - # - name: (Test) Cache Build - # uses: irgaly/xcode-cache@v1 - # with: - # key: xcode-cache-deriveddata-test-${{ github.sha }} - # restore-keys: xcode-cache-deriveddata-test- - # swiftpm-cache-key: xcode-cache-sourcedata-test-${{ github.sha }} - # swiftpm-cache-restore-keys: | - # xcode-cache-sourcedata-test- + - name: (Test) Cache Build + uses: irgaly/xcode-cache@v1 + with: + key: xcode-cache-deriveddata-test-${{ github.sha }} + restore-keys: xcode-cache-deriveddata-test- + swiftpm-cache-key: xcode-cache-sourcedata-test-${{ github.sha }} + swiftpm-cache-restore-keys: | + xcode-cache-sourcedata-test- - # - name: (Test) Restore Pods from Cache (Exact match) - # id: pods-restore - # uses: actions/cache/restore@v3 - # with: - # path: | - # ./Podfile.lock - # ./Pods/ - # ./AltStore.xcworkspace/ - # key: pods-cache-test-${{ hashFiles('Podfile') }} + - name: (Test) Restore Pods from Cache (Exact match) + id: pods-restore + uses: actions/cache/restore@v3 + with: + path: | + ./Podfile.lock + ./Pods/ + ./AltStore.xcworkspace/ + key: pods-cache-test-${{ hashFiles('Podfile') }} - # - name: (Test) Restore Pods from Cache (Last Available) - # if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }} - # id: pods-restore-recent - # uses: actions/cache/restore@v3 - # with: - # path: | - # ./Podfile.lock - # ./Pods/ - # ./AltStore.xcworkspace/ - # key: pods-cache-test- + - name: (Test) Restore Pods from Cache (Last Available) + if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }} + id: pods-restore-recent + uses: actions/cache/restore@v3 + with: + path: | + ./Podfile.lock + ./Pods/ + ./AltStore.xcworkspace/ + key: pods-cache-test- - # - name: (Test) Install CocoaPods - # run: pod install + - name: (Test) Install CocoaPods + run: pod install - # - name: (Test) Save Pods to Cache - # if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }} - # uses: actions/cache/save@v3 - # with: - # path: | - # ./Podfile.lock - # ./Pods/ - # ./AltStore.xcworkspace/ - # key: pods-cache-test-${{ hashFiles('Podfile') }} + - name: (Test) Save Pods to Cache + if: ${{ steps.pods-restore.outputs.cache-hit != 'true' }} + uses: actions/cache/save@v3 + with: + path: | + ./Podfile.lock + ./Pods/ + ./AltStore.xcworkspace/ + key: pods-cache-test-${{ hashFiles('Podfile') }} - # - name: (Test) Clean previous build artifacts - # run: | - # make clean - # mkdir -p build/logs + - name: (Test) Clean previous build artifacts + run: | + make clean + mkdir -p build/logs - # - name: (Test) List Files and derived data - # run: | - # echo ">>>>>>>>> Workdir <<<<<<<<<<" - # ls -la . - # echo "" + - name: (Test) List Files and derived data + run: | + echo ">>>>>>>>> Workdir <<<<<<<<<<" + ls -la . + echo "" - # echo ">>>>>>>>> Pods <<<<<<<<<<" - # find Pods -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists - # echo "" + echo ">>>>>>>>> Pods <<<<<<<<<<" + find Pods -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists + echo "" - # echo ">>>>>>>>> SideStore <<<<<<<<<<" - # find SideStore -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists - # echo "" + echo ">>>>>>>>> SideStore <<<<<<<<<<" + find SideStore -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists + echo "" - # echo ">>>>>>>>> Dependencies <<<<<<<<<<" - # find Dependencies -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists - # echo "" + echo ">>>>>>>>> Dependencies <<<<<<<<<<" + find Dependencies -maxdepth 2 -exec ls -ld {} + || true # List contents if directory exists + echo "" - # echo ">>>>>>>>> Xcode-Derived-Data <<<<<<<<<<" - # ls -la ~/Library/Developer/Xcode/DerivedData || true # List contents if directory exists - # echo "" + echo ">>>>>>>>> Xcode-Derived-Data <<<<<<<<<<" + ls -la ~/Library/Developer/Xcode/DerivedData || true # List contents if directory exists + echo "" - # # we expect simulator to have been booted by now, so exit otherwise - # - name: Simulator Boot Check - # run: | - # mkdir -p build/logs - # make -B sim-boot-check | tee -a build/logs/test.log - # exit ${PIPESTATUS[0]} + # we expect simulator to have been booted by now, so exit otherwise + - name: Simulator Boot Check + run: | + mkdir -p build/logs + make -B sim-boot-check | tee -a build/logs/test.log + exit ${PIPESTATUS[0]} - # - name: Start Recording UI tests (if DEBUG_RECORD_TESTS is set to 1) - # if: ${{ vars.DEBUG_RECORD_TESTS == '1' }} - # run: | - # nohup xcrun simctl io booted recordVideo -f test-recording.mp4 --codec h264 test-recording.log 2>&1 & - # RECORD_PID=$! - # echo "RECORD_PID=$RECORD_PID" >> $GITHUB_ENV + - name: Start Recording UI tests (if DEBUG_RECORD_TESTS is set to 1) + if: ${{ vars.DEBUG_RECORD_TESTS == '1' }} + run: | + nohup xcrun simctl io booted recordVideo -f test-recording.mp4 --codec h264 test-recording.log 2>&1 & + RECORD_PID=$! + echo "RECORD_PID=$RECORD_PID" >> $GITHUB_ENV - # # build will be up-to-date from previous step so here only test will be executed directly - # - name: Run SideStore Tests - # # using 'tee' to intercept stdout and log for detailed build-log - # run: | - # NSUnbufferedIO=YES make -B build-and-test 2>&1 | tee -a build/logs/test.log | xcbeautify --renderer github-actions && exit ${PIPESTATUS[0]} - # # NSUnbufferedIO=YES make -B build-and-test 2>&1 | tee build/logs/test.log | xcpretty -r junit --output ./build/tests/test-results.xml && exit ${PIPESTATUS[0]} + # build will be up-to-date from previous step so here only test will be executed directly + - name: Run SideStore Tests + # using 'tee' to intercept stdout and log for detailed build-log + run: | + NSUnbufferedIO=YES make -B build-and-test 2>&1 | tee -a build/logs/test.log | xcbeautify --renderer github-actions && exit ${PIPESTATUS[0]} + # NSUnbufferedIO=YES make -B build-and-test 2>&1 | tee build/logs/test.log | xcpretty -r junit --output ./build/tests/test-results.xml && exit ${PIPESTATUS[0]} - # - name: Stop Recording tests - # if: ${{ always() && env.RECORD_PID != '' }} - # run: | - # kill -INT ${{ env.RECORD_PID }} + - name: Stop Recording tests + if: ${{ always() && env.RECORD_PID != '' }} + run: | + kill -INT ${{ env.RECORD_PID }} - # - name: (Test) List Files and Build artifacts - # if: always() - # run: | - # echo ">>>>>>>>> Workdir <<<<<<<<<<" - # ls -la . - # echo "" + - name: (Test) List Files and Build artifacts + if: always() + run: | + echo ">>>>>>>>> Workdir <<<<<<<<<<" + ls -la . + echo "" - # echo ">>>>>>>>> Build <<<<<<<<<<" - # find build -maxdepth 3 -exec ls -ld {} + || true # List contents if directory exists - # echo "" + echo ">>>>>>>>> Build <<<<<<<<<<" + find build -maxdepth 3 -exec ls -ld {} + || true # List contents if directory exists + echo "" - # - name: Encrypt test-logs for upload - # id: encrypt-test-log - # if: always() - # run: | - # DEFAULT_BUILD_LOG_PASSWORD=12345 + - name: Encrypt test-logs for upload + id: encrypt-test-log + if: always() + run: | + DEFAULT_BUILD_LOG_PASSWORD=12345 - # BUILD_LOG_ZIP_PASSWORD=${{ secrets.BUILD_LOG_ZIP_PASSWORD }} - # BUILD_LOG_ZIP_PASSWORD=${BUILD_LOG_ZIP_PASSWORD:-$DEFAULT_BUILD_LOG_PASSWORD} + BUILD_LOG_ZIP_PASSWORD=${{ secrets.BUILD_LOG_ZIP_PASSWORD }} + BUILD_LOG_ZIP_PASSWORD=${BUILD_LOG_ZIP_PASSWORD:-$DEFAULT_BUILD_LOG_PASSWORD} - # if [ "$BUILD_LOG_ZIP_PASSWORD" == "$DEFAULT_BUILD_LOG_PASSWORD" ]; then - # echo "Warning: BUILD_LOG_ZIP_PASSWORD is not set. Defaulting to '${DEFAULT_BUILD_LOG_PASSWORD}'." - # fi + if [ "$BUILD_LOG_ZIP_PASSWORD" == "$DEFAULT_BUILD_LOG_PASSWORD" ]; then + echo "Warning: BUILD_LOG_ZIP_PASSWORD is not set. Defaulting to '${DEFAULT_BUILD_LOG_PASSWORD}'." + fi - # pushd build/logs && zip -e -P "$BUILD_LOG_ZIP_PASSWORD" ../../encrypted-test-logs.zip * || popd - # echo "::set-output name=encrypted::true" + pushd build/logs && zip -e -P "$BUILD_LOG_ZIP_PASSWORD" ../../encrypted-test-logs.zip * || popd + echo "::set-output name=encrypted::true" - # - name: Upload encrypted-test-logs.zip - # id: attach-encrypted-test-log - # if: always() && steps.encrypt-test-log.outputs.encrypted == 'true' - # uses: actions/upload-artifact@v4 - # with: - # name: encrypted-test-logs-${{ github.sha }}.zip - # path: encrypted-test-logs.zip + - name: Upload encrypted-test-logs.zip + id: attach-encrypted-test-log + if: always() && steps.encrypt-test-log.outputs.encrypted == 'true' + uses: actions/upload-artifact@v4 + with: + name: encrypted-test-logs-${{ github.sha }}.zip + path: encrypted-test-logs.zip - # - name: Print test-recording.log contents (if exists) - # if: ${{ always() && env.RECORD_PID != '' }} - # run: | - # if [ -f test-recording.log ]; then - # echo "test-recording.log found. Its contents:" - # cat test-recording.log - # else - # echo "test-recording.log not found." - # fi + - name: Print test-recording.log contents (if exists) + if: ${{ always() && env.RECORD_PID != '' }} + run: | + if [ -f test-recording.log ]; then + echo "test-recording.log found. Its contents:" + cat test-recording.log + else + echo "test-recording.log not found." + fi - # - name: Check for test-recording.mp4 presence - # id: check-recording - # if: ${{ always() && env.RECORD_PID != '' }} - # run: | - # if [ -f test-recording.mp4 ]; then - # echo "::set-output name=found::true" - # echo "test-recording.mp4 found." - # else - # echo "test-recording.mp4 not found, skipping upload." - # echo "::set-output name=found::false" - # fi + - name: Check for test-recording.mp4 presence + id: check-recording + if: ${{ always() && env.RECORD_PID != '' }} + run: | + if [ -f test-recording.mp4 ]; then + echo "::set-output name=found::true" + echo "test-recording.mp4 found." + else + echo "test-recording.mp4 not found, skipping upload." + echo "::set-output name=found::false" + fi - # - name: Upload test-recording.mp4 - # id: upload-recording - # if: ${{ always() && steps.check-recording.outputs.found == 'true' }} - # uses: actions/upload-artifact@v4 - # with: - # name: test-recording-${GITHUB_SHA:0:7}.mp4 - # path: test-recording.mp4 + - name: Upload test-recording.mp4 + id: upload-recording + if: ${{ always() && steps.check-recording.outputs.found == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: test-recording-${{ needs.serialize.outputs.short-commit }}.mp4 + path: test-recording.mp4 - # - name: Zip test-results - # run: zip -r -9 ./test-results.zip ./build/tests + - name: Zip test-results + run: zip -r -9 ./test-results.zip ./build/tests - # - name: Upload Test Artifacts - # uses: actions/upload-artifact@v4 - # with: - # name: test-results-${GITHUB_SHA:0:7}.zip - # path: test-results.zip + - name: Upload Test Artifacts + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ needs.serialize.outputs.short-commit }}.zip + path: test-results.zip deploy: name: Deploy SideStore - ${{ inputs.release_tag }} runs-on: macos-15 - needs: [serialize, build] - # needs: [serialize, build, test] + # needs: [serialize, build] + needs: [serialize, build, test] steps: - name: Download IPA artifact uses: actions/download-artifact@v4 diff --git a/SideStore/Tests/UITests/UITests.swift b/SideStore/Tests/UITests/UITests.swift index 0fc8aa8d..0cf187fb 100644 --- a/SideStore/Tests/UITests/UITests.swift +++ b/SideStore/Tests/UITests/UITests.swift @@ -379,7 +379,7 @@ private extension UITests { let sourceButton = cellsQuery.otherElements .containing(.button, identifier: source.identifier) .children(matching: .button)[source.identifier] - XCTAssert(sourceButton.exists || sourceButton.waitForExistence(timeout: 5), "Source preview for id: '\(source.alertTitle)' not found in the view") + XCTAssert(sourceButton.exists || sourceButton.waitForExistence(timeout: 10), "Source preview for id: '\(source.alertTitle)' not found in the view") // let addButton = sourceButton.children(matching: .button).firstMatch let addButton = sourceButton.children(matching: .button)["add"] @@ -407,7 +407,7 @@ private extension UITests { ("OatmealDome's AltStore Source\naltstore.oatmealdome.me", "OatmealDome's AltStore Source", true), ("UTM Repository\nVirtual machines for iOS", "UTM Repository", false), ("Flyinghead\nflyinghead.github.io/flycast-builds/altstore.json", "Flyinghead", false), - ("PojavLauncher Repository\nalt.crystall1ne.dev", "PojavLauncher Repository", false), +// ("PojavLauncher Repository\nalt.crystall1ne.dev", "PojavLauncher Repository", false), // not a stable source, sometimes becomes unreachable, so disabled ("PokeMMO\npokemmo.eu/altstore/", "PokeMMO", true), ("Odyssey\ntheodyssey.dev/altstore/odysseysource.json", "Odyssey", false), ("Yattee\nrepos.yattee.stream/alt/apps.json", "Yattee", false),