release-please
Version:
generate release PRs based on the conventionalcommits.org spec
281 lines • 11.2 kB
JavaScript
// Copyright 2023 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
//
// http://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.
Object.defineProperty(exports, "__esModule", { value: true });
exports.JavaYoshiMonoRepo = void 0;
const versions_manifest_1 = require("../updaters/java/versions-manifest");
const version_1 = require("../version");
const changelog_1 = require("../updaters/changelog");
const changelog_json_1 = require("../updaters/changelog-json");
const commit_split_1 = require("../util/commit-split");
const composite_1 = require("../updaters/composite");
const errors_1 = require("../errors");
const java_1 = require("./java");
const java_update_1 = require("../updaters/java/java-update");
const filter_commits_1 = require("../util/filter-commits");
class JavaYoshiMonoRepo extends java_1.Java {
/**
* Override this method to post process commits
* @param {ConventionalCommit[]} commits parsed commits
* @returns {ConventionalCommit[]} modified commits
*/
async postProcessCommits(commits) {
if (commits.length === 0) {
// For Java commits, push a fake commit so we force a
// SNAPSHOT release
commits.push({
type: 'fake',
bareMessage: 'fake commit',
message: 'fake commit',
breaking: false,
scope: null,
notes: [],
files: [],
references: [],
sha: 'fake',
});
}
return commits;
}
async needsSnapshot() {
return versions_manifest_1.VersionsManifest.needsSnapshot((await this.getVersionsContent()).parsedContent);
}
async buildVersionsMap() {
this.versionsContent = await this.getVersionsContent();
return versions_manifest_1.VersionsManifest.parseVersions(this.versionsContent.parsedContent);
}
async getVersionsContent() {
if (!this.versionsContent) {
try {
this.versionsContent = await this.github.getFileContentsOnBranch(this.addPath('versions.txt'), this.targetBranch);
}
catch (err) {
if (err instanceof errors_1.GitHubAPIError) {
throw new errors_1.MissingRequiredFileError(this.addPath('versions.txt'), JavaYoshiMonoRepo.name, `${this.repository.owner}/${this.repository.repo}`);
}
throw err;
}
}
return this.versionsContent;
}
async buildUpdates(options) {
const updates = [];
const version = options.newVersion;
const versionsMap = options.versionsMap;
updates.push({
path: this.addPath('versions.txt'),
createIfMissing: false,
cachedFileContents: this.versionsContent,
updater: new versions_manifest_1.VersionsManifest({
version,
versionsMap,
}),
});
const pomFilesSearch = this.github.findFilesByFilenameAndRef('pom.xml', this.targetBranch, this.path);
const buildFilesSearch = this.github.findFilesByFilenameAndRef('build.gradle', this.targetBranch, this.path);
const dependenciesSearch = this.github.findFilesByFilenameAndRef('dependencies.properties', this.targetBranch, this.path);
const readmeFilesSearch = this.github.findFilesByFilenameAndRef('README.md', this.targetBranch, this.path);
const pomFiles = await pomFilesSearch;
pomFiles.forEach(path => {
updates.push({
path: this.addPath(path),
createIfMissing: false,
updater: new java_update_1.JavaUpdate({
version,
versionsMap,
isSnapshot: options.isSnapshot,
}),
});
});
const buildFiles = await buildFilesSearch;
buildFiles.forEach(path => {
updates.push({
path: this.addPath(path),
createIfMissing: false,
updater: new java_update_1.JavaUpdate({
version,
versionsMap,
isSnapshot: options.isSnapshot,
}),
});
});
const dependenciesFiles = await dependenciesSearch;
dependenciesFiles.forEach(path => {
updates.push({
path: this.addPath(path),
createIfMissing: false,
updater: new java_update_1.JavaUpdate({
version,
versionsMap,
isSnapshot: options.isSnapshot,
}),
});
});
const readmeFiles = await readmeFilesSearch;
readmeFiles.forEach(path => {
updates.push({
path: this.addPath(path),
createIfMissing: false,
updater: new java_update_1.JavaUpdate({
version,
versionsMap,
isSnapshot: options.isSnapshot,
}),
});
});
this.extraFiles.forEach(extraFile => {
if (typeof extraFile === 'object') {
return;
}
updates.push({
path: extraFile,
createIfMissing: false,
updater: new java_update_1.JavaUpdate({
version,
versionsMap,
isSnapshot: options.isSnapshot,
}),
});
});
if (!options.isSnapshot) {
updates.push({
path: this.addPath(this.changelogPath),
createIfMissing: true,
updater: new changelog_1.Changelog({
version,
changelogEntry: options.changelogEntry,
}),
});
// Bail early if the repository has no root changelog.json.
// This file is used to opt into machine readable commits.
const hasChangelogJson = await this.hasChangelogJson();
if (hasChangelogJson && options.commits) {
const changelogUpdates = [];
const cs = new commit_split_1.CommitSplit({
includeEmpty: false,
});
const splitCommits = cs.split((0, filter_commits_1.filterCommits)(options.commits, this.changelogSections));
for (const path of Object.keys(splitCommits)) {
const repoMetadata = await this.getRepoMetadata(path);
const artifactName = repoMetadata
? repoMetadata['distribution_name']
: null;
if (repoMetadata && artifactName) {
this.logger.info(`Found artifact ${artifactName} for ${path}`);
changelogUpdates.push(new changelog_json_1.ChangelogJson({
artifactName,
version,
// We filter out "chore:" commits, to reduce noise in the upstream
// release notes. We will only show a product release note entry
// if there has been a substantial change, such as a fix or feature.
commits: splitCommits[path],
language: 'JAVA',
}));
}
}
updates.push({
path: 'changelog.json',
createIfMissing: false,
updater: new composite_1.CompositeUpdater(...changelogUpdates),
});
}
}
return updates;
}
async hasChangelogJson() {
try {
const content = await this.github.getFileContentsOnBranch('changelog.json', this.targetBranch);
return !!content;
}
catch (e) {
if (e instanceof errors_1.FileNotFoundError)
return false;
else
throw e;
}
}
async getRepoMetadata(path) {
try {
const content = await this.github.getFileContentsOnBranch(this.addPath(`${path}/.repo-metadata.json`), this.targetBranch);
return content ? JSON.parse(content.parsedContent) : null;
}
catch (e) {
if (e instanceof errors_1.FileNotFoundError)
return null;
else
throw e;
}
}
async updateVersionsMap(versionsMap, conventionalCommits) {
let isPromotion = false;
const modifiedCommits = [];
for (const commit of conventionalCommits) {
if (isPromotionCommit(commit)) {
isPromotion = true;
modifiedCommits.push({
...commit,
notes: commit.notes.filter(note => !isPromotionNote(note)),
});
}
else {
modifiedCommits.push(commit);
}
}
for (const versionKey of versionsMap.keys()) {
const version = versionsMap.get(versionKey);
if (!version) {
this.logger.warn(`didn't find version for ${versionKey}`);
continue;
}
if (isPromotion && isStableArtifact(versionKey)) {
versionsMap.set(versionKey, version_1.Version.parse('1.0.0'));
}
else {
const newVersion = await this.versioningStrategy.bump(version, modifiedCommits);
versionsMap.set(versionKey, newVersion);
}
}
return versionsMap;
}
initialReleaseVersion() {
return version_1.Version.parse('0.1.0');
}
}
exports.JavaYoshiMonoRepo = JavaYoshiMonoRepo;
const VERSIONED_ARTIFACT_REGEX = /^.*-(v\d+[^-]*)$/;
const VERSION_REGEX = /^v\d+(.*)$/;
/**
* Returns true if the artifact should be considered stable
* @param artifact name of the artifact to check
*/
function isStableArtifact(artifact) {
const match = artifact.match(VERSIONED_ARTIFACT_REGEX);
if (!match) {
// The artifact does not have a version qualifier at the end
return true;
}
const versionMatch = match[1].match(VERSION_REGEX);
if (versionMatch && versionMatch[1]) {
// The version is not stable (probably alpha/beta/rc)
return false;
}
return true;
}
function isPromotionCommit(commit) {
return commit.notes.some(isPromotionNote);
}
function isPromotionNote(note) {
return note.title === 'RELEASE AS' && note.text === '1.0.0';
}
//# sourceMappingURL=java-yoshi-mono-repo.js.map
;