From a6fd1614fe5cc0c8dd218259d23c14c611e4b621 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 22 Jan 2025 22:38:02 +0100 Subject: [PATCH] Refactor auth into action --- .github/workflows/preview-cleanup.yml | 45 +++++++++++++++++++++++++++ .github/workflows/preview.yml | 36 ++++----------------- actions/aws-auth/action.yml | 38 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/preview-cleanup.yml create mode 100644 actions/aws-auth/action.yml diff --git a/.github/workflows/preview-cleanup.yml b/.github/workflows/preview-cleanup.yml new file mode 100644 index 0000000..bb91660 --- /dev/null +++ b/.github/workflows/preview-cleanup.yml @@ -0,0 +1,45 @@ +name: preview-cleanup + +on: + pull_request_target: + types: [closed] + +permissions: + deployments: write + id-token: write + +jobs: + cleanup: + runs-on: ubuntu-latest + steps: + - uses: ./actions/aws-auth + - name: Delete s3 objects + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" --delete + + - name: Delete preview deployments + uses: actions/github-script@v7 + with: + script: | + const deployments = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: `preview-${context.issue.number}` + }); + for (const deployment of deployments.data) { + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id, + state: 'inactive', + description: 'Marking deployment as inactive' + }); + await github.rest.repos.deleteDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id + }); + } + diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index a7c7ae0..f0ce9b1 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -19,26 +19,24 @@ jobs: with: result-encoding: string script: | - const response = await github.rest.repos.createDeployment({ + const deployment = await github.rest.repos.createDeployment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, - ref: "${{ github.event.pull_request.head.ref }}", + ref: context.payload.pull_request.head.ref, environment: `preview-${context.issue.number}`, description: `Preview deployment for PR ${context.issue.number}`, auto_merge: false, required_contexts: [], }) - await github.rest.repos.createDeploymentStatus({ - deployment_id: response.data.id, + deployment_id: deployment.data.id, owner: context.repo.owner, repo: context.repo.repo, state: "in_progress", description: "Deployment created", log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}?pr=${context.issue.number}`, }) - return response.data.id - uses: actions/checkout@v4 @@ -54,29 +52,8 @@ jobs: env: PR_NUMBER: ${{ github.event.pull_request.number }} run: .artifacts/publish/docs-builder/release/docs-builder --strict --path-prefix "/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" - - name: Generate ARNs - id: generate_arns - shell: python - env: - AWS_ACCOUNT_ID: 197730964718 - run: | - import hashlib - import os - - prefix = "elastic-docs-v3-preview-" - aws_account_id = os.environ["AWS_ACCOUNT_ID"] - - m = hashlib.sha256() - m.update(os.environ["GITHUB_REPOSITORY"].encode('utf-8')) - hash = m.hexdigest()[:64-len(prefix)] - name = f"{prefix}{hash}" - with open(os.environ["GITHUB_OUTPUT"], "a") as f: - print(f"role_arn=arn:aws:iam::{aws_account_id}:role/{name}", file=f) - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - role-to-assume: ${{ steps.generate_arns.outputs.role_arn }} - aws-region: us-east-1 + + - uses: ./actions/aws-auth - name: Upload to S3 env: @@ -85,7 +62,6 @@ jobs: aws s3 sync .artifacts/docs/html "s3://elastic-docs-v3-website-preview/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}" --delete aws cloudfront create-invalidation --distribution-id EKT7LT5PM8RKS --paths "/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}/*" - - name: Update deployment status uses: actions/github-script@v7 if: steps.deployment.outputs.result @@ -97,7 +73,7 @@ jobs: deployment_id: ${{ steps.deployment.outputs.result }}, state: "success", description: "Deployment completed", - environment_url: `https://d2euvt1bxklciq.cloudfront.net/${{ github.repository }}/pull/${{ github.event.pull_request.number}}`, + environment_url: `https://d2euvt1bxklciq.cloudfront.net/${context.repo.owner}/${context.repo.repo}/pull/${context.issue.number}`, log_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}?pr=${context.issue.number}`, }) diff --git a/actions/aws-auth/action.yml b/actions/aws-auth/action.yml new file mode 100644 index 0000000..3195aa4 --- /dev/null +++ b/actions/aws-auth/action.yml @@ -0,0 +1,38 @@ +name: AWS Auth + +description: | + This is an opinionated action to authenticate with AWS. + It will generate a role ARN based on the repository name and the AWS account ID. + +inputs: + aws_account_id: + description: 'The AWS account ID to generate the role ARN for' + required: true + default: '197730964718' # elastic-web + aws_region: + description: 'The AWS region to use' + required: false + default: 'us-east-1' + +runs: + using: composite + steps: + - name: Generate AWS Role ARN + id: role_arn + shell: python + env: + AWS_ACCOUNT_ID: ${{ inputs.aws_account_id }} + run: | + import hashlib + import os + prefix = "elastic-docs-link-index-uploader-" + m = hashlib.sha256() + m.update(os.environ["GITHUB_REPOSITORY"].encode('utf-8')) + hash = m.hexdigest()[:64-len(prefix)] + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"result=arn:aws:iam::{os.environ["AWS_ACCOUNT_ID"]}:role/{prefix}{hash}") + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + role-to-assume: ${{ steps.role_arn.outputs.result }} + aws-region: ${{ inputs.aws_region }}