Skip to content

Commit

Permalink
Merge branch 'develop' into fix/ap-660
Browse files Browse the repository at this point in the history
  • Loading branch information
montelaidev authored Nov 22, 2024
2 parents ece7d0f + e3c6b29 commit 610cf1f
Show file tree
Hide file tree
Showing 271 changed files with 16,099 additions and 1,865 deletions.
24 changes: 24 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,19 @@ workflows:
requires:
- prep-build-ts-migration-dashboard

rerun-from-failed:
when:
condition:
equal: ["<< pipeline.schedule.name >>", "rerun-from-failed"]
jobs:
- prep-deps
- rerun-workflows-from-failed:
filters:
branches:
only: develop
requires:
- prep-deps

locales_only:
when:
matches:
Expand Down Expand Up @@ -930,6 +943,17 @@ jobs:
paths:
- development/ts-migration-dashboard/build/final

rerun-workflows-from-failed:
executor: node-browsers-small
steps:
- run: *shallow-git-clone-and-enable-vnc
- run: sudo corepack enable
- attach_workspace:
at: .
- run:
name: Rerun workflows from failed
command: yarn ci-rerun-from-failed

test-yarn-dedupe:
executor: node-browsers-small
steps:
Expand Down
211 changes: 211 additions & 0 deletions .circleci/scripts/rerun-ci-workflow-from-failed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
const CIRCLE_TOKEN = process.env.API_V2_TOKEN;

interface Actor {
login: string;
avatar_url: string | null;
}

interface Trigger {
received_at: string;
type: string;
actor: Actor;
}

interface VCS {
origin_repository_url: string;
target_repository_url: string;
revision: string;
provider_name: string;
branch: string;
}

interface WorkflowItem {
id: string;
errors: string[];
project_slug: string;
updated_at: string;
number: number;
state: string;
created_at: string;
trigger: Trigger;
vcs: VCS;
}

interface CircleCIResponse {
next_page_token: string | null;
items: WorkflowItem[];
}

interface WorkflowStatusItem {
pipeline_id: string;
id: string;
name: string;
project_slug: string;
tag?: string;
status: string;
started_by: string;
pipeline_number: number;
created_at: string;
stopped_at: string;
}

interface WorkflowStatusResponse {
next_page_token: string | null;
items: WorkflowStatusItem[];
}

/**
* Fetches the last 20 CircleCI workflows for the given branch.
* Note: the API returns the first 20 workflows by default.
* If we wanted to get older workflows, we would need to use the 'page-token' we would get in the first response
* and perform a subsequent request with the 'page-token' parameter.
* This seems unnecessary as of today, as the amount of daily PRs merged to develop is not that high.
*
* @returns {Promise<WorkflowItem[]>} A promise that resolves to an array of workflow items.
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails.
*/
async function getCircleCiWorkflowsByBranch(branch: string): Promise<WorkflowItem[]> {
if (!CIRCLE_TOKEN) {
throw new Error('CircleCI token is not defined');
}

const url = `https://circleci.com/api/v2/project/github/${process.env.CIRCLE_PROJECT_USERNAME}/${process.env.CIRCLE_PROJECT_REPONAME}/pipeline?branch=${branch}`;
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
};

try {
const response = await fetch(url, options);
if (!response.ok) {
const errorBody = await response.text();
console.error('HTTP error response:', errorBody);
throw new Error(`HTTP error! status: ${response.status}`);
}
const body = await response.json();
console.log('Circle Ci workflows fetched successfully!');
return body.items;
} catch (error) {
console.error('Error:', error);
throw error;
}
}

/**
* Fetches the status of a specific CircleCI workflow.
*
* @param {string} workflowId - The ID of the workflow to fetch the status for.
* @returns {Promise<WorkflowStatusResponse>} A promise that resolves to the workflow status response.
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails.
*/
async function getWorkflowStatusById(workflowId: string): Promise<WorkflowStatusResponse> {
if (!CIRCLE_TOKEN) {
throw new Error('CircleCI token is not defined');
}

const url = `https://circleci.com/api/v2/pipeline/${workflowId}/workflow`;
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
};

