Skip to content

Commit 0bee0af

Browse files
yoshi-automationparthea
authored andcommitted
chore: Add github action to update discovery artifacts with breaking change detection
1 parent 17c8516 commit 0bee0af

File tree

6 files changed

+853
-1
lines changed

6 files changed

+853
-1
lines changed

.github/workflows/main.yml

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Copyright 2021 Google LLC
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: A workflow for updating discovery artifacts
16+
# Controls when the action will run.
17+
18+
on:
19+
schedule:
20+
# * is a special character in YAML so you have to quote this string
21+
# Run this Github Action every day at 7 AM UTC
22+
- cron: '* 7 * * *'
23+
24+
# Triggers the workflow on pull request events but only for the master branch
25+
pull_request:
26+
branches: [ master ]
27+
28+
jobs:
29+
build:
30+
name: Update Discovery Artifacts PR
31+
runs-on: ubuntu-latest
32+
if: |
33+
${{github.event.pull_request.user.login == 'parthea' && github.event.pull_request.title == 'chore: Add github action to update discovery artifacts'}}
34+
steps:
35+
- name: Check out working directory for changes
36+
uses: actions/checkout@v2
37+
with:
38+
ref: refs/heads/master
39+
path: ./branch
40+
41+
- name: Check out branch with scripts
42+
uses: actions/checkout@v2
43+
with:
44+
ref: refs/heads/add-github-action-to-update-discovery-artifacts
45+
path: ./branch_with_scripts
46+
47+
- name: Check out master
48+
uses: actions/checkout@v2
49+
with:
50+
ref: refs/heads/master
51+
path: ./main
52+
53+
- name: Create branch
54+
run: |
55+
git checkout -b update-discovery-artifacts
56+
working-directory: ./branch
57+
58+
- name: Clone discovery artifacts from discovery-artifact manager
59+
uses: actions/checkout@v2
60+
with:
61+
repository: googleapis/discovery-artifact-manager
62+
path: ./discovery-artifact-manager
63+
64+
- name: Copy scripts
65+
run: |
66+
cp ../branch_with_scripts/scripts/* .
67+
working-directory: ./branch
68+
69+
- name: Copy discovery artifacts
70+
run: |
71+
cp ../discovery-artifact-manager/discoveries/*.json googleapiclient/discovery_cache/documents/
72+
working-directory: ./branch
73+
74+
- name: Get changed discovery artifacts
75+
run: git diff origin/master --name-only -- '*.json' |
76+
sed 's/.*\///' > changed_files
77+
working-directory: ./branch
78+
79+
- name: Set up Python 3.9
80+
uses: actions/setup-python@v1
81+
with:
82+
python-version: 3.9
83+
84+
- name: Install dependencies
85+
run: pip3 install -r requirements.txt
86+
working-directory: ./branch
87+
88+
- name: Install google-api-python-client
89+
run: pip3 install -e .
90+
working-directory: ./branch
91+
92+
# Apply a workaround to discovery.py to avoid DefaultCredentialsError
93+
# which is raised when calling `build_from_document()` as a result of
94+
# `google.auth.default()`. The workaround is to bypass the code block that
95+
# attempts to load default credentials.
96+
- name: Workaround to avoid DefaultCredentialsError in discovery.py
97+
run: sed -i -e 's/if credentials is None/if False/g' googleapiclient/discovery.py
98+
working-directory: ./branch
99+
100+
- name: Update the docs
101+
run: python3 describe.py
102+
working-directory: ./branch
103+
104+
- name: Run Change Summary
105+
run: python3 changesummary.py
106+
working-directory: ./branch
107+
108+
- name: Commit changes
109+
run: ./createcommits.sh
110+
working-directory: ./branch
111+
112+
- name: Push changes
113+
run: git push -f --set-upstream origin update-discovery-artifacts
114+
working-directory: ./branch
115+
116+
- name: Prepare summary for PR Body
117+
id: pr_body
118+
shell: bash
119+
run: |
120+
python3 buildprbody.py
121+
output=$(cat temp/allapis.summary)
122+
output="${output//'%'/'%25'}"
123+
output="${output//$'\n'/'%0A'}"
124+
output="${output//$'\r'/'%0D'}"
125+
echo "::set-output name=change_summary::$output"
126+
working-directory: ./branch
127+
128+
- name: Create PR
129+
uses: actions/[email protected]
130+
with:
131+
github-token: ${{secrets.YOSHI_CODE_BOT_TOKEN}}
132+
script: |
133+
async function createPR () {
134+
const { owner, repo } = context.repo
135+
const branch = 'update-discovery-artifacts'
136+
let prBody = `${{ steps.pr_body.outputs.change_summary }}`
137+
const prTitle = 'chore: Update discovery artifacts'
138+
const pullRequests = await github.pulls.list({
139+
owner: owner,
140+
repo: repo,
141+
head: `${owner}:${branch}`,
142+
state: 'open'
143+
})
144+
145+
if (pullRequests.data.length === 1) {
146+
prNumber = pullRequests.data[0].number
147+
await github.pulls.update({
148+
owner: owner,
149+
repo: repo,
150+
pull_number: prNumber,
151+
title: prTitle,
152+
body: prBody
153+
})
154+
console.log('Updated PR')
155+
} else {
156+
const createPrResult = await github.pulls.create({
157+
owner: owner,
158+
repo: repo,
159+
base: 'master',
160+
head: `${owner}:${branch}`,
161+
title: prTitle,
162+
body: prBody
163+
})
164+
prNumber = createPrResult.data.number
165+
console.log('Created PR')
166+
}
167+
}
168+
createPR()

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ Learn how to use the Google API Python Client with these guides:
3434

3535
### Reference Documentation
3636

37-
- Reference documentation for the the core library [googleapiclient](http://googleapis.github.io/google-api-python-client/docs/epy/index.html).
37+
- Reference documentation for the core library [googleapiclient](http://googleapis.github.io/google-api-python-client/docs/epy/index.html).
3838
- [Library reference documentation by API](dyn/index.md).

scripts/buildprbody.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Copyright 2021 Google LLC
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from enum import IntEnum
16+
import numpy as np
17+
import os
18+
import pandas as pd
19+
20+
21+
class ChangeType(IntEnum):
22+
UNKNOWN = 0
23+
DELETED = 1
24+
ADDED = 2
25+
CHANGED = 3
26+
27+
28+
def get_commit_link(name):
29+
"""Return a string with a link to the last commit for the given
30+
API Name.
31+
args:
32+
name (str): The name of the api.
33+
"""
34+
35+
url = "https://github.com/googleapis/google-api-python-client/commit/"
36+
sha = None
37+
api_link = ""
38+
39+
file_path = os.path.join(directory, "{0}.sha".format(name))
40+
if os.path.exists(file_path):
41+
with open(file_path, "r") as f:
42+
sha = f.readline().rstrip()
43+
if sha:
44+
api_link = "[{0}]({1}{2})".format(" [More details]", url, sha)
45+
46+
return api_link
47+
48+
49+
if __name__ == "__main__":
50+
directory = "temp"
51+
dataframe = pd.read_csv("temp/allapis.dataframe")
52+
dataframe["Version"] = dataframe["Version"].astype(str)
53+
54+
dataframe["Commit"] = np.vectorize(get_commit_link)(dataframe["Name"])
55+
56+
stable_and_breaking = (
57+
dataframe[
58+
dataframe["IsStable"]
59+
& (dataframe["ChangeType"] == ChangeType.DELETED)
60+
][["Name", "Version", "Commit"]]
61+
.drop_duplicates()
62+
.agg("".join, axis=1)
63+
.values
64+
)
65+
66+
prestable_and_breaking = (
67+
dataframe[
68+
(dataframe["IsStable"] == False)
69+
& (dataframe["ChangeType"] == ChangeType.DELETED)
70+
][["Name", "Version", "Commit"]]
71+
.drop_duplicates()
72+
.agg("".join, axis=1)
73+
.values
74+
)
75+
76+
all_apis = (
77+
dataframe[["Name", "Version", "Commit"]]
78+
.drop_duplicates()
79+
.agg("".join, axis=1)
80+
.values
81+
)
82+
83+
with open(os.path.join(directory, "allapis.summary"), "w") as f:
84+
if len(stable_and_breaking) > 0:
85+
f.writelines(
86+
[
87+
"## Deleted keys were detected in the following stable discovery artifacts:\n",
88+
"\n".join(stable_and_breaking),
89+
"\n\n",
90+
]
91+
)
92+
93+
if len(prestable_and_breaking) > 0:
94+
f.writelines(
95+
[
96+
"## Deleted keys were detected in the following pre-stable discovery artifacts:\n",
97+
"\n".join(prestable_and_breaking),
98+
"\n\n",
99+
]
100+
)
101+
102+
if len(all_apis) > 0:
103+
f.writelines(
104+
["## Discovery Artifact Change Summary:\n", "\n".join(all_apis), "\n"]
105+
)

0 commit comments

Comments
 (0)