Skip to content

Commit

Permalink
fix: Add contracts git version to DB (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
Whytecrowe authored Nov 21, 2023
2 parents ac1a5e3 + dc90936 commit 53b484b
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
command: yarn check-coverage #Validate code is adequately covered by unit tests
- persist_to_workspace:
root: ~/repo
paths: .
paths: [.]
publish:
<<: *defaults
steps:
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"lint": "yarn lint-sol & yarn lint-ts --no-error-on-unmatched-pattern",
"clean": "hardhat clean",
"build": "yarn run clean && yarn run compile",
"postbuild": "yarn save-tag-bash",
"typechain": "hardhat typechain",
"pretest": "yarn mongo:start",
"pretest": "yarn mongo:start && yarn save-tag",
"test": "hardhat test",
"test-local": "yarn test",
"posttest": "yarn mongo:stop",
Expand All @@ -27,6 +28,8 @@
"devnet": "ts-node src/tenderly/devnet/devnet-execute.ts",
"gas-cost": "ts-node src/utils/gas-costs.ts",
"docgen": "hardhat docgen",
"save-tag": "ts-node src/utils/git-tag/save-tag.ts",
"save-tag-bash": "chmod a+x ./src/utils/git-tag/save-tag.sh && bash ./src/utils/git-tag/save-tag.sh",
"mongo:start": "docker-compose up -d",
"mongo:stop": "docker-compose stop",
"mongo:down": "docker-compose down",
Expand Down
53 changes: 37 additions & 16 deletions src/deploy/db/mongo-adapter/mongo-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import fs from "fs";
import { TLogger } from "../../campaign/types";
import { Collection, Db, MongoClient, MongoClientOptions } from "mongodb";
import { IDBVersion, IMongoDBAdapterArgs } from "./types";
import { COLL_NAMES, VERSION_TYPES } from "./constants";
import { IContractDbData } from "../types";
import { tagFilePath } from "../../../utils/git-tag/constants";
// eslint-disable-next-line @typescript-eslint/no-var-requires
require("dotenv").config();

Expand Down Expand Up @@ -84,7 +86,9 @@ export class MongoDBAdapter {

// Contract methods
async getContract (contractName : string, version ?: string) {
if (!version) version = await this.getCheckLatestVersion();
if (!version) {
({ dbVersion: version } = await this.getCheckLatestVersion());
}

return this.contracts.findOne({
name: contractName,
Expand All @@ -93,7 +97,9 @@ export class MongoDBAdapter {
}

async writeContract (contractName : string, data : IContractDbData, version ?: string) {
if (!version) version = await this.getCheckLatestVersion();
if (!version) {
({ dbVersion: version } = await this.getCheckLatestVersion());
}

await this.contracts.insertOne({
...data,
Expand All @@ -119,10 +125,10 @@ export class MongoDBAdapter {
if (version) {
finalVersion = version;

if (version !== deployedV || !deployedV) {
if (!deployedV || version !== deployedV.dbVersion) {
// we should only have a single TEMP version at any given time
if (version !== tempV && tempV) {
await this.clearDBForVersion(tempV);
if (tempV && version !== tempV.dbVersion) {
await this.clearDBForVersion(tempV.dbVersion);
}

await this.createUpdateTempVersion(finalVersion);
Expand All @@ -134,10 +140,10 @@ export class MongoDBAdapter {
this.logger.info(`No version provided to MongoDBAdapter, using current timestamp as new TEMP version: ${finalVersion}`);
await this.createUpdateTempVersion(finalVersion);
} else if (!deployedV) {
finalVersion = tempV as string;
finalVersion = tempV?.dbVersion as string;
this.logger.info(`Using existing MongoDB TEMP version: ${finalVersion}`);
} else {
finalVersion = deployedV;
finalVersion = deployedV.dbVersion;
this.logger.info(`Using existing MongoDB DEPLOYED version: ${finalVersion}`);
}
}
Expand All @@ -146,11 +152,11 @@ export class MongoDBAdapter {
}

async finalizeDeployedVersion (version ?: string) {
const finalV = version || await this.getTempVersion();
const finalV = version || (await this.getTempVersion())?.dbVersion;

if (!finalV) return;

const deployedV = await this.getDeployedVersion();
const deployedV = (await this.getDeployedVersion())?.dbVersion;
if (finalV !== deployedV) {
// archive the current DEPLOYED version
await this.versions.updateOne(
Expand All @@ -166,7 +172,8 @@ export class MongoDBAdapter {
// create new DEPLOYED version
await this.versions.insertOne({
type: VERSION_TYPES.deployed,
version: finalV,
dbVersion: finalV,
contractsVersion: this.getContractsVersionFromFile(),
});

// now remove the TEMP version
Expand Down Expand Up @@ -198,40 +205,54 @@ export class MongoDBAdapter {
return v;
}

async getTempVersion () : Promise<string | null> {
async getTempVersion () : Promise<IDBVersion | null> {
const v = await this.versions.findOne({
type: VERSION_TYPES.temp,
});

if (!v) return null;

return v.version;
return v;
}

async getDeployedVersion () : Promise<string | null> {
async getDeployedVersion () : Promise<IDBVersion | null> {
const v = await this.versions.findOne({
type: VERSION_TYPES.deployed,
});

if (!v) return null;

return v.version;
return v;
}

async getLatestVersion () : Promise<string | null> {
async getLatestVersion () : Promise<IDBVersion | null> {
const v = await this.getTempVersion();

if (v) return v;

return this.getDeployedVersion();
}

getContractsVersionFromFile () {
if (!fs.existsSync(tagFilePath)) {
throw Error(`No git tag found at ${tagFilePath}`);
}

const tag = fs.readFileSync(tagFilePath, "utf8").trim();
this.logger.info(`Git tag found at ${tagFilePath}: ${tag}`);

return tag;
}

async createUpdateTempVersion (version : string) {
const contractsVersion = this.getContractsVersionFromFile();

return this.versions.updateOne({
type: VERSION_TYPES.temp,
}, {
$set: {
version,
dbVersion: version,
contractsVersion,
},
}, {
upsert: true,
Expand Down
3 changes: 2 additions & 1 deletion src/deploy/db/mongo-adapter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface IMongoDBAdapterArgs {
}

export interface IDBVersion {
version : string;
dbVersion : string;
contractsVersion : string;
type : string;
}
7 changes: 4 additions & 3 deletions src/deploy/zns-campaign.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IDeployCampaignConfig, TLogger } from "./campaign/types";
import { IDeployCampaignConfig } from "./campaign/types";
import { HardhatDeployer } from "./deployer/hardhat-deployer";
import { DeployCampaign } from "./campaign/deploy-campaign";
import {
Expand All @@ -11,20 +11,21 @@ import {
import * as hre from "hardhat";

import { getMongoAdapter } from "./db/mongo-adapter/get-adapter";
import { getLogger } from "./logger/create-logger";


export const runZnsCampaign = async ({
config,
logger,
dbVersion,
} : {
config : IDeployCampaignConfig;
logger : TLogger;
dbVersion ?: string;
}) => {
// TODO dep: figure out the best place to put this at!
hre.upgrades.silenceWarnings();

const logger = getLogger();

const deployer = new HardhatDeployer(config.deployAdmin);

const dbAdapter = await getMongoAdapter();
Expand Down
2 changes: 2 additions & 0 deletions src/utils/git-tag/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const tagFile = "git-tag.txt";
export const tagFilePath = `${process.cwd()}/artifacts/${tagFile}`;
17 changes: 17 additions & 0 deletions src/utils/git-tag/get-tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import fs from "fs";
import { tagFilePath } from "./constants";
import { getLogger } from "../../deploy/logger/create-logger";


const logger = getLogger();

export const getGitTag = () => {
if (!fs.existsSync(tagFilePath)) {
throw Error(`No git tag found at ${tagFilePath}`);
}

const tag = fs.readFileSync(tagFilePath, "utf8").trim();
logger.info(`Git tag found at ${tagFilePath}: ${tag}`);

return tag;
};
8 changes: 8 additions & 0 deletions src/utils/git-tag/save-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

tag=$(git describe --tags --abbrev=0)
echo "Last tag: $tag"
commit=$(git rev-list -n 1 "$tag")
echo "Commit: $commit"
echo "$tag:$commit" > ./artifacts/git-tag.txt
echo "Git tag saved to ./artifacts/git-tag.txt"
40 changes: 40 additions & 0 deletions src/utils/git-tag/save-tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { exec } from "child_process";
import { promisify } from "util";
import { getLogger } from "../../deploy/logger/create-logger";
import fs from "fs";
import { tagFilePath } from "./constants";


const execAsync = promisify(exec);
const logger = getLogger();


const acquireLatestGitTag = async () => {
const gitTag = await execAsync("git describe --tags --abbrev=0");
const tag = gitTag.stdout.trim();

logger.info(`Latest git tag acquired: ${tag}`);

const commitHash = await execAsync(`git rev-list -n 1 ${tag}`);
const commit = commitHash.stdout.trim();

const full = `${tag}:${commit}`;
logger.info(`Git commit hash acquired for tag: ${commit}. Full: ${full}`);

return full;
};

const saveTag = async () => {
const tag = await acquireLatestGitTag();

fs.writeFileSync(tagFilePath, tag, "utf8");
logger.info(`Saved git tag-commit to ${tagFilePath}}`);
};

saveTag()
// eslint-disable-next-line @typescript-eslint/no-empty-function
.then(process.exit(0))
.catch(e => {
logger.error(e);
process.exit(1);
});
56 changes: 46 additions & 10 deletions test/DeployCampaign.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
} from "../src/deploy/missions/contracts";
import { znsNames } from "../src/deploy/missions/contracts/names";
import { IDeployCampaignConfig, TZNSContractState, TLogger } from "../src/deploy/campaign/types";
import { getLogger } from "../src/deploy/logger/create-logger";
import { runZnsCampaign } from "../src/deploy/zns-campaign";
import { MeowMainnet } from "../src/deploy/missions/contracts/meow-token/mainnet-data";
import { HardhatDeployer } from "../src/deploy/deployer/hardhat-deployer";
Expand All @@ -36,6 +35,10 @@ import { ResolverTypes } from "../src/deploy/constants";
import { MongoDBAdapter } from "../src/deploy/db/mongo-adapter/mongo-adapter";
import { getConfig, validate } from "../src/deploy/campaign/environments";
import { ethers, BigNumber } from "ethers";
import { promisify } from "util";
import { exec } from "child_process";

const execAsync = promisify(exec);


describe("Deploy Campaign Test", () => {
Expand All @@ -51,9 +54,6 @@ describe("Deploy Campaign Test", () => {

let mongoAdapter : MongoDBAdapter;

// TODO dep: move logger to runZNSCampaign()
const logger = getLogger();

before(async () => {
[deployAdmin, admin, governor, zeroVault, userA, userB] = await hre.ethers.getSigners();
});
Expand Down Expand Up @@ -81,7 +81,6 @@ describe("Deploy Campaign Test", () => {
it("should deploy new MeowTokenMock when `mockMeowToken` is true", async () => {
const campaign = await runZnsCampaign({
config: campaignConfig,
logger,
});

const { meowToken, dbAdapter } = campaign;
Expand Down Expand Up @@ -117,7 +116,6 @@ describe("Deploy Campaign Test", () => {

const campaign = await runZnsCampaign({
config: campaignConfig,
logger,
});

const {
Expand Down Expand Up @@ -262,7 +260,6 @@ describe("Deploy Campaign Test", () => {
// run Campaign again, but normally
const nextCampaign = await runZnsCampaign({
config: campaignConfig,
logger,
});

({ dbAdapter } = nextCampaign);
Expand Down Expand Up @@ -626,11 +623,8 @@ describe("Deploy Campaign Test", () => {
[userB.address, governor.address], // admins
);

const logger = getLogger();

const campaign = await runZnsCampaign({
config,
logger,
});

const { dbAdapter } = campaign;
Expand Down Expand Up @@ -801,4 +795,46 @@ describe("Deploy Campaign Test", () => {
}
});
});

// TODO dep: add more versioning tests here for DB versions!
describe("Versioning", () => {
let campaign : DeployCampaign;

before(async () => {
campaignConfig = {
deployAdmin,
governorAddresses: [ deployAdmin.address ],
adminAddresses: [ deployAdmin.address, admin.address ],
domainToken: {
name: ZNS_DOMAIN_TOKEN_NAME,
symbol: ZNS_DOMAIN_TOKEN_SYMBOL,
defaultRoyaltyReceiver: deployAdmin.address,
defaultRoyaltyFraction: DEFAULT_ROYALTY_FRACTION,
},
rootPriceConfig: DEFAULT_PRICE_CONFIG,
zeroVaultAddress: zeroVault.address,
stakingTokenAddress: MeowMainnet.address,
mockMeowToken: true,
};

campaign = await runZnsCampaign({
config: campaignConfig,
});
});

it("should get the correct git tag + commit hash and write to DB", async () => {
const latestGitTag = (await execAsync("git describe --tags --abbrev=0")).stdout.trim();
const latestCommit = (await execAsync(`git rev-list -n 1 ${latestGitTag}`)).stdout.trim();

const fullGitTag = `${latestGitTag}:${latestCommit}`;

const { dbAdapter } = campaign;

const versionDoc = await dbAdapter.getLatestVersion();
expect(versionDoc?.contractsVersion).to.equal(fullGitTag);

const deployedVersion = await dbAdapter.getDeployedVersion();
expect(deployedVersion?.contractsVersion).to.equal(fullGitTag);
});
});
});

0 comments on commit 53b484b

Please sign in to comment.