Skip to content

Commit

Permalink
Merge branch 'master' into IOBP-496-fe-rimozione-codice-legacy-relati…
Browse files Browse the repository at this point in the history
…vo-a-sicilia-vola
  • Loading branch information
mastro993 authored Jan 31, 2024
2 parents a2ac1d5 + 585f6d4 commit 77ed9f9
Show file tree
Hide file tree
Showing 30 changed files with 589 additions and 1,210 deletions.
6 changes: 3 additions & 3 deletions Dangerfile.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Import custom DangerJS rules.
// See http://danger.systems/js
import { DangerDSLType } from "danger/distribution/dsl/DangerDSL";
import { commentPrWithTicketsInfo } from "./scripts/ts/danger/commentPrWithTicketsInfo";
import { updatePrTitleForChangelog } from "./scripts/ts/danger/updatePrTitleForChangelog";
import { getTicketsFromTitle } from "./scripts/ts/danger/utils/titleParser";
import { commentPrWithTicketsInfo } from "./scripts/ts/danger/commentPr";
import { updatePrTitleForChangelog } from "./scripts/ts/danger/updatePrTitle";
import { getTicketsFromTitle } from "./scripts/ts/common/jiraTicket";

declare const danger: DangerDSLType;

Expand Down
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "2.52.0-rc.0",
"io_backend_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_backend.yaml",
"io_public_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_public.yaml",
"io_content_specs": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.29/definitions.yml",
"io_content_specs": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.30/definitions.yml",
"io_cgn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_cgn.yaml",
"io_cgn_merchants_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.29.2-RELEASE/api_cgn_operator_search.yaml",
"api_fci": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_io_sign.yaml",
Expand All @@ -12,9 +12,9 @@
"io_consumed_pn_specs": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/openapi/consumed/api-piattaforma-notifiche.yaml",
"api_cdc": "assets/CdcSwagger.yml",
"pagopa_api": "assets/paymentManager/spec.json",
"pagopa_api_walletv2": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.29/bonus/specs/bpd/pm/walletv2.json",
"pagopa_cobadge_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.29/pagopa/cobadge/abi_definitions.yml",
"pagopa_privative_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.29/pagopa/privative/definitions.yml",
"pagopa_api_walletv2": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.30/bonus/specs/bpd/pm/walletv2.json",
"pagopa_cobadge_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.30/pagopa/cobadge/abi_definitions.yml",
"pagopa_privative_configuration": "https://raw.githubusercontent.com/pagopa/io-services-metadata/1.0.30/pagopa/privative/definitions.yml",
"idpay_api": "https://raw.githubusercontent.com/pagopa/cstar-infrastructure/v6.9.1/src/domains/idpay-app/api/idpay_appio_full/openapi.appio.full.yml",
"lollipop_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/api_lollipop_first_consumer.yaml",
"fast_login_api": "https://raw.githubusercontent.com/pagopa/io-backend/v13.25.1-RELEASE/openapi/generated/api_fast_login.yaml",
Expand Down Expand Up @@ -259,7 +259,6 @@
"babel-preset-react-native": "^4.0.1",
"chalk": "^2.4.1",
"danger": "^10.3.0",
"danger-plugin-digitalcitizenship": "^0.3.1",
"eslint": "^8.6.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-functional": "^4.1.1",
Expand All @@ -281,7 +280,6 @@
"node-fetch": "^2.6.7",
"npm-run-all": "^4.1.3",
"patch-package": "6.5.1",
"pivotaljs": "^1.0.3",
"plist": "^3.0.5",
"postinstall-postinstall": "^1.0.0",
"prettier": "2.8.8",
Expand Down Expand Up @@ -315,7 +313,7 @@
},
"standard-version": {
"scripts": {
"postchangelog": "node scripts/changelog/add_pivotal_stories.js"
"postchangelog": "node scripts/changelog/add_jira_stories.js"
}
}
}
26 changes: 0 additions & 26 deletions patches/danger-plugin-digitalcitizenship+0.3.1.patch

This file was deleted.

6 changes: 0 additions & 6 deletions patches/patches.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ Updated on **29/08/2022**

- This patch is going to fix a gradle issue that breaks the compile on android platform, due to gradle imcompatibility

### danger-plugin-digitalcitizenship+0.3.1
Created on **06/08/2020**

#### Reason:
- Recognizes the ids of pivotal stories even if they are not at the beginning of the line

### react-native-push-notification+7.3.1
Created on **10/05/2021**

Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,12 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fs = require("fs-extra");
const Pivotal = require("pivotaljs");
const pivotal = new Pivotal();

const jiraTicketBaseUrl = "https://pagopa.atlassian.net/browse/";

/**
* Skip the use of API to find the story url if the url is already retrieved (contains pivotaltracker.com)
* or the id length is < 9 (not a pivotal id)
* @param id
* @param url
* @return {*|boolean}
*/
function skipStoryCheck(id, url) {
return url.includes("pivotaltracker.com") || id.length < 9;
}

async function replacePivotalUrl(match, storyId, url) {
const sameUrl = `[${storyId}](${url})`;
try {
// avoid to use the api if story is already linked to pivotal
if (skipStoryCheck(storyId, url)) {
return sameUrl;
}
// try to get the story with the specified id
const story = await getStory(storyId.substr(1));

// if the story doesn't exists (eg: story deleted) remove the markdown link
return story.url !== undefined
? `[${storyId}](${story.url})`
: `${storyId}`;
} catch (err) {
return sameUrl;
}
}

async function addJiraUrl(match, ticketKeys) {
return `[${ticketKeys
.split(",")
// eslint-disable-next-line sonarjs/no-nested-template-literals
.map(x => `[${x}](${new URL(x, jiraTicketBaseUrl).toString()})`)}]`;
}

