diff --git a/.github/workflows/auth-react-test-1.yml b/.github/workflows/auth-react-test-1.yml new file mode 100644 index 00000000..e80f3d8f --- /dev/null +++ b/.github/workflows/auth-react-test-1.yml @@ -0,0 +1,138 @@ +name: Auth-React Tests - L1 + +on: + pull_request: + types: + - opened + - reopened + - synchronize + push: + tags: + - dev-v[0-9]+.[0-9]+.[0-9]+ + +# Only one instance of this workflow will run on the same ref (PR/Branch/Tag) +# Previous runs will be cancelled. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + define-versions: + runs-on: ubuntu-latest + outputs: + fdiVersions: ${{ steps.versions.outputs.fdiVersions }} + webJsInterfaceVersion: ${{ steps.versions.outputs.webJsInterfaceVersion }} + steps: + - uses: actions/checkout@v4 + + - uses: supertokens/get-supported-versions-action@main + id: versions + with: + has-fdi: true + has-web-js: true + + setup-auth-react: + runs-on: ubuntu-latest + needs: define-versions + strategy: + fail-fast: true + matrix: + fdi-version: ${{ fromJSON(needs.define-versions.outputs.fdiVersions) }} + + outputs: + AUTH_REACT__LOG_DIR: ${{ steps.envs.outputs.AUTH_REACT__LOG_DIR }} + AUTH_REACT__SCREENSHOT_DIR: ${{ steps.envs.outputs.AUTH_REACT__SCREENSHOT_DIR }} + AUTH_REACT__NODE_PORT: ${{ steps.envs.outputs.AUTH_REACT__NODE_PORT }} + AUTH_REACT__APP_SERVER: ${{ steps.envs.outputs.AUTH_REACT__NODE_PORT }} + AUTH_REACT__TEST_MODE: ${{ steps.envs.outputs.AUTH_REACT__TEST_MODE }} + AUTH_REACT__PORT: ${{ steps.envs.outputs.AUTH_REACT__PORT }} + specs: ${{ steps.envs.outputs.specs }} + fdiVersions: ${{ needs.define-versions.outputs.fdiVersions }} + + steps: + - uses: actions/checkout@v4 + with: + path: supertokens-web-js + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - uses: supertokens/get-versions-action@main + id: versions + with: + driver-name: node + fdi-version: ${{ matrix.fdi-version }} + fetch-frontend-versions: false + web-js-interface-version: ${{ needs.define-versions.outputs.webJsInterfaceVersion }} + env: + SUPERTOKENS_API_KEY: ${{ secrets.SUPERTOKENS_API_KEY }} + + - uses: supertokens/auth-react-testing-action/setup@main + id: envs + with: + auth-react-version: ${{ steps.versions.outputs.webJsReactVersionXy }} + node-sdk-version: ${{ steps.versions.outputs.nodeTag }} + fdi-version: ${{ matrix.fdi-version }} + use-common-app-and-test-server: "true" + persist-workspace: "false" + + # We will use this in the test run to get the core version + - uses: actions/checkout@v4 + with: + repository: supertokens/supertokens-node + ref: ${{ steps.versions.outputs.nodeTag }} + path: supertokens-node + + - name: Copy over required dependencies + run: | + cd supertokens-web-js + # Create a tarball of the web-js package + npm pack + + cd ../supertokens-auth-react + # Extract the tarball to the auth-react package + tar -xf ../supertokens-web-js/supertokens-web-js-*.tgz --strip-components=1 -C node_modules/supertokens-web-js + # # Remove existing website package and link to the one from web-js + # rm -rf node_modules/supertokens-website + # ln -s "../supertokens-web-js/node_modules/supertokens-website" node_modules + + - name: Set up auth-react with new dependencies + working-directory: supertokens-auth-react/examples/for-tests + env: + # Common + APP_SERVER: ${{ steps.envs.outputs.AUTH_REACT__APP_SERVER }} + NODE_PORT: ${{ steps.envs.outputs.AUTH_REACT__NODE_PORT }} + TEST_MODE: ${{ steps.envs.outputs.AUTH_REACT__TEST_MODE }} + # Step-specific + CI: true + BROWSER: none + PORT: ${{ steps.envs.outputs.AUTH_REACT__PORT }} + REACT_APP_API_PORT: ${{ steps.envs.outputs.AUTH_REACT__APP_SERVER }} + run: | + npm run prep + + - uses: bissolli/gh-action-persist-workspace@v2 + with: + action: persist + artifactName: auth-react-${{ matrix.fdi-version }} + + launch-test-workflow: + uses: ./.github/workflows/auth-react-test-2.yml + needs: setup-auth-react + name: FDI ${{ matrix.fdi-version }} + strategy: + max-parallel: 1 # This is important to avoid ddos GHA API + fail-fast: false # Don't fail fast to avoid locking TF State + matrix: + fdi-version: ${{ fromJSON(needs.setup-auth-react.outputs.fdiVersions) }} + with: + fdi-version: ${{ matrix.fdi-version }} + specs: ${{ needs.setup-auth-react.outputs.specs }} + AUTH_REACT__LOG_DIR: ${{ needs.setup-auth-react.outputs.AUTH_REACT__LOG_DIR }} + AUTH_REACT__SCREENSHOT_DIR: ${{ needs.setup-auth-react.outputs.AUTH_REACT__SCREENSHOT_DIR }} + AUTH_REACT__APP_SERVER: ${{ needs.setup-auth-react.outputs.AUTH_REACT__APP_SERVER }} + AUTH_REACT__NODE_PORT: ${{ needs.setup-auth-react.outputs.AUTH_REACT__NODE_PORT }} + AUTH_REACT__TEST_MODE: ${{ needs.setup-auth-react.outputs.AUTH_REACT__TEST_MODE }} + AUTH_REACT__PORT: ${{ needs.setup-auth-react.outputs.AUTH_REACT__PORT }} + secrets: inherit diff --git a/.github/workflows/auth-react-test-2.yml b/.github/workflows/auth-react-test-2.yml new file mode 100644 index 00000000..45688601 --- /dev/null +++ b/.github/workflows/auth-react-test-2.yml @@ -0,0 +1,119 @@ +name: Auth-React Tests - L2 +on: + workflow_call: + inputs: + fdi-version: + description: "FDI Version" + required: true + type: string + + specs: + description: "Spec Files" + required: true + type: string + + AUTH_REACT__LOG_DIR: + description: AUTH_REACT__LOG_DIR + required: true + type: string + + AUTH_REACT__SCREENSHOT_DIR: + description: AUTH_REACT__SCREENSHOT_DIR + required: true + type: string + + AUTH_REACT__APP_SERVER: + description: AUTH_REACT__APP_SERVER + required: true + type: string + + AUTH_REACT__NODE_PORT: + description: AUTH_REACT__NODE_PORT + required: true + type: string + + AUTH_REACT__TEST_MODE: + description: AUTH_REACT__TEST_MODE + required: true + type: string + + AUTH_REACT__PORT: + description: AUTH_REACT__PORT + required: true + type: string + +jobs: + test: + runs-on: ubuntu-latest + + strategy: + max-parallel: 10 + fail-fast: false + matrix: + spec: ${{ fromJSON(inputs.specs) }} + + env: + SUPERTOKENS_CORE_PORT: 3567 + SUPERTOKENS_CORE_HOST: localhost + TEST_MODE: testing + # Auth react setup envs + AUTH_REACT__LOG_DIR: ${{ inputs.AUTH_REACT__LOG_DIR }} + AUTH_REACT__SCREENSHOT_DIR: ${{ inputs.AUTH_REACT__SCREENSHOT_DIR }} + AUTH_REACT__NODE_PORT: ${{ inputs.AUTH_REACT__NODE_PORT }} + AUTH_REACT__APP_SERVER: ${{ inputs.AUTH_REACT__NODE_PORT }} + AUTH_REACT__TEST_MODE: ${{ inputs.AUTH_REACT__TEST_MODE }} + AUTH_REACT__PORT: ${{ inputs.AUTH_REACT__PORT }} + SUPERTOKENS_API_KEY: ${{ secrets.SUPERTOKENS_API_KEY }} + + steps: + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - uses: bissolli/gh-action-persist-workspace@v2 + with: + action: retrieve + artifactName: auth-react-${{ inputs.fdi-version }} + + - name: Get Node CDI versions + id: node-cdi-versions + uses: supertokens/get-supported-versions-action@main + with: + has-cdi: true + working-directory: supertokens-node + + - uses: supertokens/get-versions-action@main + id: versions + with: + driver-name: node + fdi-version: ${{ inputs.fdi-version }} + + - name: Get last Node CDI version + id: last-node-cdi-version + run: | + export lastVersion=$(echo '${{ steps.node-cdi-versions.outputs.cdiVersions }}' | jq -r '.[-1]') + echo "lastNodeCdiVersion=$lastVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + - name: Get Core version + id: core-version + uses: supertokens/get-versions-action@main + with: + driver-name: node + cdi-version: ${{ steps.last-node-cdi-version.outputs.lastNodeCdiVersion }} + env: + SUPERTOKENS_API_KEY: ${{ secrets.SUPERTOKENS_API_KEY }} + + - name: Start core + run: docker compose up --wait + working-directory: supertokens-web-js + env: + SUPERTOKENS_CORE_VERSION: ${{ steps.core-version.outputs.coreVersionXy }} + + - uses: supertokens/auth-react-testing-action@main + name: test ${{ matrix.spec }} for ${{ inputs.fdi-version }} + with: + fdi-version: ${{ inputs.fdi-version }} + check-name-suffix: "[FDI=${{ inputs.fdi-version }}][Spec=${{ matrix.spec }}]" + path: supertokens-auth-react + spec: ${{ matrix.spec }} + retrieve-workspace: "false" diff --git a/.github/workflows/pipeline-dev-tag.yml b/.github/workflows/pipeline-dev-tag.yml new file mode 100644 index 00000000..825d810b --- /dev/null +++ b/.github/workflows/pipeline-dev-tag.yml @@ -0,0 +1,153 @@ +name: "Dev Tag Pipeline" + +on: + workflow_dispatch: + inputs: + branch: + description: The branch to create the dev tag on + type: string + required: true + +permissions: + contents: write + +jobs: + setup: + runs-on: ubuntu-latest + + outputs: + packageVersion: ${{ steps.versions.outputs.packageVersion }} + packageVersionXy: ${{ steps.versions.outputs.packageVersionXy }} + packageLockVersion: ${{ steps.versions.outputs.packageLockVersion }} + packageLockVersionXy: ${{ steps.versions.outputs.packageLockVersionXy }} + newestVersion: ${{ steps.versions.outputs.newestVersion }} + targetBranch: ${{ steps.versions.outputs.targetBranch }} + devTag: ${{ steps.versions.outputs.devTag }} + releaseTag: ${{ steps.versions.outputs.releaseTag }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + # Need a complete fetch to make the master merge check work + fetch-depth: 0 + fetch-tags: true + token: ${{ secrets.ALL_REPO_PAT }} + + - name: Setup git + run: | + # NOTE: The user email is {user.id}+{user.login}@users.noreply.github.com. + # See users API: https://api.github.com/users/github-actions%5Bbot%5D + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git fetch origin master + + - name: Check if branch needs master merge + run: | + if [[ $(git log origin/master ^HEAD) != "" ]]; then + echo "You need to merge master into this branch." + exit 1 + fi + + - name: Populate variables + id: versions + run: | + . ./hooks/populate-hook-constants.sh + + echo "packageVersion=$packageVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageVersionXy=$packageVersionXy" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageLockVersion=$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageLockVersionXy=$packageLockVersionXy" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "newestVersion=$newestVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "targetBranch=$targetBranch" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + echo "devTag=dev-v$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "releaseTag=v$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + - name: Check tag and branch correctness + run: | + if [[ "${{ steps.versions.outputs.packageVersion }}" != "${{ steps.versions.outputs.packageLockVersion }}" ]] + then + echo "The package version and package lock version do not match." + exit 1 + fi + + if [[ "${{ steps.versions.outputs.packageVersion }}" != ${{ inputs.branch }}* ]] + then + echo "Adding tag to wrong branch" + exit 1 + fi + + if git rev-parse ${{ steps.versions.outputs.releaseTag }} >/dev/null 2>&1 + then + echo "The released version of this tag already exists." + exit 1 + fi + + - name: Delete tag if already tagged + run: | + git tag --delete ${{ steps.versions.outputs.devTag }} || true + git push --delete origin ${{ steps.versions.outputs.devTag }} || true + + - name: Install dependencies + run: npm install + + - name: Build docs + run: | + npm run build-pretty + npm run build-docs + + - name: Commit doc changes + run: | + git add --all + git commit --allow-empty -nm "doc: update docs for ${{ steps.versions.outputs.releaseTag }} tag" + git push + + - name: Create and push tag + run: | + # NOTE: The user email is {user.id}+{user.login}@users.noreply.github.com. + # See users API: https://api.github.com/users/github-actions%5Bbot%5D + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git tag ${{ steps.versions.outputs.devTag }} + git push --tags --follow-tags + + mark-dev-tag-as-not-passed: + runs-on: ubuntu-latest + needs: + - setup + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.setup.outputs.devTag }} + fetch-tags: true + + - id: versions + uses: supertokens/get-supported-versions-action@main + with: + has-cdi: false + has-fdi: true + has-web-js: true + + - id: escape-versions + run: | + echo "fdiVersions=$(sed 's/"/\\"/g' <<< '${{ steps.versions.outputs.fdiVersions }}')" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "webJsInterfaceVersion=$(sed 's/"/\\"/g' <<< '${{ steps.versions.outputs.webJsInterfaceVersion }}')" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + - run: | + ./hooks/populate-hook-constants.sh + + curl --fail-with-body -X PUT \ + https://api.supertokens.io/0/frontend \ + -H 'Content-Type: application/json' \ + -H 'api-version: 1' \ + -d "{ + \"password\": \"${{ secrets.SUPERTOKENS_API_KEY }}\", + \"version\":\"${{ needs.setup.outputs.packageVersion }}\", + \"name\": \"web-js\", + \"frontendDriverInterfaces\": ${{ steps.escape-versions.outputs.fdiVersions }}, + \"webJsInterface\": \"${{ steps.escape-versions.outputs.webJsInterfaceVersion }}\" + }" diff --git a/.github/workflows/pipeline-release-tag.yml b/.github/workflows/pipeline-release-tag.yml new file mode 100644 index 00000000..6cb1fed0 --- /dev/null +++ b/.github/workflows/pipeline-release-tag.yml @@ -0,0 +1,410 @@ +name: "Release Pipeline" + +on: + workflow_dispatch: + inputs: + branch: + description: The branch to create the release tag on + type: string + required: true + + skip-test-checks: + description: Skip tests passed checks + type: boolean + default: false + required: false + + skip-other-version-checks: + description: Skip server checks for core and frontend versions + type: boolean + default: false + required: false + +permissions: + contents: write + +jobs: + setup: + runs-on: ubuntu-latest + + outputs: + packageVersion: ${{ steps.versions.outputs.packageVersion }} + packageVersionXy: ${{ steps.versions.outputs.packageVersionXy }} + packageLockVersion: ${{ steps.versions.outputs.packageLockVersion }} + packageLockVersionXy: ${{ steps.versions.outputs.packageLockVersionXy }} + newestVersion: ${{ steps.versions.outputs.newestVersion }} + targetBranch: ${{ steps.versions.outputs.targetBranch }} + devTag: ${{ steps.versions.outputs.devTag }} + releaseTag: ${{ steps.versions.outputs.releaseTag }} + targetFolder: ${{ steps.versions.outputs.targetFolder }} + versionFolder: ${{ steps.versions.outputs.versionFolder }} + artifactName: ${{ steps.versions.outputs.artifactName }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + fetch-tags: true + token: ${{ secrets.ALL_REPO_PAT }} + + - name: Populate variables + id: versions + run: | + . ./hooks/populate-hook-constants.sh + + echo "packageVersion=$packageVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageVersionXy=$packageVersionXy" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageLockVersion=$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "packageLockVersionXy=$packageLockVersionXy" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "newestVersion=$newestVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "targetBranch=$targetBranch" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + echo "devTag=dev-v$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "releaseTag=v$packageLockVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + echo "targetFolder=app/docs/sdk/docs/web-js" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "versionFolder=$packageVersionXy.X" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + echo "artifactName=web-js-docs-$packageVersion" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + mark-as-success: + runs-on: ubuntu-latest + + needs: + - setup + + steps: + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install dependencies + run: | + pip install httpx + + - if: ${{ inputs.skip-test-checks == 'false' || inputs.skip-test-checks == false }} + name: Get commit status + run: | + python3 -c "$(cat << EOF + + from collections import defaultdict + import httpx + import sys + + check_runs_url = "https://api.github.com/repos/${{ github.repository }}/commits/tags/${{ needs.setup.outputs.devTag }}/check-runs?per_page=100&page={page}" + jobs_url="https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/jobs" + + current_jobs_response = httpx.get(jobs_url).json() + current_job_ids = [job["id"] for job in current_jobs_response["jobs"]] + + page = 1 + total = 0 + + status_map = defaultdict(int) + conclusion_map = defaultdict(int) + failures = [] + + while True: + response = httpx.get(check_runs_url.format(page=page)).json() + + if len(response["check_runs"]) == 0: + break + + for run_info in response["check_runs"]: + # Release pipeline jobs also show up in check-runs + # We skip them from the checks to avoid pipeline failures + if run_info["id"] in current_job_ids: + continue + + if run_info["conclusion"] == "failure": + failures.append(run_info["html_url"]) + + status_map[run_info["status"]] += 1 + conclusion_map[run_info["conclusion"]] += 1 + total += 1 + + page += 1 + + print(f"{page=}") + print(f"{total=}") + print("Status Map =", dict(status_map)) + print("Conclusion Map =", dict(conclusion_map)) + print() + + # Possible values (from docs): + # [completed, action_required, cancelled, failure, neutral, skipped, stale, success, + # timed_out, in_progress, queued, requested, waiting, pending] + if status_map["completed"] < total: + print("Some checks not completed.") + print(failures) + sys.exit(1) + + # Possible values (from testing): + # None, success, skipped, failure + if conclusion_map.get("failure", 0) > 0: + print("Some checks not successful.") + print(failures) + sys.exit(1) + + EOF + )" + + - run: | + curl --fail-with-body -X PATCH \ + https://api.supertokens.io/0/frontend \ + -H 'Content-Type: application/json' \ + -H 'api-version: 0' \ + -d "{ + \"password\": \"${{ secrets.SUPERTOKENS_API_KEY }}\", + \"version\":\"${{ needs.setup.outputs.packageVersion }}\", + \"name\": \"web-js\", + \"testPassed\": true + }" + + release: + runs-on: ubuntu-latest + + # This job marks the version as a release version and creates tags. + # Binding this to the publish env to require approvals before run. + # Further jobs are follow-ups to the release and are not required to be approved once release is approved. + environment: publish + + needs: + - setup + - mark-as-success + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + fetch-tags: true + token: ${{ secrets.ALL_REPO_PAT }} + + - name: Setup git + run: | + # NOTE: The user email is {user.id}+{user.login}@users.noreply.github.com. + # See users API: https://api.github.com/users/github-actions%5Bbot%5D + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Check tests passed + run: | + testsPassed=`curl -s -X GET "https://api.supertokens.io/0/frontend?password=${{ secrets.SUPERTOKENS_API_KEY }}&version=${{ needs.setup.outputs.packageVersion }}&name=web-js" -H 'api-version: 0'` + + if [[ $(echo $testsPassed | jq .testPassed) != "true" ]] + then + echo "All tests have not passed. Exiting." + exit 1 + fi + + # - if: ${{ inputs.skip-other-version-checks == 'false' || inputs.skip-other-version-checks == false }} + # name: Check if core and frontend released + # run: | + # canReleaseSafelyResponse=`curl -s -X GET "https://api.supertokens.io/0/frontend/release/check?password=${{ secrets.SUPERTOKENS_API_KEY }}&version=${{ needs.setup.outputs.packageVersion }}&name=web-js" -H 'api-version: 0'` + + # if [[ $(echo $canReleaseSafelyResponse | jq .canRelease) != "true" ]] + # then + # echo "Cannot release. Have you released corresponding core and frontend?" + # exit 1 + # fi + + - name: Check if current commit is dev-tagged + run: | + currentCommit=$(git log --format="%H" -n 1) + currentTag=`git tag -l --points-at $currentCommit` + expectedTag="${{ needs.setup.outputs.devTag }}" + + if [[ "$currentTag" != "$expectedTag" ]] + then + echo "Commit does not have the correct dev tag for this release" + echo "Current: $currentTag" + echo "Expected: $expectedTag" + exit 1 + fi + + - name: Mark for release + run: | + curl --fail-with-body -X PATCH \ + https://api.supertokens.io/0/frontend \ + -H 'Content-Type: application/json' \ + -H 'api-version: 0' \ + -d "{ + \"password\": \"${{ secrets.SUPERTOKENS_RELEASE_API_KEY }}\", + \"name\":\"web-js\", + \"version\":\"${{ needs.setup.outputs.packageVersion }}\", + \"release\": true + }" + + - name: Create release tag, delete dev tag + run: | + # Add new release tag + git tag ${{ needs.setup.outputs.releaseTag }} + git push --tags + + # Delete current dev tag + git tag --delete ${{ needs.setup.outputs.devTag }} + git push --delete origin ${{ needs.setup.outputs.devTag }} + + - name: Create JSON payload + run: | + # Initialize an empty JSON object string + jsonPayload="{\"password\": \"$releasePassword\"" + # Iterate through all files in the ./bundle directory + for file in ./bundle/*; do + # Extract the filename without the path + filename=$(basename "$file") + + # Extract the name part (before the first dot) + name="${filename%%.*}" + + # Add the key-value pair to the JSON object string + if [ -n "$jsonPayload" ] && [ "$jsonPayload" != "{" ]; then + jsonPayload+="," + fi + jsonPayload+="\"$name\":\"https://cdn.jsdelivr.net/gh/supertokens/supertokens-web-js@v${{ needs.setup.outputs.packageVersion }}/bundle/$filename\"" + done + # Close the JSON object + jsonPayload+="}" + + curl --fail-with-body -X PUT \ + https://api.supertokens.io/0/frontend/web-js \ + -H 'Content-Type: application/json' \ + -H 'api-version: 0' \ + -d "${jsonPayload}" + + merge: + runs-on: ubuntu-latest + needs: + - setup + - release + + outputs: + isLatest: ${{ steps.merge-check.outputs.isLatest }} + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + # Need a complete fetch to make the master merge work + fetch-depth: 0 + fetch-tags: true + token: ${{ secrets.ALL_REPO_PAT }} + + - name: Setup git + run: | + # NOTE: The user email is {user.id}+{user.login}@users.noreply.github.com. + # See users API: https://api.github.com/users/github-actions%5Bbot%5D + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + - name: Check API and merge to master + id: merge-check + run: | + response=`curl -s -X GET "https://api.supertokens.io/0/frontend/latest/check?password=${{ secrets.SUPERTOKENS_API_KEY }}&version=${{ needs.setup.outputs.packageVersion }}&name=web-js" -H 'api-version: 0'` + isLatest=$(echo $response | jq .isLatest) + + echo "isLatest=$isLatest" | tee -a "$GITHUB_OUTPUT" "$GITHUB_ENV" + + if [[ $isLatest == "true" ]] + then + git checkout master + git checkout ${{ inputs.branch }} + + git merge master + git checkout master + git merge ${{ inputs.branch }} + git push + git checkout ${{ inputs.branch }} + fi + + publish-docs: + runs-on: ubuntu-latest + needs: + - setup + - release + - merge + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.setup.outputs.releaseTag }} + fetch-tags: true + path: supertokens-web-js + + - uses: actions/checkout@v4 + with: + repository: supertokens/supertokens-backend-website + token: ${{ secrets.ALL_REPO_PAT }} + path: supertokens-backend-website + + - run: | + shopt -s extglob # Enable extended globbing + + if [[ "${{ needs.merge.outputs.isLatest }}" == "true" ]] + then + # Delete everything except the version folders + rm -rf supertokens-backend-website/${{ needs.setup.outputs.targetFolder }}/!(*.*.X) + # Copy files to the root dir + cp -r supertokens-web-js/docs/* supertokens-backend-website/${{ needs.setup.outputs.targetFolder }}/ + fi + + # Delete the current version folder if it exists + rm -rf supertokens-backend-website/${{ needs.setup.outputs.targetFolder }}/${{ needs.setup.outputs.versionFolder }} + # Copy the current docs + mkdir -p supertokens-backend-website/${{ needs.setup.outputs.targetFolder }}/${{ needs.setup.outputs.versionFolder }} + cp -r supertokens-web-js/docs/* supertokens-backend-website/${{ needs.setup.outputs.targetFolder }}/${{ needs.setup.outputs.versionFolder }} + + - uses: actions/upload-artifact@v4 + with: + name: ${{ needs.setup.outputs.artifactName }} + path: supertokens-backend-website/${{ needs.setup.outputs.targetFolder }} + + - name: Trigger the backend website CI + uses: actions/github-script@v7 + with: + # NOTE: We should use a better scoped PAT here. + github-token: ${{ secrets.ALL_REPO_PAT }} + script: | + github.rest.actions.createWorkflowDispatch({ + owner: 'supertokens', + repo: 'supertokens-backend-website', + workflow_id: 'release-sdk-documentation-changes.yml', + ref: 'master', + inputs: { + "sdk-name": "web-js", + "sdk-repo": "supertokens/supertokens-web-js", + "version": `${{ needs.setup.outputs.packageVersion }}`, + "artifact-name": `${{ needs.setup.outputs.artifactName }}`, + "target-folder": `${{ needs.setup.outputs.targetFolder }}`, + "run-id": `${{ github.run_id }}`, + "stage": "production", + } + }) + + publish: + runs-on: ubuntu-latest + environment: publish + needs: + - setup + - release + - merge + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ needs.setup.outputs.releaseTag }} + fetch-tags: true + + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org/" + + - run: | + if [[ "${{ needs.merge.outputs.isLatest }}" == "true" ]] + then + npm publish --tag latest + else + npm publish --tag version-${{ needs.setup.outputs.packageVersion }} + fi + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/tests-pass-check-pr.yml b/.github/workflows/tests-pass-check-pr.yml deleted file mode 100644 index cfa2cbae..00000000 --- a/.github/workflows/tests-pass-check-pr.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: 'Check if "Run tests" action succeeded' - -on: - pull_request: - types: - - opened - - reopened - - edited - - synchronize - -jobs: - pr-run-test-action: - name: Check if "Run tests" action succeeded - timeout-minutes: 60 - concurrency: - group: ${{ github.head_ref }} - cancel-in-progress: true - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: node install - run: cd ./.github/helpers && npm i - - name: Calling github API - run: cd ./.github/helpers && GITHUB_TOKEN=${{ github.token }} REPO=${{ github.repository }} RUN_ID=${{ github.run_id }} BRANCH=${{ github.head_ref }} JOB_ID=${{ github.job }} SOURCE_OWNER=${{ github.event.pull_request.head.repo.owner.login }} CURRENT_SHA=${{ github.event.pull_request.head.sha }} node node_modules/github-workflow-helpers/test-pass-check-pr.js diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index cbf9cec4..00000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: "Run tests" -on: - workflow_dispatch: - inputs: - authReactOwnerName: - description: "supertokens-auth-react owner name" - default: supertokens - required: true - authReactBranchName: - description: "supertokens-auth-react repo branch name" - default: master - required: true - pluginInterfaceRepoOwnerName: - description: "supertokens-plugin-interface repo owner name" - default: supertokens - required: true - pluginInterfaceBranchName: - description: "supertokens-plugin-interface repos branch name" - default: master - required: true - coreRepoOwnerName: - description: "supertokens-core repo owner name" - default: supertokens - required: true - coreBranchName: - description: "supertokens-core repo branch name" - default: master - required: true - nodeRepoOwnerName: - description: "supertokens-node repo owner name" - default: supertokens - required: true - nodeBranchName: - description: "supertokens-node repo branch name" - default: master - required: true -jobs: - test_job: - name: Run tests - timeout-minutes: 120 - runs-on: ubuntu-latest - container: rishabhpoddar/supertokens_website_sdk_testing_node_16 - steps: - - name: Environment variables - run: | - echo "React Owner: ${{ github.event.inputs.authReactOwnerName }}" - echo "React Branch: ${{ github.event.inputs.authReactBranchName }}" - echo "Plugin Interface Owner: ${{ github.event.inputs.pluginInterfaceRepoOwnerName }}" - echo "Plugin Interface Branch: ${{ github.event.inputs.pluginInterfaceBranchName }}" - echo "Core Owner: ${{ github.event.inputs.coreRepoOwnerName }}" - echo "Core Branch: ${{ github.event.inputs.coreBranchName }}" - echo "Node Owner: ${{ github.event.inputs.nodeRepoOwnerName }}" - echo "Node Branch: ${{ github.event.inputs.nodeBranchName }}" - - name: Make git use https instead of ssh - run: git config --global url."https://github.com/".insteadOf ssh://git@github.com/ - - uses: actions/checkout@v2 - with: - persist-credentials: false - - run: npm i || true - - run: chown -R 1001:121 "/github/home/.npm" - - run: npm i --force - - name: Cloning supertokens-root - run: cd ../ && git clone https://github.com/supertokens/supertokens-root.git - - name: Update Java 1 - run: update-alternatives --install "/usr/bin/java" "java" "/usr/java/jdk-15.0.1/bin/java" 2 - - name: Update Java 2 - run: update-alternatives --install "/usr/bin/javac" "javac" "/usr/java/jdk-15.0.1/bin/javac" 2 - - name: Modifying modules.txt in supertokens-root - run: cd ../supertokens-root && echo "core,${{ github.event.inputs.coreBranchName }},${{ github.event.inputs.coreRepoOwnerName }}\nplugin-interface,${{ github.event.inputs.pluginInterfaceBranchName }},${{ github.event.inputs.pluginInterfaceRepoOwnerName }}" > modules.txt - - name: Contents of modules.txt - run: cat ../supertokens-root/modules.txt - - name: Running loadModules in supertokens-root - run: cd ../supertokens-root && ./loadModules - - name: Setup supertokens-auth-react - run: cd ../ && git clone https://github.com/${{ github.event.inputs.authReactOwnerName }}/supertokens-auth-react && cd supertokens-auth-react && git checkout ${{ github.event.inputs.authReactBranchName }} && chown -R 1001:121 "/github/home/.npm" && npm run init - - name: Installing supertokens-node - run: cd ../supertokens-auth-react/test/server/ && npm i -d --force && npm i --force github:${{ github.event.inputs.nodeRepoOwnerName }}/supertokens-node#${{ github.event.inputs.nodeBranchName }} - - name: Replacing Auth0 credentials in .env.js - run: sed -i 's/AUTH0_EMAIL = "bradparishdoh@gmail.com"/AUTH0_EMAIL = "${{ secrets.AUTH0_EMAIL }}"/g' ../supertokens-auth-react/test/.env.js && sed -i 's/AUTH0_PASSWORD = "ow93jduDSje00asd"/AUTH0_PASSWORD = "${{ secrets.AUTH0_PASSWORD }}"/g' ../supertokens-auth-react/test/.env.js - - name: Prepare dependencies - run: npm pack && cd ../supertokens-auth-react && tar -xf ../supertokens-web-js/supertokens-web-js-*.tgz --strip-components=1 -C node_modules/supertokens-web-js && rm -rf node_modules/supertokens-website && ln -s "$PWD/../supertokens-web-js/node_modules/supertokens-website" node_modules - - name: Setting up supertokens-root test environment - run: cd ../supertokens-root && bash ./utils/setupTestEnv --local - - name: Run tests - run: cd ../supertokens-auth-react && npm run test diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 00000000..7d368177 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,28 @@ +name: Web JS Unit Tests + +on: + pull_request: + types: + - opened + - reopened + - synchronize + push: + tags: + - dev-v[0-9]+.[0-9]+.[0-9]+ + +# Only one instance of this workflow will run on the same ref (PR/Branch/Tag) +# Previous runs will be cancelled. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20 + - run: npm install + - run: npm run test diff --git a/compose.yml b/compose.yml new file mode 100644 index 00000000..9d01cf43 --- /dev/null +++ b/compose.yml @@ -0,0 +1,23 @@ +services: + core: + # Uses `$SUPERTOKENS_CORE_VERSION` when available, else latest + image: supertokens/supertokens-core:dev-branch-${SUPERTOKENS_CORE_VERSION:-master} + ports: + # Uses `$SUPERTOKENS_CORE_PORT` when available, else 3567 for local port + - ${SUPERTOKENS_CORE_PORT:-3567}:3567 + platform: linux/amd64 + depends_on: [oauth] + environment: + OAUTH_PROVIDER_PUBLIC_SERVICE_URL: http://oauth:4444 + OAUTH_PROVIDER_ADMIN_SERVICE_URL: http://oauth:4445 + OAUTH_PROVIDER_CONSENT_LOGIN_BASE_URL: http://localhost:3001/auth + OAUTH_CLIENT_SECRET_ENCRYPTION_KEY: asdfasdfasdfasdfasdf + healthcheck: + test: bash -c 'curl -s "http://127.0.0.1:3567/hello" | grep "Hello"' + interval: 10s + timeout: 5s + retries: 5 + + oauth: + image: supertokens/oauth2-test:latest + platform: linux/amd64 diff --git a/hooks/populate-hook-constants.sh b/hooks/populate-hook-constants.sh new file mode 100755 index 00000000..c5a56d06 --- /dev/null +++ b/hooks/populate-hook-constants.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Look for the version string with additional handling for: +# - Abitrary Spaces: ` *` +# - Extracting the version into a match group: `(...)` +# - Substituting the matched string with the match group: `/\1/` +export packageVersion=$( echo $(cat package.json | jq .version) | sed -n 's/^["]\([0-9\.]*\).*/\1/p' ) +export packageVersionXy=$( echo $(cat package.json | jq .version) | sed -n 's/^["]\([0-9]*\.[0-9]*\).*/\1/p' ) +export packageLockVersion=$( echo $(cat package-lock.json | jq .version) | sed -n 's/["]\([0-9\.]*\).*/\1/p' ) +export packageLockVersionXy=$( echo $(cat package-lock.json | jq .version) | sed -n 's/["]\([0-9]*\.[0-9]*\).*/\1/p' ) + +export newestVersion=$( if [[ "$packageVersion" > "$packageLockVersion" ]]; then echo "$packageVersion"; else echo "$packageLockVersion"; fi ) + +# Target branch of the PR. +# Ideally, this is all we want to check. +if [[ "$GITHUB_BASE_REF" != "" ]] +then + export targetBranch="$GITHUB_BASE_REF" +else # Fallback to current branch if not in a PR + export targetBranch=$(git branch --show-current 2> /dev/null) || export targetBranch="(unnamed branch)" # Get current branch +fi +export targetBranch=${targetBranch##refs/heads/} # Remove refs/heads/ if present