diff --git a/.github/actions/find-artifact/action.yml b/.github/actions/find-artifact/action.yml index 5169038..178a7cb 100644 --- a/.github/actions/find-artifact/action.yml +++ b/.github/actions/find-artifact/action.yml @@ -20,10 +20,26 @@ inputs: outputs: artifact-id: description: 'The ID of the artifact' + value: ${{ steps.find-artifact.outputs.artifact-id }} artifact-url: description: 'The URL of the artifact' + value: ${{ steps.find-artifact.outputs.artifact-url }} artifact-ids: description: 'All IDs of the artifacts matching the name' + value: ${{ steps.find-artifact.outputs.artifact-ids }} runs: - using: 'node20' - main: 'index.js' + using: 'composite' + steps: + - name: Install dependencies + run: npm install + shell: bash + working-directory: ${{ github.action_path }} + - name: Find artifact + id: find-artifact + env: + INPUT_NAME: ${{ inputs.name }} + INPUT_RE_SIGN: ${{ inputs.re-sign }} + INPUT_GITHUB_TOKEN: ${{ inputs.github-token }} + INPUT_REPOSITORY: ${{ inputs.repository }} + run: node ${{ github.action_path }}/index.mjs + shell: bash diff --git a/.github/actions/find-artifact/index.js b/.github/actions/find-artifact/index.mjs similarity index 68% rename from .github/actions/find-artifact/index.js rename to .github/actions/find-artifact/index.mjs index 331c5ff..84bb9cc 100644 --- a/.github/actions/find-artifact/index.js +++ b/.github/actions/find-artifact/index.mjs @@ -1,5 +1,5 @@ -const core = require('@actions/core'); -const github = require('@actions/github'); +import * as core from "@actions/core"; +import * as github from "@actions/github"; const perPage = 100; // Maximum allowed by GitHub API @@ -9,8 +9,8 @@ async function fetchArtifacts(octokit, repository, name) { while (true) { const response = await octokit.rest.actions.listArtifactsForRepo({ - owner: repository.split('/')[0], - repo: repository.split('/')[1], + owner: repository.split("/")[0], + repo: repository.split("/")[1], name, per_page: perPage, page, @@ -31,7 +31,7 @@ async function fetchArtifacts(octokit, repository, name) { } function getPrNumber() { - if (github.context.eventName === 'pull_request') { + if (github.context.eventName === "pull_request") { return github.context.payload.pull_request.number; } return undefined; @@ -39,10 +39,23 @@ function getPrNumber() { async function run() { try { - const token = core.getInput('github-token'); - const repository = core.getInput('repository'); - const name = core.getInput('name'); - const reSign = core.getInput('re-sign'); + const token = core.getInput("github_token") || process.env.GITHUB_TOKEN; + + if (!token) { + throw new Error("GitHub token is required"); + } + + const repository = core.getInput("repository"); + if (!repository) { + throw new Error("Repository is required"); + } + + const name = core.getInput("name"); + if (!name) { + throw new Error("Artifact name is required"); + } + + const reSign = core.getInput("re_sign"); const prNumber = getPrNumber(); const octokit = github.getOctokit(token); @@ -61,20 +74,20 @@ async function run() { for (const artifact of artifacts) { console.log( `- ID: ${artifact.id}, Name: ${artifact.name}, Size: ${formatSize( - artifact.size_in_bytes, - )}, Expires at: ${artifact.expires_at}`, + artifact.size_in_bytes + )}, Expires at: ${artifact.expires_at}` ); } - const firstArtifact = artifacts.find(artifact => !artifact.expired); + const firstArtifact = artifacts.find((artifact) => !artifact.expired); console.log(`First artifact: ${JSON.stringify(firstArtifact, null, 2)}`); const url = formatDownloadUrl( repository, firstArtifact.workflow_run.id, - firstArtifact.id, + firstArtifact.id ); - console.log('Stable download URL:', url); + console.log("Stable download URL:", url); let artifactName = name; // There are artifacts from PR but the base artifact is gone, recreate with the original name @@ -84,12 +97,12 @@ async function run() { } else if (prNumber && reSign) { artifactName = `${name}-${prNumber}`; } - core.setOutput('artifact-name', artifactName); - core.setOutput('artifact-id', firstArtifact.id); - core.setOutput('artifact-url', url); + core.setOutput("artifact-name", artifactName); + core.setOutput("artifact-id", firstArtifact.id); + core.setOutput("artifact-url", url); core.setOutput( - 'artifact-ids', - artifactsByPrNumber.map(artifact => artifact.id).join(' '), + "artifact-ids", + artifactsByPrNumber.map((artifact) => artifact.id).join(" ") ); } catch (error) { core.setFailed(`Action failed with error: ${error.message}`); diff --git a/.github/actions/find-artifact/package.json b/.github/actions/find-artifact/package.json index 1818861..d1e86da 100644 --- a/.github/actions/find-artifact/package.json +++ b/.github/actions/find-artifact/package.json @@ -7,4 +7,4 @@ "@actions/core": "^1.11.1", "@actions/github": "^6.0.0" } -} \ No newline at end of file +} diff --git a/.github/actions/rnef-native-fingerprint/action.yml b/.github/actions/rnef-native-fingerprint/action.yml index 4c8f39a..aec7103 100644 --- a/.github/actions/rnef-native-fingerprint/action.yml +++ b/.github/actions/rnef-native-fingerprint/action.yml @@ -11,6 +11,18 @@ inputs: outputs: hash: description: 'The fingerprint hash' + value: ${{ steps.fingerprint.outputs.hash }} runs: - using: 'node20' - main: 'index.mjs' \ No newline at end of file + using: 'composite' + steps: + - name: Install dependencies + run: npm install + shell: bash + working-directory: ${{ github.action_path }} + - name: Run fingerprint + id: fingerprint + env: + INPUT_PLATFORM: ${{ inputs.platform }} + INPUT_WORKING_DIRECTORY: ${{ inputs.working-directory }} + run: node ${{ github.action_path }}/index.mjs + shell: bash diff --git a/.github/actions/rnef-native-fingerprint/index.mjs b/.github/actions/rnef-native-fingerprint/index.mjs index 486e4ef..40e9ac0 100644 --- a/.github/actions/rnef-native-fingerprint/index.mjs +++ b/.github/actions/rnef-native-fingerprint/index.mjs @@ -1,13 +1,13 @@ -import path from 'node:path'; -import core from '@actions/core'; -import {getConfig} from '@rnef/config'; -import {nativeFingerprint} from '@rnef/tools'; +import path from "node:path"; +import core from "@actions/core"; +import { getConfig } from "@rnef/config"; +import { nativeFingerprint } from "@rnef/tools"; -const ALLOWED_PLATFORMS = ['android', 'ios']; +const ALLOWED_PLATFORMS = ["android", "ios"]; async function run() { - const platform = core.getInput('platform'); - const workingDirectory = core.getInput('working-directory'); + const platform = core.getInput("platform"); + const workingDirectory = core.getInput("working-directory"); if (!ALLOWED_PLATFORMS.includes(platform)) { throw new Error(`Invalid platform: ${platform}`); } @@ -22,10 +22,10 @@ async function run() { ...fingerprintOptions, }); - console.log('Hash:', fingerprint.hash); - console.log('Sources:', fingerprint.sources); + console.log("Hash:", fingerprint.hash); + console.log("Sources:", fingerprint.sources); - core.setOutput('hash', fingerprint.hash); + core.setOutput("hash", fingerprint.hash); } await run(); diff --git a/.github/actions/rnef-native-fingerprint/package.json b/.github/actions/rnef-native-fingerprint/package.json index 4be30e9..7946ad9 100644 --- a/.github/actions/rnef-native-fingerprint/package.json +++ b/.github/actions/rnef-native-fingerprint/package.json @@ -2,8 +2,9 @@ "name": "rnef-native-fingerprint", "version": "1.0.0", "description": "Generate native fingerprint for RNEF builds", - "main": "index.js", + "main": "index.mjs", "dependencies": { + "@rnef/config": "^0.4.1", "@actions/core": "^1.11.1" } -} \ No newline at end of file +} diff --git a/.github/actions/rnef-post-build/action.yml b/.github/actions/rnef-post-build/action.yml index 3f6d766..f01bf35 100644 --- a/.github/actions/rnef-post-build/action.yml +++ b/.github/actions/rnef-post-build/action.yml @@ -1,5 +1,5 @@ name: 'Post Build' -description: 'Post Build info' +description: 'Post build comment for RNEF builds' inputs: artifact-url: @@ -10,8 +10,19 @@ inputs: required: true github-token: description: A GitHub Personal Access Token with write access to the project - required: false - default: ${{ github.token }} + required: true runs: - using: 'node20' - main: 'index.js' + using: 'composite' + steps: + - name: Install dependencies + run: npm install + shell: bash + working-directory: ${{ github.action_path }} + - name: Post build + id: post-build + env: + INPUT_ARTIFACT_URL: ${{ inputs.artifact-url }} + INPUT_TITLE: ${{ inputs.title }} + INPUT_GITHUB_TOKEN: ${{ inputs.github-token }} + run: node ${{ github.action_path }}/index.mjs + shell: bash diff --git a/.github/actions/rnef-post-build/index.js b/.github/actions/rnef-post-build/index.mjs similarity index 52% rename from .github/actions/rnef-post-build/index.js rename to .github/actions/rnef-post-build/index.mjs index e268efe..8ee83fa 100644 --- a/.github/actions/rnef-post-build/index.js +++ b/.github/actions/rnef-post-build/index.mjs @@ -1,10 +1,21 @@ -const core = require('@actions/core'); -const github = require('@actions/github'); +import core from "@actions/core"; +import github from "@actions/github"; async function run() { - const token = core.getInput('github-token'); - const titleInput = core.getInput('title'); - const artifactUrl = core.getInput('artifact-url'); + const token = core.getInput("github_token") || process.env.GITHUB_TOKEN; + if (!token) { + throw new Error("GitHub token is required"); + } + + const titleInput = core.getInput("title"); + if (!titleInput) { + throw new Error("Title is required"); + } + + const artifactUrl = core.getInput("artifact_url"); + if (!artifactUrl) { + throw new Error("Artifact URL is required"); + } const title = `## ${titleInput}`; const body = `🔗 [Download link](${artifactUrl}).\n\n @@ -12,15 +23,15 @@ Note: if the download link expires, please re-run the workflow to generate a new *Generated at ${new Date().toISOString()} UTC*\n`; const octokit = github.getOctokit(token); - const {data: comments} = await octokit.rest.issues.listComments({ + const { data: comments } = await octokit.rest.issues.listComments({ ...github.context.repo, issue_number: github.context.issue.number, }); const botComment = comments.find( - comment => - comment.user.login === 'github-actions[bot]' && - comment.body.includes(title), + (comment) => + comment.user.login === "github-actions[bot]" && + comment.body.includes(title) ); if (botComment) { @@ -29,14 +40,14 @@ Note: if the download link expires, please re-run the workflow to generate a new comment_id: botComment.id, body: `${title}\n\n${body}`, }); - console.log('Updated comment'); + console.log("Updated comment"); } else { await octokit.rest.issues.createComment({ ...github.context.repo, issue_number: github.context.issue.number, body: `${title}\n\n${body}`, }); - console.log('Created comment'); + console.log("Created comment"); } } diff --git a/.github/actions/rnef-post-build/package.json b/.github/actions/rnef-post-build/package.json index b77f415..994d93f 100644 --- a/.github/actions/rnef-post-build/package.json +++ b/.github/actions/rnef-post-build/package.json @@ -7,4 +7,4 @@ "@actions/core": "^1.11.1", "@actions/github": "^6.0.0" } -} \ No newline at end of file +} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 9e448df..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Test - -on: - push: - branches: [main] - pull_request: - branches: ['**'] - -jobs: - build-simulator: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - cache: 'npm' - - - name: Install dependencies - run: npm install diff --git a/README.md b/README.md index eda71dd..364939d 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ jobs: destination: 'simulator' # or 'device' scheme: 'YourScheme' configuration: 'Debug' + github-token: ${{ secrets.GITHUB_TOKEN }} # For device builds, add these: # certificate-base64: ${{ secrets.CERTIFICATE_BASE64 }} # certificate-password: ${{ secrets.CERTIFICATE_PASSWORD }} @@ -45,7 +46,7 @@ jobs: | Input | Description | Required | Default | | ----------------------------- | ------------------------------------------ | -------- | --------------------- | -| `github-token` | GitHub Token | No | `${{ github.token }}` | +| `github-token` | GitHub Token | Yes | - | | `working-directory` | Working directory for the build command | No | `.` | | `destination` | Build destination: "simulator" or "device" | Yes | `simulator` | | `scheme` | Xcode scheme | Yes | - | diff --git a/action.yml b/action.yml index a9aaf85..c030c83 100644 --- a/action.yml +++ b/action.yml @@ -8,8 +8,7 @@ branding: inputs: github-token: description: GitHub Token - required: false - default: ${{ github.token }} + required: true working-directory: description: 'Working directory for the build command' required: false @@ -61,6 +60,10 @@ outputs: runs: using: 'composite' steps: + - name: Install dependencies + run: npm install + shell: bash + - name: Validate inputs run: | if [ "${{ inputs.destination }}" != "simulator" ] && [ "${{ inputs.destination }}" != "device" ]; then @@ -114,6 +117,7 @@ runs: with: name: ${{ env.ARTIFACT_NAME }} re-sign: ${{ inputs.re-sign }} + github-token: ${{ inputs.github-token }} - name: Set Provisioning Profile Path run: | @@ -256,3 +260,4 @@ runs: with: title: iOS ${{ inputs.configuration }} ${{ inputs.destination == 'simulator' && 'APP for simulators' || 'IPA for physical devices' }} artifact-url: ${{ steps.upload-artifact.outputs.artifact-url || steps.find-artifact.outputs.artifact-url }} + github-token: ${{ inputs.github-token }} diff --git a/package.json b/package.json index 65f562c..ea20439 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "action-ios", "version": "1.0.0", - "description": "GitHub Action for building iOS applications using RNEF (React Native EAS Fastlane)", + "description": "GitHub Action for building iOS applications using RNEF (React Native Enterprise Framework)", "main": "index.js", "author": "", "license": "MIT",