Skip to content

Commit

Permalink
feat(changelog.json): implement changelog.json for python (#1841)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe authored Feb 7, 2023
1 parent 1493bd7 commit 52594b1
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 0 deletions.
37 changes: 37 additions & 0 deletions __snapshots__/python.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
exports['Python buildUpdates updates changelog.json if present 1'] = `
{
"entries": [
{
"changes": [
{
"type": "fix",
"sha": "845db1381b3d5d20151cad2588f85feb",
"message": "update dependency com.google.cloud:google-cloud-storage to v1.120.0",
"issues": [],
"scope": "deps"
},
{
"type": "chore",
"sha": "b3f8966b023b8f21ce127142aa91841c",
"message": "update a very important dep",
"issues": [],
"breakingChangeNote": "update a very important dep"
},
{
"type": "fix",
"sha": "08ca01180a91c0a1ba8992b491db9212",
"message": "update dependency com.google.cloud:google-cloud-spanner to v1.50.0",
"issues": [],
"scope": "deps"
}
],
"version": "0.1.0",
"language": "PYTHON",
"artifactName": "google-cloud-automl",
"id": "abc-123-efd-qwerty",
"createTime": "2023-01-05T16:42:33.446Z"
}
],
"updateTime": "2023-01-05T16:42:33.446Z"
}
`
48 changes: 48 additions & 0 deletions src/strategies/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base';
import {Update} from '../update';
import {Changelog} from '../updaters/changelog';
import {ChangelogJson} from '../updaters/changelog-json';
import {Version} from '../version';
import {SetupCfg} from '../updaters/python/setup-cfg';
import {SetupPy} from '../updaters/python/setup-py';
Expand All @@ -24,6 +25,8 @@ import {
PyProjectToml,
} from '../updaters/python/pyproject-toml';
import {PythonFileWithVersion} from '../updaters/python/python-file-with-version';
import {FileNotFoundError} from '../errors';
import {filterCommits} from '../util/filter-commits';

const CHANGELOG_SECTIONS = [
{type: 'feat', section: 'Features'},
Expand Down Expand Up @@ -133,6 +136,22 @@ export class Python extends BaseStrategy {
});
});

// If a machine readable changelog.json exists update it:
const artifactName = projectName ?? (await this.getNameFromSetupPy());
if (options.commits && artifactName) {
const commits = filterCommits(options.commits, this.changelogSections);
updates.push({
path: 'changelog.json',
createIfMissing: false,
updater: new ChangelogJson({
artifactName,
version,
commits,
language: 'PYTHON',
}),
});
}

return updates;
}

Expand All @@ -148,6 +167,35 @@ export class Python extends BaseStrategy {
}
}

protected async getNameFromSetupPy(): Promise<string | null> {
const ARTIFACT_NAME_REGEX = /name *= *['"](?<name>.*)['"](\r|\n|$)/;
const setupPyContents = await this.getSetupPyContents();
if (setupPyContents) {
const match = setupPyContents.match(ARTIFACT_NAME_REGEX);
if (match && match?.groups?.name) {
return match.groups.name;
}
}
return null;
}

protected async getSetupPyContents(): Promise<string | null> {
try {
return (
await this.github.getFileContentsOnBranch(
this.addPath('setup.py'),
this.targetBranch
)
).parsedContent;
} catch (e) {
if (e instanceof FileNotFoundError) {
return null;
} else {
throw e;
}
}
}

protected initialReleaseVersion(): Version {
return Version.parse('0.1.0');
}
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/strategies/python/changelog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"repository": "google-cloud-foo",
"entries": []
}
78 changes: 78 additions & 0 deletions test/fixtures/strategies/python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import io
import os

import setuptools

name = "google-cloud-automl"
description = "Cloud AutoML API client library"
version = "0.5.0"
release_status = "Development Status :: 3 - Alpha"
dependencies = [
"google-api-core[grpc] >= 1.14.0, < 2.0.0dev",
'enum34; python_version < "3.4"',
]
extras = {
"pandas": ["pandas>=0.24.0"],
"storage": ["google-cloud-storage >= 1.18.0, < 2.0.0dev"],
}

package_root = os.path.abspath(os.path.dirname(__file__))

readme_filename = os.path.join(package_root, "README.rst")
with io.open(readme_filename, encoding="utf-8") as readme_file:
readme = readme_file.read()

packages = [
package for package in setuptools.find_packages() if package.startswith("google")
]

namespaces = ["google"]
if "google.cloud" in packages:
namespaces.append("google.cloud")

