diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b20835f..9f958fb 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -9,11 +9,6 @@ on: schedule: - cron: '0 0 * * 0' # https://crontab.guru/every-week -env: - TEST_APP_DEPS: react-native-modal react-native-webview - TEST_APP_DEV_DEPS: typescript @babel/preset-env react-shallow-renderer - RN_BUNDLE_ARGS: --entry-file index.js --platform android --dev false --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res - jobs: build: runs-on: ubuntu-latest @@ -21,11 +16,32 @@ jobs: - uses: actions/checkout@v4 - run: npm install - run: npm test - test-yarn: + + test: needs: build runs-on: ubuntu-latest outputs: rn-version: ${{ steps.rn-version.outputs.value }} + concurrency: + group: '${{ github.workflow }}-${{ matrix.platform }}-${{ matrix.pm }}-${{ github.head_ref || github.ref_name }}' + cancel-in-progress: true + strategy: + fail-fast: false + max-parallel: 5 + matrix: + os: [ ubuntu-latest ] + platform: [ android ] + pm: [ npm, yarn ] + bundle-args: [ '--bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res' ] + include: + - os: macos-latest + platform: ios + pm: npm + bundle-args: --bundle-output ios/main.jsbundle + - os: macos-latest + platform: ios + pm: yarn + bundle-args: --bundle-output ios/main.jsbundle steps: - uses: actions/checkout@v4 with: @@ -34,85 +50,32 @@ jobs: with: java-version: 17 distribution: adopt - - run: npx react-native init rnexample + - run: | + npm i + npm run example -- --pm ${{ matrix.pm }} + working-directory: react-native-hcaptcha - id: rn-version - working-directory: rnexample + working-directory: react-native-hcaptcha-example run: | RN_VERSION=$(cat package.json | jq ".dependencies.\"react-native\"" -r) echo "value=${RN_VERSION}" >> $GITHUB_OUTPUT - - name: Run yarn add ... - working-directory: rnexample - run: | - yarn add @hcaptcha/react-native-hcaptcha@file:../react-native-hcaptcha - yarn add --dev ${{ env.TEST_APP_DEV_DEPS }} - yarn add ${{ env.TEST_APP_DEPS }} - cp ../react-native-hcaptcha/Example.App.js App.js - cp ../react-native-hcaptcha/Example.jest.config.js jest.config.js - - run: | - mkdir -p android/app/src/main/assets - mkdir -p android/app/src/main/res - yarn react-native bundle ${{ env.RN_BUNDLE_ARGS }} - working-directory: rnexample + - run: yarn react-native bundle --entry-file index.js --platform ${{ matrix.platform }} --dev false ${{ matrix.bundle-args }} + working-directory: react-native-hcaptcha-example - run: cat package.json - working-directory: rnexample + working-directory: react-native-hcaptcha-example - run: yarn test --config ./jest.config.js - working-directory: rnexample + working-directory: react-native-hcaptcha-example - run: npx --yes check-peer-dependencies --yarn --runOnlyOnRootDependencies - working-directory: rnexample - test-npm: - needs: build - runs-on: ubuntu-latest - outputs: - rn-version: ${{ steps.rn-version.outputs.value }} - steps: - - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: adopt - - run: npx react-native init rnexample - - id: rn-version - working-directory: rnexample - run: | - RN_VERSION=$(cat package.json | jq ".dependencies.\"react-native\"" -r) - echo "value=${RN_VERSION}" >> $GITHUB_OUTPUT - - uses: actions/checkout@v4 - with: - path: rnexample/react-native-hcaptcha - - name: Run npm install ... - working-directory: rnexample - run: | - npm i --save file:./react-native-hcaptcha - npm i --save --include=dev ${{ env.TEST_APP_DEV_DEPS }} - npm i --save ${{ env.TEST_APP_DEPS }} - cp ./react-native-hcaptcha/Example.App.js App.js - cp ./react-native-hcaptcha/Example.jest.config.js jest.config.js - - run: | - mkdir -p android/app/src/main/assets - mkdir -p android/app/src/main/res - npx react-native bundle ${{ env.RN_BUNDLE_ARGS }} - working-directory: rnexample - - run: cat package.json - working-directory: rnexample - - run: npm run test -- --config ./jest.config.js - working-directory: rnexample - - run: npx --yes check-peer-dependencies --npm --runOnlyOnRootDependencies - working-directory: rnexample - - run: | - echo "org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m" >> gradle.properties - ./gradlew assemble - working-directory: rnexample/android - - uses: actions/upload-artifact@v4 - with: - name: apks - path: rnexample/android/app/build/outputs/apk/release/app-release.apk + working-directory: react-native-hcaptcha-example + create-an-issue: runs-on: ubuntu-latest - needs: [test-npm, test-yarn] - if: always() && github.event == 'schedule' && (needs.test-npm.result == 'failure' || needs.test-yarn.result == 'failure') + needs: test + if: always() && github.event == 'schedule' && needs.test.result == 'failure' steps: - uses: actions/checkout@v4 - run: | - RN_VERSION="${{ needs.test-npm.outputs.rn-version || needs.test-yarn.outputs.rn-version }}" + RN_VERSION="${{ needs.test.outputs.rn-version }}" GHA_RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" echo "RN_VERSION=${RN_VERSION}" >> $GITHUB_ENV echo "GHA_RUN_URL=${GHA_RUN_URL}" >> $GITHUB_ENV @@ -123,9 +86,10 @@ jobs: assignees: CAMOBAP update_existing: true filename: .github/examples-issue-template.md + release: if: github.event_name == 'release' - needs: [test-npm, test-yarn] + needs: test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/__scripts__/generate-example.js b/__scripts__/generate-example.js index 1c6a8cf..37aa38b 100644 --- a/__scripts__/generate-example.js +++ b/__scripts__/generate-example.js @@ -25,7 +25,7 @@ function parseArgs(args) { cliName: 'react-native', projectName: 'react_native_hcaptcha_example', projectRelativeProjectPath: '../react-native-hcaptcha-example', - packageManager: 'yarn', // npm is broken https://github.com/facebook/react-native/issues/29977 + packageManager: 'yarn', projectTemplate: undefined, frameworkVersion: undefined, }; @@ -37,6 +37,10 @@ function parseArgs(args) { options.projectName = value.replace(/[^a-zA-Z0-9]/g, '_'); options.projectRelativeProjectPath = path.join('..', value); }, + '--path': (value) => { + options.projectRelativeProjectPath = value; + }, + '--pm': (value) => options.packageManager = value, '-h': showHelp, '--help': showHelp }; @@ -82,7 +86,7 @@ function cleanupEnvPathNode() { // Function to build the create command function buildCreateCommand({ cliName, projectRelativeProjectPath, projectName, projectTemplate, packageManager, frameworkVersion }) { - let createCommand = [cliName, 'init', projectName, '--directory', projectRelativeProjectPath]; + let createCommand = ['npm', 'exec', cliName, 'init', projectName, '--directory', projectRelativeProjectPath]; if (projectTemplate) { createCommand.push('--template', projectTemplate); @@ -118,7 +122,7 @@ function checkHcaptchaLinked() { function main({ cliName, projectRelativeProjectPath, projectName, projectTemplate, packageManager, frameworkVersion }) { cleanupEnvPathNode(); - console.warn(`Warning! Example project will be generated in '${path.dirname(__dirname)}' directory`); + console.warn(`Warning! Example project will be generated in '${path.dirname(__dirname)}' directory __dirname=${__dirname}`); // Build the command to initialize the project const createCommand = buildCreateCommand({ cliName, projectRelativeProjectPath, projectName, projectTemplate, packageManager, frameworkVersion }); @@ -134,7 +138,8 @@ function main({ cliName, projectRelativeProjectPath, projectName, projectTemplat fs.readdirSync(projectPath) .filter(file => file.startsWith('App.')) .forEach(file => fs.unlinkSync(path.join(projectPath, file))); - fs.copyFileSync('Example.App.js', `${projectPath}/App.js`); + fs.copyFileSync('Example.App.js', path.join(projectPath, 'App.js')); + fs.copyFileSync('Example.jest.config.js', path.join(projectPath, 'jest.config.js')); // Install dependencies const isHcaptchaLinked = checkHcaptchaLinked(); @@ -147,7 +152,10 @@ function main({ cliName, projectRelativeProjectPath, projectName, projectTemplat execSync(`yarn add ${mainPackagePath}`, packageManagerOptions); execSync(`yarn add ${peerPackages}`, packageManagerOptions); } else { - execSync(`npm i --save ${mainPackagePath}`, packageManagerOptions); + // https://github.com/facebook/react-native/issues/29977 - react-native doesn't work with symlinks so `cp` instead + // fs.symlinkSync(mainPackagePath, path.join(projectPath, 'react-native-hcaptcha'), 'dir'); + execSync(`cp -r ${mainPackagePath} ${projectPath}`); + execSync(`npm i --save ./react-native-hcaptcha`, packageManagerOptions); execSync(`npm i --save ${peerPackages}`, packageManagerOptions); } @@ -162,6 +170,8 @@ function main({ cliName, projectRelativeProjectPath, projectName, projectTemplat execSync('bundle exec pod install', podOptions); } + // ['assets', 'res'].map(dir => fs.mkdirSync(path.join(projectPath, 'android/app/src/main', dir))); + console.log('Setup complete.'); } diff --git a/package.json b/package.json index 9171d3e..b6e59d4 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "jest", - "example": "node __scripts__/generate-example.js --name react-native-hcaptcha-example" + "example": "node __scripts__/generate-example.js" }, "jest": { "preset": "react-native", @@ -61,4 +61,4 @@ "babel-jest": "^27.2.2", "metro-react-native-babel-preset": "^0.77.0" } -} +} \ No newline at end of file