try {
console.log(`Fetching workflow ${workflowId}...`);

const response = await fetch(url, options);
if (!response.ok) {
const errorBody = await response.text();
console.error('HTTP error response:', errorBody);
throw new Error(`HTTP error! status: ${response.status}`);
}
const workflowStatus = await response.json();

console.log(`Number of runs: ${workflowStatus.items.length}`);
console.log(`Workflow status from last run: ${workflowStatus.items[0].status}`);

return workflowStatus;

} catch (error) {
console.error('Error:', error);
throw error;
}
}

/**
* Reruns a CircleCI workflow by its ID.
*
* @param {string} workflowId - The ID of the workflow to rerun.
* @throws Will throw an error if the CircleCI token is not defined or if the HTTP request fails.
*/
async function rerunWorkflowById(workflowId: string) {
if (!CIRCLE_TOKEN) {
throw new Error('CircleCI token is not defined');
}

const url = `https://circleci.com/api/v2/workflow/${workflowId}/rerun`;
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Circle-Token': CIRCLE_TOKEN,
},
body: JSON.stringify({
enable_ssh: false,
from_failed: true,
sparse_tree: false, // mutually exclusive with the from_failed parameter
})
};

try {
console.log(`Rerunning workflow ${workflowId}...`);
const response = await fetch(url, options);
if (!response.ok) {
const errorBody = await response.text();
console.error('HTTP error response:', errorBody);
throw new Error(`HTTP error! status: ${response.status}`);
}
const body = await response.json();
console.log('Workflow rerun successfully!');
console.log(body);
} catch (error) {
console.error('Error:', error);
}
}

/**
* Re-runs failed CircleCI workflows from develop branch.
* The workflow will only be re-runed if:
* 1. It has the status of 'failed'
* 2. It has only been run once
* 3. It is among the most recent 20 workflows
* 4. It was triggered by the 'github-merge-queue[bot]' user
*
* @throws Will throw an error if fetching the workflows or re-running a workflow fails.
*/
async function rerunFailedWorkflowsFromDevelop() {
console.log('Getting Circle Ci workflows from develop branch...');
const workflows = await getCircleCiWorkflowsByBranch('develop');

console.log('Assessing if any of the workflows needs to be rerun...');
for (const item of workflows) {
if (item.trigger.actor.login === 'github-merge-queue[bot]') {
const workflowStatus = await getWorkflowStatusById(item.id);

if (workflowStatus.items.length === 1 && workflowStatus.items[0].status === 'failed') {
await rerunWorkflowById(workflowStatus.items[0].id);
console.log(`Rerun workflow with ID: ${workflowStatus.items[0].id}`);
}
}
}
console.log('Task completed successfully!');
}

