sdadfadas

Форк
0
/
ephemeral-env.yml 
283 строки · 10.5 Кб
1
name: Ephemeral env workflow
2

3
on:
4
  issue_comment:
5
    types: [created]
6

7
jobs:
8
  config:
9
    runs-on: "ubuntu-22.04"
10
    if: github.event.issue.pull_request
11
    outputs:
12
      has-secrets: ${{ steps.check.outputs.has-secrets }}
13
    steps:
14
      - name: "Check for secrets"
15
        id: check
16
        shell: bash
17
        run: |
18
          if [ -n "${{ (secrets.AWS_ACCESS_KEY_ID != '' && secrets.AWS_SECRET_ACCESS_KEY != '') || '' }}" ]; then
19
            echo "has-secrets=1" >> "$GITHUB_OUTPUT"
20
          fi
21

22
  ephemeral-env-comment:
23
    concurrency:
24
      group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}-comment
25
      cancel-in-progress: true
26
    needs: config
27
    if: needs.config.outputs.has-secrets
28
    name: Evaluate ephemeral env comment trigger (/testenv)
29
    runs-on: ubuntu-22.04
30
    permissions:
31
      pull-requests: write
32
    outputs:
33
      slash-command: ${{ steps.eval-body.outputs.result }}
34
      feature-flags: ${{ steps.eval-feature-flags.outputs.result }}
35

36
    steps:
37
    - name: Debug
38
      run: |
39
        echo "Comment on PR #${{ github.event.issue.number }} by ${{ github.event.issue.user.login }}, ${{ github.event.comment.author_association }}"
40

41
    - name: Eval comment body for /testenv slash command
42
      uses: actions/github-script@v7
43
      id: eval-body
44
      with:
45
        result-encoding: string
46
        script: |
47
          const pattern = /^\/testenv (up|down)/
48
          const result = pattern.exec(context.payload.comment.body)
49
          return result === null ? 'noop' : result[1]
50

51
    - name: Eval comment body for feature flags
52
      uses: actions/github-script@v7
53
      id: eval-feature-flags
54
      with:
55
        script: |
56
          const pattern = /FEATURE_(\w+)=(\w+)/g;
57
          let results = [];
58
          [...context.payload.comment.body.matchAll(pattern)].forEach(match => {
59
            const config = {
60
              name: `SUPERSET_FEATURE_${match[1]}`,
61
              value: match[2],
62
            };
63
            results.push(config);
64
          });
65
          return results;
66

67
    - name: Limit to committers
68
      if: >
69
        steps.eval-body.outputs.result != 'noop' &&
70
        github.event.comment.author_association != 'MEMBER' &&
71
        github.event.comment.author_association != 'OWNER'
72
      uses: actions/github-script@v7
73
      with:
74
        github-token: ${{github.token}}
75
        script: |
76
          const errMsg = '@${{ github.event.comment.user.login }} Ephemeral environment creation is currently limited to committers.'
77
          github.rest.issues.createComment({
78
            issue_number: ${{ github.event.issue.number }},
79
            owner: context.repo.owner,
80
            repo: context.repo.repo,
81
            body: errMsg
82
          })
83
          core.setFailed(errMsg)
84

85
  ephemeral-docker-build:
86
    concurrency:
87
      group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}-build
88
      cancel-in-progress: true
89
    needs: ephemeral-env-comment
90
    name: ephemeral-docker-build
91
    runs-on: ubuntu-22.04
92
    steps:
93
      - name: Get Info from comment
94
        uses: actions/github-script@v7
95
        id: get-pr-info
96
        with:
97
          script: |
98
            const request = {
99
                owner: context.repo.owner,
100
                repo: context.repo.repo,
101
                pull_number: ${{ github.event.issue.number }},
102
            }
103
            core.info(`Getting PR #${request.pull_number} from ${request.owner}/${request.repo}`)
104
            const pr = await github.rest.pulls.get(request);
105
            return pr.data;
106