setuptools.setup(
name=name,
version=version,
description=description,
long_description=readme,
author="Google LLC",
author_email="[email protected]",
license="Apache 2.0",
url="https://github.com/GoogleCloudPlatform/google-cloud-python",
classifiers=[
release_status,
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Operating System :: OS Independent",
"Topic :: Internet",
],
platforms="Posix; MacOS X; Windows",
packages=packages,
namespace_packages=namespaces,
install_requires=dependencies,
extras_require=extras,
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
include_package_data=True,
zip_safe=False,
)
67 changes: 67 additions & 0 deletions test/strategies/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ import {PyProjectToml} from '../../src/updaters/python/pyproject-toml';
import {SetupCfg} from '../../src/updaters/python/setup-cfg';
import {SetupPy} from '../../src/updaters/python/setup-py';
import {Changelog} from '../../src/updaters/changelog';
import {ChangelogJson} from '../../src/updaters/changelog-json';
import * as snapshot from 'snap-shot-it';

const sandbox = sinon.createSandbox();
const fixturesPath = './test/fixtures/strategies/python';

const UUID_REGEX =
/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g;
const ISO_DATE_REGEX =
/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]+Z/g; // 2023-01-05T16:42:33.446Z

const COMMITS = [
...buildMockConventionalCommit(
Expand Down Expand Up @@ -59,6 +67,9 @@ describe('Python', () => {
github,
component: 'google-cloud-automl',
});
sandbox
.stub(github, 'getFileContentsOnBranch')
.resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
const latestRelease = undefined;
const release = await strategy.buildReleasePullRequest(
Expand All @@ -74,6 +85,9 @@ describe('Python', () => {
github,
component: 'google-cloud-automl',
});
sandbox
.stub(github, 'getFileContentsOnBranch')
.resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
const latestRelease = {
tag: new TagName(Version.parse('0.123.4'), 'google-cloud-automl'),
Expand All @@ -94,6 +108,9 @@ describe('Python', () => {
github,
component: 'google-cloud-automl',
});
sandbox
.stub(github, 'getFileContentsOnBranch')
.resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
const latestRelease = undefined;
const release = await strategy.buildReleasePullRequest(
Expand Down Expand Up @@ -153,6 +170,9 @@ describe('Python', () => {
github,
component: 'google-cloud-automl',
});
sandbox
.stub(github, 'getFileContentsOnBranch')
.resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
sandbox
.stub(github, 'findFilesByFilenameAndRef')
.resolves(['src/version.py']);
Expand All @@ -164,5 +184,52 @@ describe('Python', () => {
const updates = release!.updates;
assertHasUpdate(updates, 'src/version.py', PythonFileWithVersion);
});

it('updates changelog.json if present', async () => {
const COMMITS = [
...buildMockConventionalCommit(
'fix(deps): update dependency com.google.cloud:google-cloud-storage to v1.120.0'
),
...buildMockConventionalCommit('chore: update deps'),
...buildMockConventionalCommit('chore!: update a very important dep'),
...buildMockConventionalCommit(
'fix(deps): update dependency com.google.cloud:google-cloud-spanner to v1.50.0'
),
...buildMockConventionalCommit('chore: update common templates'),
];
const strategy = new Python({
targetBranch: 'main',
github,
component: 'google-cloud-automl',
});
sandbox.stub(github, 'findFilesByFilenameAndRef').resolves([]);
const getFileContentsStub = sandbox.stub(
github,
'getFileContentsOnBranch'
);
getFileContentsStub
.withArgs('changelog.json', 'main')
.resolves(buildGitHubFileContent(fixturesPath, 'changelog.json'));
getFileContentsStub
.withArgs('setup.py', 'main')
.resolves(buildGitHubFileContent(fixturesPath, 'setup.py'));
const latestRelease = undefined;
const release = await strategy.buildReleasePullRequest(
COMMITS,
latestRelease
);
const updates = release!.updates;
assertHasUpdate(updates, 'CHANGELOG.md', Changelog);
const update = assertHasUpdate(updates, 'changelog.json', ChangelogJson);
const newContent = update.updater.updateContent(
JSON.stringify({entries: []})
);
snapshot(
newContent
.replace(/\r\n/g, '\n') // make newline consistent regardless of OS.
.replace(UUID_REGEX, 'abc-123-efd-qwerty')
.replace(ISO_DATE_REGEX, '2023-01-05T16:42:33.446Z')
);
});
});
});

0 comments on commit 52594b1

Please sign in to comment.