Expand All @@ -47,7 +17,7 @@ async function replaceJiraStories(content) {
}

/**
* replace the changelog content by removing the repetition of "closes [#idPivotalorJiraStory](url)"
* replace the changelog content by removing the repetition of "closes [#idJiraStory](url)"
* @param content
* @return {Promise<string>}
*/
Expand All @@ -61,8 +31,6 @@ async function addTasksUrls() {
const rawChangelog = fs.readFileSync("CHANGELOG.md").toString("utf8");

const updatedChangelog = await [
// Add pivotal stories url
replacePivotalStories,
// Add jira ticket url
replaceJiraStories,
// clean closes
Expand All @@ -75,14 +43,6 @@ async function addTasksUrls() {
fs.writeFileSync("CHANGELOG.md", updatedChangelog);
}

async function replacePivotalStories(content) {
// identify the pattern [#XXXXX](url) for markdown link
const pivotalTagRegex = /\[(#\d+)\]\(([a-zA-z/\d\-@:%._+~#=]+)\)/g;

// check for all the matches if is a pivotal story and update the url
return await replaceAsync(content, pivotalTagRegex, replacePivotalUrl);
}

/**
* A custom method created to allows the replace in a string using an async function
* @param str
Expand All @@ -94,29 +54,18 @@ async function replaceAsync(str, regex, asyncFn) {
const promises = [];
str.replace(regex, (match, ...args) => {
const promise = asyncFn(match, ...args);
// eslint-disable-next-line functional/immutable-data
promises.push(promise);
});
const data = await Promise.all(promises);
// eslint-disable-next-line functional/immutable-data
return str.replace(regex, () => data.shift());
}

/**
* Wrap the getStory callback with a promise
* @param storyId
* @return {Promise<Pivotal.Story>}
*/
getStory = storyId =>
new Promise((resolve, reject) => {
pivotal.getStory(storyId, (err, story) => {
if (err) {
return reject(err);
}
resolve(story);
});
});

// Execute the script to find the pivotal stories and jira ticket id in order to associate
// Execute the script to find jira ticket id in order to associate
// the right url in the changelog
addTasksUrls()
// eslint-disable-next-line no-console
.then(() => console.log("done"))
// eslint-disable-next-line no-console
.catch(ex => console.log(ex));
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { flow, pipe } from "fp-ts/lib/function";
import * as TE from "fp-ts/lib/TaskEither";
import { Errors } from "io-ts";
import fetch from "node-fetch";
import { RemoteJiraTicket } from "./types";
import * as O from "fp-ts/lib/Option";
import { JiraTicketRetrievalResults, RemoteJiraTicket } from "./types";

const jiraOrgBaseUrl = "https://pagopa.atlassian.net/rest/api/3/issue/";
export const jiraTicketBaseUrl = "https://pagopa.atlassian.net/browse/";
Expand Down Expand Up @@ -58,3 +59,39 @@ export const getJiraTickets = async (
jiraIds: ReadonlyArray<string>
): Promise<ReadonlyArray<E.Either<Errors | Error, RemoteJiraTicket>>> =>
await Promise.all(jiraIds.map(getJiraTicket));

const jiraRegex = /\[([A-Z0-9]+-\d+(,[A-Z0-9]+-\d+)*)]\s.+/;

/**
* Extracts Jira ticket ids from the pr title (if any)
* @param title
*/
export const getJiraIdFromPrTitle = (
title: string
): O.Option<ReadonlyArray<string>> =>
pipe(
title.match(jiraRegex),
O.fromNullable,
O.map(a => a[1].split(","))
);

/**
* Try to retrieve Jira tickets from pr title
* and transforms them into {@link GenericTicket}
* @param title
*/
export const getTicketsFromTitle = async (
title: string
): Promise<JiraTicketRetrievalResults> => {
const maybeJiraId = await pipe(
getJiraIdFromPrTitle(title),
O.map(getJiraTickets),
O.toUndefined
);

if (maybeJiraId) {
return maybeJiraId;
} else {
return [E.left(new Error("No Jira ticket found"))];
}
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as t from "io-ts";
import * as E from "fp-ts/lib/Either";
import { Errors } from "io-ts";

const JiraIssueType = t.keyof({
Epic: null,
Expand All @@ -12,28 +14,28 @@ const JiraIssueType = t.keyof({

export type JiraIssueType = t.TypeOf<typeof JiraIssueType>;

const IssueType = t.interface({
const IssueType = t.type({
name: JiraIssueType,
subtask: t.boolean
});

const Project = t.interface({
const Project = t.type({
id: t.string,
key: t.string,
name: t.string
});

const FieldsR = t.interface({
const FieldsR = t.type({
issuetype: IssueType,
project: Project,
labels: t.array(t.string),
summary: t.string
});

const FieldsP = t.partial({
parent: t.interface({
parent: t.type({
key: t.string,
fields: t.interface({
fields: t.type({
summary: t.string,
issuetype: IssueType
})
Expand All @@ -53,3 +55,11 @@ export const RemoteJiraTicket = t.interface({
});

export type RemoteJiraTicket = t.TypeOf<typeof RemoteJiraTicket>;

export type RemoteJiraTicketParent = Required<
t.TypeOf<typeof FieldsP>
>["parent"];

export type JiraTicketRetrievalResults = ReadonlyArray<
E.Either<Error | Errors, RemoteJiraTicket>
>;
39 changes: 0 additions & 39 deletions scripts/ts/common/ticket/pivotal/types.d.ts

This file was deleted.

Loading

0 comments on commit 77ed9f9

Please sign in to comment.