rerunFailedWorkflowsFromDevelop()
.catch((error) => {
console.error(error);
process.exitCode = 1;
});
7 changes: 7 additions & 0 deletions .storybook/test-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,13 @@ const state = {
decimals: 18,
},
],
tokenBalances: {
'0x64a845a5b02460acf8a3d84503b0d68d028b4bb4': {
'0x1': {
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': '0x25e4bc',
},
},
},
allDetectedTokens: {
'0xaa36a7': {
'0x9d0ba4ddac06032527b140912ec808ab9451b788': [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
diff --git a/dist/assetsUtil.cjs b/dist/assetsUtil.cjs
index 48571b8c1b78e94d88e1837e986b5f8735ac651b..61246f51500c8cab48f18296a73629fb73454caa 100644
--- a/dist/assetsUtil.cjs
+++ b/dist/assetsUtil.cjs
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }
exports.fetchTokenContractExchangeRates = exports.reduceInBatchesSerially = exports.divideIntoBatches = exports.ethersBigNumberToBN = exports.addUrlProtocolPrefix = exports.getFormattedIpfsUrl = exports.getIpfsCIDv1AndPath = exports.removeIpfsProtocolPrefix = exports.isTokenListSupportedForNetwork = exports.isTokenDetectionSupportedForNetwork = exports.SupportedStakedBalanceNetworks = exports.SupportedTokenDetectionNetworks = exports.formatIconUrlWithProxy = exports.formatAggregatorNames = exports.hasNewCollectionFields = exports.compareNftMetadata = exports.TOKEN_PRICES_BATCH_SIZE = void 0;
const controller_utils_1 = require("@metamask/controller-utils");
const utils_1 = require("@metamask/utils");
@@ -233,7 +234,7 @@ async function getIpfsCIDv1AndPath(ipfsUrl) {
const index = url.indexOf('/');
const cid = index !== -1 ? url.substring(0, index) : url;
const path = index !== -1 ? url.substring(index) : undefined;
- const { CID } = await import("multiformats");
+ const { CID } = _interopRequireWildcard(require("multiformats"));
// We want to ensure that the CID is v1 (https://docs.ipfs.io/concepts/content-addressing/#identifier-formats)
// because most cid v0s appear to be incompatible with IPFS subdomains
return {
diff --git a/dist/token-prices-service/codefi-v2.mjs b/dist/token-prices-service/codefi-v2.mjs
index e7eaad2cfa8b233c4fd42a51f745233a1cc5c387..bf8ec7819f678c2f185d6a85d7e3ea81f055a309 100644
--- a/dist/token-prices-service/codefi-v2.mjs
+++ b/dist/token-prices-service/codefi-v2.mjs
@@ -12,8 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
var _CodefiTokenPricesServiceV2_tokenPricePolicy;
import { handleFetch } from "@metamask/controller-utils";
import { hexToNumber } from "@metamask/utils";
-import $cockatiel from "cockatiel";
-const { circuitBreaker, ConsecutiveBreaker, ExponentialBackoff, handleAll, retry, wrap, CircuitState } = $cockatiel;
+import { circuitBreaker, ConsecutiveBreaker, ExponentialBackoff, handleAll, retry, wrap, CircuitState } from "cockatiel"
/**
* The list of currencies that can be supplied as the `vsCurrency` parameter to
* the `/spot-prices` endpoint, in lowercase form.
diff --git a/dist/TokenDetectionController.cjs b/dist/TokenDetectionController.cjs
index 8fd5efde7a3c24080f8a43f79d10300e8c271245..a3c334ac7dd2e5698e6b54a73491b7145c2a9010 100644
--- a/dist/TokenDetectionController.cjs
+++ b/dist/TokenDetectionController.cjs
@@ -250,17 +250,20 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
}
});
this.messagingSystem.subscribe('AccountsController:selectedEvmAccountChange',
- // TODO: Either fix this lint violation or explain why it's necessary to ignore.
- // eslint-disable-next-line @typescript-eslint/no-misused-promises
- async (selectedAccount) => {
- const isSelectedAccountIdChanged = __classPrivateFieldGet(this, _TokenDetectionController_selectedAccountId, "f") !== selectedAccount.id;
- if (isSelectedAccountIdChanged) {
- __classPrivateFieldSet(this, _TokenDetectionController_selectedAccountId, selectedAccount.id, "f");
- await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this, {
- selectedAddress: selectedAccount.address,
- });
- }
- });
+ // TODO: Either fix this lint violation or explain why it's necessary to ignore.
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
+ async (selectedAccount) => {
+ const { networkConfigurationsByChainId } = this.messagingSystem.call('NetworkController:getState');
+ const chainIds = Object.keys(networkConfigurationsByChainId);
+ const isSelectedAccountIdChanged = __classPrivateFieldGet(this, _TokenDetectionController_selectedAccountId, "f") !== selectedAccount.id;
+ if (isSelectedAccountIdChanged) {
+ __classPrivateFieldSet(this, _TokenDetectionController_selectedAccountId, selectedAccount.id, "f");
+ await __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_restartTokenDetection).call(this, {
+ selectedAddress: selectedAccount.address,
+ chainIds,
+ });
+ }
+ });
}, _TokenDetectionController_stopPolling = function _TokenDetectionController_stopPolling() {
if (__classPrivateFieldGet(this, _TokenDetectionController_intervalId, "f")) {
clearInterval(__classPrivateFieldGet(this, _TokenDetectionController_intervalId, "f"));
Loading

0 comments on commit 610cf1f

Please sign in to comment.