summaryrefslogtreecommitdiffstatshomepage
path: root/.github/workflows/commit-built-file-changes.yml
blob: 52ce676c8942eda9a7a87581c7a19779baec260f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Commits all missed changes to built files back to pull request branches.
name: Commit Built File Changes (PRs)

on:
  workflow_run:
    workflows: [ 'Check Built Files (PRs)' ]
    types:
      - completed

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
  # The concurrency group contains the workflow name and the branch name for pull requests
  # or the commit hash for any other events.
  group: ${{ github.workflow }}-${{ github.event_name == 'workflow_run' && format( '{0}-{1}', github.event.workflow_run.head_branch, github.event.workflow_run.head_repository.name ) || github.sha }}

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
  # Checks a PR for uncommitted changes to built files.
  #
  # Performs the following steps:
  # - Attempts to download the artifact containing the PR diff.
  # - Checks for the existence of an artifact.
  # - Unzips the artifact.
  # - Generates a token for authenticating with the GitHub App.
  # - Checks out the repository.
  # - Applies the patch file.
  # - Displays the result of git diff.
  # - Configures the Git author.
  # - Stages changes.
  # - Commits changes.
  # - Pushes changes.
  update-built-files:
    name: Check and update built files
    runs-on: ubuntu-24.04
    if: ${{ github.repository == 'wordpress/wordpress-develop' }}
    timeout-minutes: 10
    permissions:
      contents: write
    steps:
      - name: Download artifact
        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
        with:
          script: |
            const artifacts = await github.rest.actions.listWorkflowRunArtifacts( {
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: process.env.RUN_ID,
            } );

            const matchArtifact = artifacts.data.artifacts.filter( ( artifact ) => {
              return artifact.name === 'pr-built-file-changes'
            } )[0];

            if ( ! matchArtifact ) {
              core.info( 'No artifact found!' );
              return;
            }

            const download = await github.rest.actions.downloadArtifact( {
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: matchArtifact.id,
               archive_format: 'zip',
            } );

            const fs = require( 'fs' );
            fs.writeFileSync( '${{ github.workspace }}/pr-built-file-changes.zip', Buffer.from( download.data ) )
        env:
          RUN_ID: ${{ github.event.workflow_run.id }}

      - name: Check for artifact
        id: artifact-check
        run: |
          if [ -f "pr-built-file-changes.zip" ]; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi

      - name: Unzip the artifact containing the PR data
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        run: unzip pr-built-file-changes.zip

      - name: Generate Installation Token
        id: generate_token
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        env:
          GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }}
          GH_APP_PRIVATE_KEY: ${{ secrets.GH_PR_BUILT_FILES_PRIVATE_KEY }}
        run: |
          echo "$GH_APP_PRIVATE_KEY" > private-key.pem

          # Generate JWT
          JWT=$(python3 - <<EOF
          import jwt, time
          private_key = open("private-key.pem", "r").read()
          payload = {
              "iat": int(time.time()),
              "exp": int(time.time()) + 600,  # 10-minute expiration
              "iss": $GH_APP_ID
          }
          print(jwt.encode(payload, private_key, algorithm="RS256"))
          EOF
          )

          # Get Installation ID
          INSTALLATION_ID=$(curl -s -X GET -H "Authorization: Bearer $JWT" \
            -H "Accept: application/vnd.github.v3+json" \
            https://api.github.com/app/installations | jq -r '.[0].id')

          # Request Installation Access Token
          ACCESS_TOKEN=$(curl -s -X POST -H "Authorization: Bearer $JWT" \
            -H "Accept: application/vnd.github.v3+json" \
            "https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens" | jq -r '.token')

          echo "ACCESS_TOKEN=$ACCESS_TOKEN" >> "$GITHUB_ENV"

          rm -f private-key.pem

      - name: Checkout repository
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        with:
          repository: ${{ github.event.workflow_run.head_repository.full_name }}
          ref: ${{ github.event.workflow_run.head_branch }}
          path: 'pr-repo'
          show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
          token: ${{ env.ACCESS_TOKEN }}

      - name: Apply patch
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        run: git apply ${{ github.workspace }}/changes.diff

      - name: Display changes to versioned files
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        run: git diff

      - name: Configure git user name and email
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        env:
          GH_APP_ID: ${{ secrets.GH_PR_BUILT_FILES_APP_ID }}
        run: |
          git config user.name "wordpress-develop-pr-bot[bot]"
          git config user.email ${{ env.GH_APP_ID }}+wordpress-develop-pr-bot[bot]@users.noreply.github.com

      - name: Stage changes
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        run: git add .

      - name: Commit changes
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        run: |
          git commit -m "Automation: Updating built files with changes. [dependabot skip]"

      - name: Push changes
        if: ${{ steps.artifact-check.outputs.exists == 'true' }}
        working-directory: 'pr-repo'
        run: git push