name: Docs deploy
on:
  workflow_run: # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
    workflows: ['Docs build']
    types:
      - completed

env:
  TG_NON_INTERACTIVE: 'true'

jobs:
  checks:
    name: Docs Deploy Checks
    runs-on: ubuntu-latest
    permissions:
      actions: read
      pull-requests: read
    outputs:
      parameters: ${{ steps.parameters.outputs.result }}
      artifact: ${{ steps.get-artifact.outputs.result }}
    steps:
      - id: token
        uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
        with:
          client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
          private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}

      - if: ${{ github.event.workflow_run.conclusion != 'success' }}
        run: echo 'The triggering workflow did not succeed' && exit 1
      - name: Get artifact
        id: get-artifact
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          github-token: ${{ steps.token.outputs.token }}
          script: |
            let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: context.payload.workflow_run.id,
            });
            let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
              return artifact.name == "docs-build-output"
            })[0];
            if (!matchArtifact) {
              console.log("No artifact found with the name docs-build-output, build job was skipped")
              return { found: false };
            }
            return { found: true, id: matchArtifact.id };
      - name: Determine deploy parameters
        id: parameters
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        env:
          HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
        with:
          github-token: ${{ steps.token.outputs.token }}
          script: |
            const eventType = context.payload.workflow_run.event;
            const isFork = context.payload.workflow_run.repository.fork;

            let parameters;

            console.log({eventType, isFork});

            if (eventType == "push") {
              const branch = context.payload.workflow_run.head_branch;
              console.log({branch});
              const shouldDeploy = !isFork && branch == "main";
              parameters = {
                event: "branch",
                name: "main",
                shouldDeploy
              };
            } else if (eventType == "pull_request") {
              let pull_number = context.payload.workflow_run.pull_requests[0]?.number;
              if(!pull_number) {
                const {HEAD_SHA} = process.env;
                const response = await github.rest.search.issuesAndPullRequests({q: `repo:${{ github.repository }} is:pr sha:${HEAD_SHA}`,per_page: 1,})
                const items = response.data.items
                if (items.length < 1) {
                  throw new Error("No pull request found for the commit")
                }
                const pullRequestNumber = items[0].number
                console.info("Pull request number is", pullRequestNumber)
                pull_number = pullRequestNumber
              }
              const {data: pr} = await github.rest.pulls.get({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number
              });

              console.log({pull_number});

              parameters = {
                event: "pr",
                name: `pr-${pull_number}`,
                pr_number: pull_number,
                shouldDeploy: true
              };
            } else if (eventType == "release") {
              const tag = context.payload.workflow_run.head_branch;
              const { data: release } = await github.rest.repos.getReleaseByTag({
                owner: context.repo.owner,
                repo: context.repo.repo,
                tag,
              });
              parameters = {
                event: "release",
                name: tag,
                prerelease: release.prerelease,
                shouldDeploy: !isFork
              };
            }

            console.log(parameters);
            return parameters;

  deploy:
    name: Docs Deploy
    runs-on: ubuntu-latest
    needs: checks
    permissions:
      contents: read
      actions: read
      pull-requests: write
    if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
    steps:
      - id: token
        uses: immich-app/devtools/actions/create-workflow-token@9db058b2e6eec20e07760b0e17a0505c78ec3191 # create-workflow-token-action-v2.0.1
        with:
          client-id: ${{ secrets.PUSH_O_MATIC_APP_CLIENT_ID }}
          private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }}

      - name: Checkout code
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
          token: ${{ steps.token.outputs.token }}

      - name: Setup Mise
        uses: immich-app/devtools/actions/use-mise@3bca63ca3c15020293b36b51737a3ee2c773340b # use-mise-action-v3.1.0
        with:
          github_token: ${{ steps.token.outputs.token }}

      - name: Load parameters
        id: parameters
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        env:
          PARAM_JSON: ${{ needs.checks.outputs.parameters }}
        with:
          github-token: ${{ steps.token.outputs.token }}
          script: |
            const parameters = JSON.parse(process.env.PARAM_JSON);
            core.setOutput("event", parameters.event);
            core.setOutput("name", parameters.name);
            core.setOutput("prerelease", parameters.prerelease);
            core.setOutput("shouldDeploy", parameters.shouldDeploy);

      - name: Download artifact
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        env:
          ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
        with:
          github-token: ${{ steps.token.outputs.token }}
          script: |
            let artifact = JSON.parse(process.env.ARTIFACT_JSON);
            let download = await github.rest.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: artifact.id,
               archive_format: 'zip',
            });
            let fs = require('fs');
            fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/docs-build-output.zip`, Buffer.from(download.data));

      - name: Unzip artifact
        run: unzip "${{ github.workspace }}/docs-build-output.zip" -d "${{ github.workspace }}/docs/build"

      - name: Deploy Docs Subdomain
        env:
          TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
          TF_VAR_prefix_event_type: ${{ steps.parameters.outputs.event }}
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
        working-directory: 'deployment/modules/cloudflare/docs'
        run: 'mise run //deployment:tf apply'

      - name: Deploy Docs Subdomain Output
        id: docs-output
        env:
          TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
          TF_VAR_prefix_event_type: ${{ steps.parameters.outputs.event }}
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
        working-directory: 'deployment/modules/cloudflare/docs'
        run: |
          mise run //deployment:tf output -- -json | jq -r '
            "projectName=\(.pages_project_name.value)",
            "subdomain=\(.immich_app_branch_subdomain.value)"
          ' >> $GITHUB_OUTPUT

      - name: Publish to Cloudflare Pages
        working-directory: docs
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          PROJECT_NAME: ${{ steps.docs-output.outputs.projectName }}
          BRANCH_NAME: ${{ steps.parameters.outputs.name }}
        run: mise run //docs:deploy

      - name: Deploy Docs Release Domain
        if: ${{ steps.parameters.outputs.event == 'release' && steps.parameters.outputs.prerelease != 'true' }}
        env:
          TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
        working-directory: 'deployment/modules/cloudflare/docs-release'
        run: 'mise run //deployment:tf apply'

      - name: Comment
        uses: immich-app/devtools/actions/sticky-comment@0135acd12ad9f3369b94a2aa3c0ae8c835a4e926 # sticky-comment-action-v1.0.0
        if: ${{ steps.parameters.outputs.event == 'pr' }}
        with:
          id: docs-pr-url
          token: ${{ steps.token.outputs.token }}
          number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
          body: |
            📖 Documentation deployed to [${{ steps.docs-output.outputs.subdomain }}](https://${{ steps.docs-output.outputs.subdomain }})
