Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9f69308
(fix) Hotfix for duplicated entries for pools for epoch 568 on mainne…
Ciabas Jul 7, 2025
c8e01fd
(fix) Hotfix for calculations on SPOs on gov actions
Ciabas Jul 8, 2025
22cdc6c
Merge pull request #3876 from IntersectMBO/duplicates-in-pool-stat-table
aaboyle878 Jul 8, 2025
9c7f14a
Merge pull request #3878 from IntersectMBO/calculates-for-SPOs-on-gov…
aaboyle878 Jul 8, 2025
897a21a
(fix#3879): broken parameters on Live Voting page
Ciabas Jul 9, 2025
fc4ae54
Revert "(fix) Hotfix for calculations on SPOs on gov actions"
Ciabas Jul 9, 2025
ed0e029
Revert "(fix) Hotfix for duplicated entries for pools for epoch 568 o…
Ciabas Jul 9, 2025
9779d9e
Merge pull request #3885 from IntersectMBO/revert-3876-duplicates-in-…
Ciabas Jul 10, 2025
e9ebbde
Merge pull request #3884 from IntersectMBO/revert-3878-calculates-for…
Ciabas Jul 10, 2025
f72812a
(fix#3881): add not voted to SPOs counting on gov actions
Ciabas Jul 9, 2025
0f4d315
(fix#3881): calculate SPO % based on the whole group (yes/no/abstain/…
Ciabas Jul 10, 2025
b8b6687
Merge pull request #3889 from IntersectMBO/3881-update-how-we-display…
Ciabas Jul 10, 2025
1097c02
Merge pull request #3883 from IntersectMBO/3879-parameters-page-on-li…
Ciabas Jul 11, 2025
52692b5
(fix) Add SPOs not voted values to gov actions
Ciabas Jul 8, 2025
170e7e7
Merge pull request #3880 from IntersectMBO/add-SPOs-not-voted-to-gov-…
Ciabas Jul 15, 2025
e792251
chore: disable hardfork proposal test
kneerose Jul 15, 2025
56c5a89
fix: update governance actions test to ensure correct navigation and …
kneerose Jul 15, 2025
7a4d396
Merge pull request #3891 from IntersectMBO/chore/disable-hardfork-pro…
kneerose Jul 16, 2025
85d80e7
Merge pull request #3892 from IntersectMBO/fix/access-gov-action-page…
kneerose Jul 16, 2025
bd0f7ff
chore: update GovTool to v2.0.29
github-actions[bot] Jul 16, 2025
bdab6b6
Merge pull request #3893 from IntersectMBO/chore/update-govtool-to-v2…
Ciabas Jul 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ changes.

## [Unreleased]

### Added

### Fixed

### Changed

### Removed

## [v2.0.29](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.29) 2025-07-16


### Added

- Preserve maintenance ending banner state on the wallet connection change [Issue 3681](https://github.com/IntersectMBO/govtool/issues/3681)
Expand Down
2 changes: 1 addition & 1 deletion govtool/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.23/x/vva-be/build/vva-be/vva-be /usr/local/bin
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.29/x/vva-be/build/vva-be/vva-be /usr/local/bin
2 changes: 1 addition & 1 deletion govtool/backend/Dockerfile.qovery
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.23/x/vva-be/build/vva-be/vva-be /usr/local/bin
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.29/x/vva-be/build/vva-be/vva-be /usr/local/bin

# Expose the necessary port
EXPOSE 9876
Expand Down
2 changes: 1 addition & 1 deletion govtool/backend/vva-be.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 3.6
name: vva-be
version: 2.0.23
version: 2.0.29

-- A short (one-line) description of the package.
-- synopsis:
Expand Down
4 changes: 2 additions & 2 deletions govtool/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion govtool/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@govtool/frontend",
"private": true,
"version": "2.0.23",
"version": "2.0.29",
"type": "module",
"scripts": {
"build": "vite build",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ type CCMember = {
newExpirationEpoch?: number;
};

function isArrayOfStrings(value: unknown): value is string[] {
return (
Array.isArray(value) && value.every((item) => typeof item === "string")
);
}

export const GovernanceActionNewCommitteeDetailsTabContent = ({
details,
}: Pick<ProposalData, "details">) => {
Expand All @@ -38,6 +44,10 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
newExpirationEpoch: member.newExpirationEpoch,
}));

const membersToBeRemoved = isArrayOfStrings(details?.membersToBeRemoved)
? details.membersToBeRemoved
: [];

return (
<Box>
{membersToBeAdded.length > 0 && (
Expand Down Expand Up @@ -78,7 +88,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
))}
</Box>
)}
{(details?.membersToBeRemoved as string[]).length > 0 && (
{membersToBeRemoved.length > 0 && (
<Box mb="32px">
<Typography
sx={{
Expand All @@ -93,8 +103,8 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({
>
{t("govActions.membersToBeRemoved")}
</Typography>
{(details?.membersToBeRemoved as string[]).map((hash) => (
<Box display="flex" flexDirection="row">
{membersToBeRemoved.map((hash) => (
<Box display="flex" flexDirection="row" key={hash}>
<Typography
sx={{
fontSize: 16,
Expand Down
44 changes: 34 additions & 10 deletions govtool/frontend/src/components/molecules/VotesSubmitted.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export const VotesSubmitted = ({
dRepAbstainVotes + (networkTotalStake?.alwaysAbstainVotingPower ?? 0);

// TODO: Move this logic to backend

// DRep votes
const dRepYesVotesPercentage = totalStakeControlledByDReps
? (dRepYesVotes / totalStakeControlledByDReps) * 100
: undefined;
Expand All @@ -108,25 +110,45 @@ export const VotesSubmitted = ({
const dRepNotVotedVotesPercentage =
100 - (dRepYesVotesPercentage ?? 0) - (dRepNoVotesPercentage ?? 0);

// SPO/Pool votes
const poolYesVotesPercentage =
poolYesVotes + poolNoVotes
? (poolYesVotes / (poolYesVotes + poolNoVotes)) * 100
typeof poolYesVotes === "number" &&
typeof networkTotalStake?.totalStakeControlledBySPOs === "number" &&
networkTotalStake.totalStakeControlledBySPOs > 0
? (poolYesVotes / networkTotalStake.totalStakeControlledBySPOs) * 100
: undefined;
const poolNoVotesPercentage = poolYesVotesPercentage
? 100 - poolYesVotesPercentage
: poolNoVotes
? 100
: undefined;

const poolNoVotesPercentage =
typeof poolNoVotes === "number" &&
typeof networkTotalStake?.totalStakeControlledBySPOs === "number" &&
networkTotalStake.totalStakeControlledBySPOs > 0
? (poolNoVotes / networkTotalStake.totalStakeControlledBySPOs) * 100
: undefined;

const poolNotVotedVotes =
typeof networkTotalStake?.totalStakeControlledBySPOs === "number"
? networkTotalStake.totalStakeControlledBySPOs -
(poolYesVotes + poolNoVotes + poolAbstainVotes)
: undefined;

const poolNotVotedVotesPercentage =
100 -
(typeof poolYesVotesPercentage === "number" ? poolYesVotesPercentage : 0) -
(typeof poolNoVotesPercentage === "number" ? poolNoVotesPercentage : 0);

// Constitutional Commission votes
const ccYesVotesPercentage = noOfCommitteeMembers
? (ccYesVotes / noOfCommitteeMembers) * 100
: undefined;
const ccNoVotesPercentage = noOfCommitteeMembers

const ccNoVotesPercentage = noOfCommitteeMembers
? (ccNoVotes / noOfCommitteeMembers) * 100
: undefined;
const ccNotVotedVotes =

const ccNotVotedVotes =
noOfCommitteeMembers - ccYesVotes - ccNoVotes - ccAbstainVotes;
const ccNotVotedVotesPercentage =

const ccNotVotedVotesPercentage =
100 - (ccYesVotesPercentage ?? 0) - (ccNoVotesPercentage ?? 0);

return (
Expand Down Expand Up @@ -200,6 +222,8 @@ export const VotesSubmitted = ({
noVotes={poolNoVotes}
noVotesPercentage={poolNoVotesPercentage}
abstainVotes={poolAbstainVotes}
notVotedVotes={poolNotVotedVotes}
notVotedPercentage={poolNotVotedVotesPercentage}
threshold={
(() => {
const votingThresholdKey = getGovActionVotingThresholdKey({
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/components/organisms/DrawerMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const DrawerMobile = ({
<MenuNavItem
closeDrawer={() => setIsDrawerOpen(false)}
navItem={navItem}
key={navItem.label}
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions govtool/metadata-validation/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion govtool/metadata-validation/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@govtool/metadata-validation",
"version": "2.0.23",
"version": "2.0.29",
"description": "",
"author": "",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion govtool/metadata-validation/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async function bootstrap() {
const config = new DocumentBuilder()
.setTitle('Metadata Validation Tool')
.setDescription('The Metadata Validation Tool API description')
.setVersion("2.0.23")
.setVersion("2.0.29")
.build();

const document = SwaggerModule.createDocument(app, config);
Expand Down
2 changes: 2 additions & 0 deletions tests/govtool-frontend/playwright/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ FAUCET_ADDRESS=
FAUCET_PAYMENT_PRIVATE=
FAUCET_STAKE_PRIVATE=

IS_HARDFORK_PROPOSAL_ENABLED=false

CI=true
TEST_WORKERS=6 // Number of workers to run in parallel
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const environments = {
(process.env.SCHEDULED_WORKFLOW &&
process.env.SCHEDULED_WORKFLOW == "true") ||
false,
isHardforkProposalEnabled:
process.env.IS_HARDFORK_PROPOSAL_ENABLED === "true" || false,
};

export default environments;
19 changes: 19 additions & 0 deletions tests/govtool-frontend/playwright/lib/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import environments from "@constants/environments";
import { ProposalType } from "@types";
export const parseVotingPowerAndPercentage = (
combinedString: string
): { votingPower: string; percentage: string } => {
Expand Down Expand Up @@ -27,3 +28,21 @@ export const getWalletConfigForFaucet = () => {
address: environments.faucet.address || "",
};
};


export const getProposalType = () => {
return Object.values(ProposalType).filter(
(type) =>
!(
environments.isHardforkProposalEnabled === false &&
type === ProposalType.hardFork
)
);
};

export const getProposalWalletCount = (): number => {
if (environments.isScheduled) {
return 1;
}
return environments.isHardforkProposalEnabled ? 6 : 5;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { faker } from "@faker-js/faker";
import { isBootStrapingPhase } from "@helpers/cardano";
import { ShelleyWallet } from "@helpers/crypto";
import { expectWithInfo } from "@helpers/exceptionHandler";
import { getProposalType } from "@helpers/index";
import {
downloadMetadata,
uploadScriptAndGenerateUrl,
Expand Down Expand Up @@ -615,8 +616,8 @@ export default class ProposalSubmissionPage {

async createProposal(
receivingAddress: string,
proposalType: ProposalType = Object.values(ProposalType)[
Math.floor(Math.random() * Object.values(ProposalType).length)
proposalType: ProposalType = getProposalType()[
Math.floor(Math.random() * getProposalType().length)
]
): Promise<number> {
await this.addLinkBtn.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ test("4A_1. Should access Governance Actions page with connecting wallet", async
await openDrawer(page);
}

await page.getByTestId("governance-actions-link").click();
await expect(page.getByText(/Governance Actions/i)).toHaveCount(2);
await page.getByTestId("governance-actions-live-voting-link").click();
await expect(page.getByText(/Live Voting/i)).toHaveCount(2);
});

test("4B_1. Should restrict voting for users who are not registered as DReps (with wallet connected)", async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import removeAllSpaces from "@helpers/removeAllSpaces";
import { functionWaitedAssert } from "@helpers/waitedLoop";
import extractExpiryDateFromText from "@helpers/extractExpiryDateFromText";
import { InvalidMetadata } from "@constants/index";
import { isMobile } from "@helpers/mobile";

test.beforeEach(async () => {
await setAllureEpic("4. Proposal visibility");
Expand Down Expand Up @@ -44,7 +45,11 @@ test("4A_2. Should access Governance Actions page without connecting wallet", as
await page.goto("/");
await page.getByTestId("move-to-governance-actions-button").click();

await expect(page.getByText(/Governance actions/i)).toHaveCount(2);
if (!isMobile(page)) {
await page.getByTestId("governance-actions").click();
}

await expect(page.getByText(/Live Voting/i)).toHaveCount(2);
});

test("4B_2. Should restrict voting for users who are not registered as DReps (without wallet connected)", async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ProposalType } from "@types";
import walletManager from "lib/walletManager";
import { valid as mockValid, invalid as mockInvalid } from "@mock/index";
import { rewardAddressBech32 } from "@helpers/shellyWallet";
import { getWalletConfigForFaucet } from "@helpers/index";
import { getProposalType, getWalletConfigForFaucet } from "@helpers/index";
import { faker } from "@faker-js/faker";
import { proposalSubmissionAuthFile } from "@constants/auth";
import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage";
Expand All @@ -28,7 +28,7 @@ test.beforeEach(async () => {
await skipIfTemporyWalletIsNotAvailable("proposalSubmissionWallets.json");
});

Object.values(ProposalType).forEach((proposalType, index) => {
getProposalType().forEach((proposalType, index) => {
test(`7H_${index + 1}. Should submit a ${proposalType.toLocaleLowerCase()} proposal as governance action`, async ({
page,
browser,
Expand Down
Loading
Loading