Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production Release 2023-10-16 #938

Merged
merged 8 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
uses: github/codeql-action/init@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
uses: github/codeql-action/autobuild@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -67,4 +67,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
uses: github/codeql-action/analyze@d90b8d79de6dc1f58e83a1499aa58d6c93dc28de # v2.22.2
189 changes: 189 additions & 0 deletions .github/workflows/maintain-prod-release-pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
on:
# run manually from the actions panels
workflow_dispatch:

# since we can't currently create a PR and have the jobs run
# successfully, run when one is manually created.
pull_request:
types: [opened]
branches: [prod]

# update the PR text when new commits are merged to the master branch
push:
branches:
- master

# and re-run early in the morning, mainly so the title gets updated with today's date
schedule:
- cron: "42 1 * * *"

permissions:
contents: read
pull-requests: write

jobs:
main:
name: Maintain Prod PR
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;

function renderCommit(commitMsg) {
const prRegex = /\(#(\d+)\)$/m;
const allRefsRegex = /#(\d+)\s/g;

const prRef = commitMsg.match(prRegex);

if (!prRef) {
return `- ${"???" + commitMsg}`;
}

const prNumber = prRef[1];

const otherReferences = [...commitMsg.matchAll(allRefsRegex)]
.map((m) => m[1])
.filter((r) => r !== prNumber);

const messages = [
`- #${prNumber}`,
...otherReferences.map((r) => ` - re #${r}`),
];

return messages.join("\n");
}

function buildSection(title, commitMsgs) {
if (commitMsgs.length === 0) return "";

return `\n## ${title}\n\n${commitMsgs.map(renderCommit).join("\n")}`;
}

function buildBody(messages) {
const groups = [
{
type: "feat",
title: "Features",
},
{
type: "fix",
title: "Fixes",
},
{
type: "chore",
title: "Chores",
},
{
type: "refactor",
title: "Refactors",
},
];

const knownSections = groups.map((group) =>
buildSection(
group.title,
messages.filter((m) => m.startsWith(group.type))
)
);

const allKnownSections = groups.map((g) => g.type);
const unknownSections = buildSection(
"Other",
messages.filter((m) => !allKnownSections.some((s) => m.startsWith(s)))
);

return [...knownSections, unknownSections].join("\n");
}

async function findReleasePR() {
const { data: prs } = await github.rest.pulls.list({
owner,
repo,
base: "prod",
state: "open",
});

if (prs.length === 0) {
console.log("no release PR found");
return undefined;
}

if (prs.length !== 1) {
throw new Error(`${prs.length} production PRs found...`);
}

const pr = prs[0];

console.log(
`Found PR#${pr.number} ${pr.title} ${
pr.draft ? "(draft)" : "(not draft)"
} - ${pr.html_url}`
);
return pr;
}

const pr = await findReleasePR();

if (!pr) {
console.log("checking commits...");
const commits = await github.rest.repos.compareCommitsWithBasehead({
owner,
repo,
basehead: "prod...master",
});

if (commits.data.commits.length === 0) {
console.log("no changes to release!");
return;
}

const commitMessages = commits.data.commits.map((c) => c.commit.message);

const result = buildBody(commitMessages);

console.log("need to create a draft release PR!", result);

// but don't actually do it yet: if you create one using the github
// token, it doesn't run the security jobs. Create an empty one by hand,
// for now.
/*
const newPr = await github.rest.pulls.create({
owner,
repo,
title: "Production Release (next)",
head: "master",
base: "prod",
draft: true,
body: result,
});

console.log("created: " + newPr.data.html_url);
*/
} else {
const { data: commits } = await github.rest.pulls.listCommits({
owner,
repo,
pull_number: pr.number,
});

const commitMessages = commits.map((c) => c.commit.message);
const body = buildBody(commitMessages);
const title = `Production Release ${new Date().toISOString().slice(0, 10)}`;

if (body === pr.body && title === pr.title) {
console.log("up to date!");
} else {
console.log(`Updating PR!`, { title, body });

await github.rest.pulls.update({
owner,
repo,
pull_number: pr.number,
body,
title,
});
}
}
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.18.0
18.18.1
39 changes: 39 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@mui/icons-material": "5.14.9",
"@mui/lab": "5.0.0-alpha.145",
"@mui/material": "5.14.10",
"@mui/x-data-grid": "6.16.1",
"@mui/x-date-pickers": "5.0.20",
"axios": "1.5.0",
"base64url": "3.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/auth/components/AdvertiserAgreed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { PaymentType } from "graphql/types";
export function AdvertiserAgreed() {
const { advertiser } = useAdvertiser();
const requiresPaymentAgree =
advertiser.selfServiceCreate &&
advertiser.selfServiceManageCampaign &&
advertiser.selfServicePaymentType !== PaymentType.Netsuite;
const history = useHistory();
const { setSessionUser } = useAuthContext();
Expand Down
3 changes: 1 addition & 2 deletions src/auth/context/auth.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { PaymentType } from "graphql/types";
export type IAdvertiser = {
id: string;
name: string;
selfServiceCreate: boolean;
selfServiceEdit: boolean;
selfServiceManageCampaign: boolean;
selfServiceSetPrice: boolean;
selfServicePaymentType: PaymentType;
publicKey?: string | null;
Expand Down
3 changes: 1 addition & 2 deletions src/auth/hooks/queries/useAdvertiser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ export function useAdvertiser(): {
const defaultAdvertiser: IAdvertiser = {
id: "",
name: "",
selfServiceCreate: false,
selfServiceEdit: false,
selfServiceManageCampaign: false,
selfServiceSetPrice: false,
publicKey: null,
selfServicePaymentType: PaymentType.Stripe,
Expand Down
3 changes: 1 addition & 2 deletions src/auth/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { RegistrationForm } from "auth/registration/types";
export type Advertiser = Pick<
AdvertiserFragment,
| "selfServiceSetPrice"
| "selfServiceCreate"
| "selfServiceEdit"
| "selfServiceManageCampaign"
| "id"
| "name"
| "publicKey"
Expand Down
2 changes: 1 addition & 1 deletion src/auth/registration/Register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { RegistrationSchema } from "validation/RegistrationSchema";
import { initialValues, RegistrationForm } from "auth/registration/types";
import { NameField } from "auth/registration/NameField";
import { AddressField } from "auth/registration/AddressField";
import { FormikSubmitButton } from "form/FormikHelpers";
import { FormikSubmitButton } from "form/FormikButton";
import { useRegister } from "auth/hooks/mutations/useRegister";
import { AdvertiserRegistered } from "auth/registration/AdvertiserRegistered";
import { NextAndBack } from "components/Steps/NextAndBack";
Expand Down
7 changes: 3 additions & 4 deletions src/components/Assets/ImageAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ type ImageOption = { label: string; image?: string };

const filter = createFilterOptions<ImageOption>();

export function ImageAutocomplete() {
export function ImageAutocomplete(props: { name: string }) {
const [createImage, setCreateImage] = useState(false);
const [, meta, imageUrl] = useField<string | undefined>(
`newCreative.payloadInlineContent.imageUrl`,
);
const [, meta, imageUrl] = useField<string | undefined>(props.name);
const hasError = Boolean(meta.error);
const showError = hasError && meta.touched;
const { advertiser } = useAdvertiser();
Expand Down Expand Up @@ -60,6 +58,7 @@ export function ImageAutocomplete() {
imageUrl.setValue(nv ? nv.image : undefined);
setCreateImage(nv != null && nv.image === undefined);
}}
isOptionEqualToValue={(option, value) => option.image === value.image}
/>

<UploadImage
Expand Down
19 changes: 19 additions & 0 deletions src/components/Button/FormatHelp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { IconButton } from "@mui/material";
import HelpIcon from "@mui/icons-material/Help";

export function FormatHelp() {
return (
<IconButton
size="small"
onClick={() =>
window.open(
"https://brave.com/brave-ads/ad-formats/",
"__blank",
"noopener",
)
}
>
<HelpIcon fontSize="small" />
</IconButton>
);
}
Loading