chore(ads): remove ads experimental annotations #1873
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "@RCGitBot please test" | |
| on: | |
| issue_comment: | |
| types: [created] | |
| # Deny-all baseline: each job must declare its own `permissions:` block. | |
| permissions: {} | |
| jobs: | |
| approve-full-tests: | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event.issue.pull_request && | |
| github.event.comment.body == '@RCGitBot please test' && | |
| github.repository == 'RevenueCat/purchases-ios' && | |
| github.event.comment.author_association == 'MEMBER' | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| # GitHub Actions `issue_comment` workflows always run from the default branch, | |
| # so we resolve the PR's head branch to find its CircleCI pipeline and approve | |
| # the hold job in the existing workflow. | |
| - name: Get PR branch | |
| id: get-branch | |
| run: echo "branch=$(gh pr view "$PR_NO" --repo "$REPO" --json headRefName --jq '.headRefName')" >> "$GITHUB_OUTPUT" | |
| env: | |
| REPO: ${{ github.repository }} | |
| PR_NO: ${{ github.event.issue.number }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Approve CircleCI hold job | |
| id: approve | |
| env: | |
| CCI_TOKEN: ${{ secrets.CIRCLECI_TOKEN }} | |
| BRANCH: ${{ steps.get-branch.outputs.branch }} | |
| run: | | |
| PROJECT_SLUG="gh/RevenueCat/purchases-ios" | |
| WORKFLOW_NAME="run-all-tests" | |
| APPROVAL_JOB_NAME="approve-full-tests" | |
| # This repo uses CircleCI dynamic config: on push, a setup workflow runs | |
| # first and generates a continuation config. The 'run-all-tests' workflow | |
| # (and its 'approve-full-tests' hold job) only appears in the pipeline once | |
| # setup finishes. If someone comments '@RCGitBot please test' while setup is | |
| # still running, the workflow/approval job isn't there yet. So we poll for it | |
| # instead of failing immediately. | |
| # Keep total polling under ~1 minute: 4 attempts with 15s between them = ~45s | |
| # of waiting (plus request time). | |
| MAX_ATTEMPTS=4 | |
| SLEEP_SECONDS=15 | |
| # 1. Get the most recent pipeline for this branch | |
| PIPELINE_ID=$(curl -s --max-time 15 -G \ | |
| -H "Circle-Token: $CCI_TOKEN" \ | |
| --data-urlencode "branch=$BRANCH" \ | |
| "https://circleci.com/api/v2/project/$PROJECT_SLUG/pipeline" \ | |
| | jq -r '.items[0].id') | |
| if [[ -z "$PIPELINE_ID" || "$PIPELINE_ID" == "null" ]]; then | |
| echo "::error::No CircleCI pipeline found for branch '$BRANCH'" | |
| exit 1 | |
| fi | |
| echo "Found pipeline: $PIPELINE_ID" | |
| # 2. Poll for the run-all-tests workflow and its approval job. Both may be | |
| # missing while the setup workflow is still generating the continuation config. | |
| WORKFLOW_ID="" | |
| APPROVAL_REQUEST_ID="" | |
| for ((attempt=1; attempt<=MAX_ATTEMPTS; attempt++)); do | |
| WORKFLOW_ID=$(curl -s --max-time 15 \ | |
| -H "Circle-Token: $CCI_TOKEN" \ | |
| "https://circleci.com/api/v2/pipeline/$PIPELINE_ID/workflow" \ | |
| | jq -r --arg name "$WORKFLOW_NAME" '.items[] | select(.name == $name) | .id') | |
| if [[ -n "$WORKFLOW_ID" && "$WORKFLOW_ID" != "null" ]]; then | |
| echo "Found workflow: $WORKFLOW_ID" | |
| JOBS_RESPONSE=$(curl -s --max-time 15 \ | |
| -H "Circle-Token: $CCI_TOKEN" \ | |
| "https://circleci.com/api/v2/workflow/$WORKFLOW_ID/job") | |
| JOB_STATUS=$(echo "$JOBS_RESPONSE" | jq -r --arg name "$APPROVAL_JOB_NAME" \ | |
| '.items[] | select(.name == $name and .type == "approval") | .status') | |
| if [[ "$JOB_STATUS" == "success" ]]; then | |
| echo "Hold job '$APPROVAL_JOB_NAME' was already approved" | |
| exit 0 | |
| fi | |
| APPROVAL_REQUEST_ID=$(echo "$JOBS_RESPONSE" | jq -r --arg name "$APPROVAL_JOB_NAME" \ | |
| '.items[] | select(.name == $name and .type == "approval") | .approval_request_id') | |
| if [[ -n "$APPROVAL_REQUEST_ID" && "$APPROVAL_REQUEST_ID" != "null" ]]; then | |
| break | |
| fi | |
| fi | |
| if [[ "$attempt" -lt "$MAX_ATTEMPTS" ]]; then | |
| echo "Attempt $attempt/$MAX_ATTEMPTS: '$WORKFLOW_NAME' workflow / '$APPROVAL_JOB_NAME' job not ready yet (setup may still be running). Retrying in ${SLEEP_SECONDS}s..." | |
| sleep "$SLEEP_SECONDS" | |
| fi | |
| done | |
| if [[ -z "$WORKFLOW_ID" || "$WORKFLOW_ID" == "null" ]]; then | |
| echo "::error::No '$WORKFLOW_NAME' workflow found in pipeline $PIPELINE_ID after $MAX_ATTEMPTS attempts" | |
| exit 1 | |
| fi | |
| if [[ -z "$APPROVAL_REQUEST_ID" || "$APPROVAL_REQUEST_ID" == "null" ]]; then | |
| echo "::error::Approval job '$APPROVAL_JOB_NAME' not found in workflow $WORKFLOW_ID after $MAX_ATTEMPTS attempts" | |
| exit 1 | |
| fi | |
| echo "Found approval request: $APPROVAL_REQUEST_ID" | |
| # 3. Approve it | |
| HTTP_STATUS=$(curl -s --max-time 15 -o /dev/null -w "%{http_code}" -X POST \ | |
| -H "Circle-Token: $CCI_TOKEN" \ | |
| "https://circleci.com/api/v2/workflow/$WORKFLOW_ID/approve/$APPROVAL_REQUEST_ID") | |
| if [[ "$HTTP_STATUS" != "202" ]]; then | |
| echo "::error::Failed to approve job. CircleCI returned HTTP $HTTP_STATUS" | |
| exit 1 | |
| fi | |
| echo "Successfully approved '$APPROVAL_JOB_NAME' in workflow '$WORKFLOW_NAME'" | |
| - name: React to comment | |
| if: always() | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| JOB_STATUS: ${{ job.status }} | |
| REPO: ${{ github.repository }} | |
| COMMENT_ID: ${{ github.event.comment.id }} | |
| run: | | |
| if [[ "$JOB_STATUS" == "success" ]]; then | |
| REACTION="+1" | |
| else | |
| REACTION="-1" | |
| fi | |
| gh api "repos/$REPO/issues/comments/$COMMENT_ID/reactions" \ | |
| -f content="$REACTION" | |
| # Trigger CircleCI job(s) on-demand via "@RCGitBot please test <job1> <job2> <job3>". | |
| # Triggers a new CircleCI pipeline; the setup config generates a continuation | |
| # config containing only a workflow with the requested job(s). | |
| run-specific-jobs: | |
| runs-on: ubuntu-latest | |
| if: | | |
| github.event.issue.pull_request && | |
| startsWith(github.event.comment.body, '@RCGitBot please test ') && | |
| github.repository == 'RevenueCat/purchases-ios' && | |
| github.event.comment.author_association == 'MEMBER' | |
| permissions: | |
| pull-requests: write | |
| steps: | |
| - name: Parse job names | |
| id: parse | |
| env: | |
| COMMENT: ${{ github.event.comment.body }} | |
| run: | | |
| # GHA's startsWith() is case-insensitive, so lowercase the comment before stripping | |
| # the prefix. Then use the length to slice the original, preserving job name case | |
| # (e.g. backend-integration-tests-SK1). | |
| PREFIX="@rcgitbot please test " | |
| COMMENT_LOWER="$(echo "$COMMENT" | tr '[:upper:]' '[:lower:]')" | |
| if [[ "$COMMENT_LOWER" != "$PREFIX"* ]]; then | |
| echo "::error::Comment does not start with '@RCGitBot please test '" | |
| exit 1 | |
| fi | |
| JOBS_RAW="${COMMENT:${#PREFIX}}" | |
| # Trim whitespace | |
| JOBS_RAW=$(echo "$JOBS_RAW" | xargs) | |
| if [[ -z "$JOBS_RAW" ]]; then | |
| echo "::error::No job name(s) provided" | |
| exit 1 | |
| fi | |
| # Validate: only alphanumeric, hyphens, underscores, and spaces | |
| if [[ ! "$JOBS_RAW" =~ ^[a-zA-Z0-9_[:space:]-]+$ ]]; then | |
| echo "::error::Invalid input: $JOBS_RAW (only alphanumeric, hyphens, underscores, and spaces allowed)" | |
| exit 1 | |
| fi | |
| echo "job_names=$JOBS_RAW" >> "$GITHUB_OUTPUT" | |
| echo "Parsed job(s): $JOBS_RAW" | |
| - name: Get PR branch | |
| id: get-branch | |
| run: echo "branch=$(gh pr view "$PR_NO" --repo "$REPO" --json headRefName --jq '.headRefName')" >> "$GITHUB_OUTPUT" | |
| env: | |
| REPO: ${{ github.repository }} | |
| PR_NO: ${{ github.event.issue.number }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Trigger CircleCI pipeline | |
| id: trigger | |
| env: | |
| CCI_TOKEN: ${{ secrets.CIRCLECI_TOKEN }} | |
| BRANCH: ${{ steps.get-branch.outputs.branch }} | |
| JOB_NAMES: ${{ steps.parse.outputs.job_names }} | |
| run: | | |
| PROJECT_SLUG="gh/RevenueCat/purchases-ios" | |
| # Build the payload with jq rather than string interpolation: branch names come | |
| # from the PR head ref and may contain characters that need JSON escaping. | |
| BODY_JSON=$(jq -n --arg branch "$BRANCH" --arg jobs "$JOB_NAMES" \ | |
| '{branch: $branch, parameters: {requested_jobs: $jobs}}') | |
| RESPONSE=$(curl -s --max-time 15 -w "\n%{http_code}" -X POST \ | |
| -H "Circle-Token: $CCI_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "$BODY_JSON" \ | |
| "https://circleci.com/api/v2/project/$PROJECT_SLUG/pipeline") | |
| HTTP_STATUS=$(echo "$RESPONSE" | tail -1) | |
| BODY=$(echo "$RESPONSE" | head -n -1) | |
| if [[ "$HTTP_STATUS" != "201" ]]; then | |
| echo "::error::Failed to trigger pipeline. CircleCI returned HTTP $HTTP_STATUS" | |
| echo "$BODY" | |
| exit 1 | |
| fi | |
| PIPELINE_ID=$(echo "$BODY" | jq -r '.id') | |
| PIPELINE_NUMBER=$(echo "$BODY" | jq -r '.number') | |
| echo "pipeline_number=$PIPELINE_NUMBER" >> "$GITHUB_OUTPUT" | |
| echo "Triggered pipeline #$PIPELINE_NUMBER (id: $PIPELINE_ID) for job(s) '$JOB_NAMES' on branch '$BRANCH'" | |
| - name: Post pipeline link | |
| if: success() | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PIPELINE_NUMBER: ${{ steps.trigger.outputs.pipeline_number }} | |
| JOB_NAMES: ${{ steps.parse.outputs.job_names }} | |
| REPO: ${{ github.repository }} | |
| ISSUE_NUMBER: ${{ github.event.issue.number }} | |
| run: | | |
| gh api "repos/$REPO/issues/$ISSUE_NUMBER/comments" \ | |
| -f body="🚀 Triggered **$JOB_NAMES** → [Pipeline #$PIPELINE_NUMBER](https://app.circleci.com/pipelines/gh/RevenueCat/purchases-ios/$PIPELINE_NUMBER)" | |
| - name: React to comment | |
| if: always() | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| JOB_STATUS: ${{ job.status }} | |
| REPO: ${{ github.repository }} | |
| COMMENT_ID: ${{ github.event.comment.id }} | |
| run: | | |
| if [[ "$JOB_STATUS" == "success" ]]; then | |
| REACTION="+1" | |
| else | |
| REACTION="-1" | |
| fi | |
| gh api "repos/$REPO/issues/comments/$COMMENT_ID/reactions" \ | |
| -f content="$REACTION" |