107
      - name: Debug
108
        id: get-sha
109
        run: |
110
          echo "sha=${{ fromJSON(steps.get-pr-info.outputs.result).head.sha }}" >> $GITHUB_OUTPUT
111

112
      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} : ${{steps.get-sha.outputs.sha}} )"
113
        uses: actions/checkout@v4
114
        with:
115
          ref: ${{ steps.get-sha.outputs.sha }}
116
          persist-credentials: false
117

118
      - name: Set up QEMU
119
        uses: docker/setup-qemu-action@v3
120

121
      - name: Set up Docker Buildx
122
        uses: docker/setup-buildx-action@v3
123

124
      - name: Build ephemeral env image
125
        run: |
126
          ./scripts/build_docker.py \
127
            "ci" \
128
            "pull_request" \
129
            --build_context_ref ${{ github.event.issue.number }}
130

131
      - name: Configure AWS credentials
132
        uses: aws-actions/configure-aws-credentials@v4
133
        with:
134
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
135
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
136
          aws-region: us-west-2
137

138
      - name: Login to Amazon ECR
139
        id: login-ecr
140
        uses: aws-actions/amazon-ecr-login@v2
141

142
      - name: Load, tag and push image to ECR
143
        id: push-image
144
        env:
145
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
146
          ECR_REPOSITORY: superset-ci
147
          IMAGE_TAG: apache/superset:${{ steps.get-sha.outputs.sha }}-ci
148
        run: |
149
          docker tag $IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:pr-${{ github.event.issue.number }}-ci
150
          docker push -a $ECR_REGISTRY/$ECR_REPOSITORY
151

152
  ephemeral-env-up:
153
    needs: [ephemeral-env-comment, ephemeral-docker-build]
154
    if: needs.ephemeral-env-comment.outputs.slash-command == 'up'
155
    name: Spin up an ephemeral environment
156
    runs-on: ubuntu-22.04
157
    permissions:
158
      contents: read
159
      pull-requests: write
160

161
    steps:
162
    - uses: actions/checkout@v4
163
      with:
164
        persist-credentials: false
165

166
    - name: Configure AWS credentials
167
      uses: aws-actions/configure-aws-credentials@v4
168
      with:
169
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
170
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
171
        aws-region: us-west-2
172

173
    - name: Login to Amazon ECR
174
      id: login-ecr
175
      uses: aws-actions/amazon-ecr-login@v2
176

177
    - name: Check target image exists in ECR
178
      id: check-image
179
      continue-on-error: true
180
      run: |
181
        aws ecr describe-images \
182
        --registry-id $(echo "${{ steps.login-ecr.outputs.registry }}" | grep -Eo "^[0-9]+") \
183
        --repository-name superset-ci \
184
        --image-ids imageTag=pr-${{ github.event.issue.number }}-ci
185

186
    - name: Fail on missing container image
187
      if: steps.check-image.outcome == 'failure'
188
      uses: actions/github-script@v7
189
      with:
190
        github-token: ${{github.token}}
191
        script: |
192
          const errMsg = '@${{ github.event.comment.user.login }} Container image not yet published for this PR. Please try again when build is complete.'
193
          github.rest.issues.createComment({
194
            issue_number: ${{ github.event.issue.number }},
195
            owner: context.repo.owner,
196
            repo: context.repo.repo,
197
            body: errMsg
198
          })
199
          core.setFailed(errMsg)
200

201
    - name: Fill in the new image ID in the Amazon ECS task definition
202
      id: task-def
203
      uses: aws-actions/amazon-ecs-render-task-definition@v1
204
      with:
205
        task-definition: .github/workflows/ecs-task-definition.json
206
        container-name: superset-ci
207
        image: ${{ steps.login-ecr.outputs.registry }}/superset-ci:pr-${{ github.event.issue.number }}-ci
208

209
    - name: Update env vars in the Amazon ECS task definition
210
      run: |
211
        cat <<< "$(jq '.containerDefinitions[0].environment += ${{ needs.ephemeral-env-comment.outputs.feature-flags }}' < ${{ steps.task-def.outputs.task-definition }})" > ${{ steps.task-def.outputs.task-definition }}
212

213
    - name: Describe ECS service
214
      id: describe-services
215
      run: |
216
        echo "active=$(aws ecs describe-services --cluster superset-ci --services pr-${{ github.event.issue.number }}-service | jq '.services[] | select(.status == "ACTIVE") | any')" >> $GITHUB_OUTPUT
217
    - name: Create ECS service
218
      if: steps.describe-services.outputs.active != 'true'
219
      id: create-service
220
      env:
221
        ECR_SUBNETS: subnet-0e15a5034b4121710,subnet-0e8efef4a72224974
222
        ECR_SECURITY_GROUP: sg-092ff3a6ae0574d91
223
      run: |
224
        aws ecs create-service \
225
        --cluster superset-ci \
226
        --service-name pr-${{ github.event.issue.number }}-service \
227
        --task-definition superset-ci \
228
        --launch-type FARGATE \
229
        --desired-count 1 \
230
        --platform-version LATEST \
231
        --network-configuration "awsvpcConfiguration={subnets=[$ECR_SUBNETS],securityGroups=[$ECR_SECURITY_GROUP],assignPublicIp=ENABLED}" \
232
        --tags key=pr,value=${{ github.event.issue.number }} key=github_user,value=${{ github.actor }}
233

234
    - name: Deploy Amazon ECS task definition
235
      id: deploy-task
236
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
237
      with:
238
        task-definition: ${{ steps.task-def.outputs.task-definition }}
239
        service: pr-${{ github.event.issue.number }}-service
240
        cluster: superset-ci
241
        wait-for-service-stability: true
242
        wait-for-minutes: 10
243

244
    - name: List tasks
245
      id: list-tasks
246
      run: |
247
        echo "task=$(aws ecs list-tasks --cluster superset-ci --service-name pr-${{ github.event.issue.number }}-service | jq '.taskArns | first')" >> $GITHUB_OUTPUT
248

249
    - name: Get network interface
250
      id: get-eni
251
      run: |
252
        echo "eni=$(aws ecs describe-tasks --cluster superset-ci --tasks ${{ steps.list-tasks.outputs.task }} | jq '.tasks | .[0] | .attachments | .[0] | .details | map(select(.name=="networkInterfaceId")) | .[0] | .value')" >> $GITHUB_OUTPUT
253

254
    - name: Get public IP
255
      id: get-ip
256
      run: |
257
        echo "ip=$(aws ec2 describe-network-interfaces --network-interface-ids ${{ steps.get-eni.outputs.eni }} | jq -r '.NetworkInterfaces | first | .Association.PublicIp')" >> $GITHUB_OUTPUT
258

259
    - name: Comment (success)
260
      if: ${{ success() }}
261
      uses: actions/github-script@v7
262
      with:
263
        github-token: ${{github.token}}
264
        script: |
265
          github.rest.issues.createComment({
266
            issue_number: ${{ github.event.issue.number }},
267
            owner: context.repo.owner,
268
            repo: context.repo.repo,
269
            body: '@${{ github.event.comment.user.login }} Ephemeral environment spinning up at http://${{ steps.get-ip.outputs.ip }}:8080. Credentials are `admin`/`admin`. Please allow several minutes for bootstrapping and startup.'
270
          })
271

272
    - name: Comment (failure)
273
      if: ${{ failure() }}
274
      uses: actions/github-script@v7
275
      with:
276
        github-token: ${{github.token}}
277
        script: |
278
          github.rest.issues.createComment({
279
            issue_number: ${{ github.event.issue.number }},
280
            owner: context.repo.owner,
281
            repo: context.repo.repo,
282
            body: '@${{ github.event.comment.user.login }} Ephemeral environment creation failed. Please check the Actions logs for details.'
283
          })
284

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.