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

Implement finch tracker #732

Merged
merged 93 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
3074129
Add finch_parser
atuchin-m Aug 29, 2023
7289520
Fix classifying
atuchin-m Aug 29, 2023
7d7fd5a
Move to src/
atuchin-m Aug 29, 2023
45fc595
Frontend changes
atuchin-m Aug 29, 2023
05fa884
Move the frontend
atuchin-m Aug 29, 2023
632cf73
Move webpack
atuchin-m Aug 30, 2023
3e4fb08
Change UI
atuchin-m Aug 30, 2023
8619dcf
Fix lint, add clean
atuchin-m Aug 30, 2023
d89784f
Formating
atuchin-m Aug 30, 2023
061ceb3
More formating
atuchin-m Aug 30, 2023
3b687e5
Renaming
atuchin-m Aug 30, 2023
f41aa55
package-lock.json
atuchin-m Aug 30, 2023
9509d39
Add licenses
atuchin-m Aug 30, 2023
8e588fe
Improve blacklist
atuchin-m Aug 30, 2023
5b47e66
Parse Control_ group
atuchin-m Aug 30, 2023
c5cdc3a
Change folder logic
atuchin-m Aug 30, 2023
16f3554
Remove ts-loader
atuchin-m Aug 30, 2023
db43116
Fix lint
atuchin-m Aug 31, 2023
7ae2386
Decompose app.ts
atuchin-m Aug 31, 2023
c281cf7
Vue => React
atuchin-m Sep 1, 2023
11be636
Cosmetic fixes
atuchin-m Sep 1, 2023
9172b86
Lint fixes
atuchin-m Sep 1, 2023
3435893
Some cleanup
atuchin-m Sep 1, 2023
4db477e
Add favicon
atuchin-m Sep 4, 2023
26f205e
Show empty groups
atuchin-m Sep 4, 2023
12cc814
Parse Chromium version
atuchin-m Sep 4, 2023
7ca0db5
Implement filters
atuchin-m Sep 4, 2023
72fe42e
Add 2 filters
atuchin-m Sep 4, 2023
daac438
Rename files
atuchin-m Sep 4, 2023
a304cde
Update deploy workflow
atuchin-m Sep 5, 2023
dd7f3ca
Update cmd options
atuchin-m Sep 5, 2023
ea7021d
Move URLs
atuchin-m Sep 5, 2023
eab88f0
Add CI jobs
atuchin-m Sep 11, 2023
729e2b6
Make mrkdwn json summary
atuchin-m Sep 11, 2023
94c48a6
String filters
atuchin-m Sep 11, 2023
8f52635
Cleanup
atuchin-m Sep 11, 2023
15d9197
Fix build:proto
atuchin-m Sep 11, 2023
7229669
Review fixes
atuchin-m Sep 11, 2023
10bee0a
Fix config.js
atuchin-m Sep 11, 2023
b8c3bfd
Add a fallback message
atuchin-m Sep 11, 2023
5b5142b
Unified search link for features
atuchin-m Sep 12, 2023
6e0b2f0
Remove isBraveSeed
atuchin-m Sep 12, 2023
102cbd6
FilterDetails => StudyDetails
atuchin-m Sep 12, 2023
149628c
Change name filter
atuchin-m Sep 12, 2023
9b88f69
UI improvements
atuchin-m Sep 12, 2023
7d01e2a
Use chrome_version for all seeds
atuchin-m Sep 12, 2023
33af64f
Add upstream URL
atuchin-m Sep 12, 2023
3326d4b
Set min priority for upstream
atuchin-m Sep 12, 2023
1a7f816
Remove regexp
atuchin-m Sep 12, 2023
4b74e9c
Simplify filtering
atuchin-m Sep 12, 2023
4166727
Fix some review issues
atuchin-m Sep 13, 2023
6917faf
Move the job to private repo
atuchin-m Sep 13, 2023
9da3744
output the whole payload
atuchin-m Sep 13, 2023
d11bd57
Update repo URL
atuchin-m Sep 13, 2023
a77327c
npm run serve:dev allows hot-reloading dev experience (#744)
petemill Sep 14, 2023
2b8f732
Don't create output file for empty summary
atuchin-m Sep 13, 2023
6dc805b
Fix console.log
atuchin-m Sep 14, 2023
c27ca53
Fix clean && lint, remove js files from lint
atuchin-m Sep 14, 2023
07794a0
Change upstream URL
atuchin-m Sep 14, 2023
ff8c663
Relax eslint settings
atuchin-m Sep 14, 2023
8f9cf92
Explicitly ignore *.js in eslintrc
atuchin-m Sep 14, 2023
4fcc66f
Fix void main()
atuchin-m Sep 14, 2023
234ffc3
Fix <label>
atuchin-m Sep 14, 2023
f17437a
Remove upstreamTab
atuchin-m Sep 14, 2023
b77e30c
src/web/src => src/web/app
atuchin-m Sep 14, 2023
b72008c
React.useMemo() for experiments
atuchin-m Sep 14, 2023
80abe32
React.useMemo() for studies
atuchin-m Sep 14, 2023
bdba411
Code style
atuchin-m Sep 14, 2023
3239953
Add id to StudyModel
atuchin-m Sep 14, 2023
11477d9
Decompose app.tsx
atuchin-m Sep 14, 2023
a0ab9a9
Decompose core_utils.ts
atuchin-m Sep 14, 2023
36d3a58
Add jest tests
atuchin-m Sep 14, 2023
bebf666
Add jest to package.json
atuchin-m Sep 14, 2023
daf5111
Add ts-jest to package.json
atuchin-m Sep 14, 2023
62b7b98
Change jest.config.js
atuchin-m Sep 14, 2023
b72ea18
Add summary tests
atuchin-m Sep 14, 2023
76ef00f
Notify about parsing error, cut archived
atuchin-m Sep 14, 2023
97b952e
Fix directory structure
atuchin-m Sep 14, 2023
7d00f61
Split models
atuchin-m Sep 15, 2023
0ae1407
Add study_models.tests.ts
atuchin-m Sep 15, 2023
95f135b
Fix seed loading
atuchin-m Sep 16, 2023
d335757
Reject for non HTTP 200
atuchin-m Sep 16, 2023
5718084
Better sourcegraph regexs
atuchin-m Sep 16, 2023
b44fef2
Control_ => Control
atuchin-m Sep 19, 2023
909f5c2
Update README.md
atuchin-m Sep 19, 2023
63b8194
Add comments, use -1 version for Brave
atuchin-m Sep 19, 2023
56976cf
Add src/README.md
atuchin-m Sep 19, 2023
5b01a85
Show min/max version
atuchin-m Sep 20, 2023
e25e06d
Sanitize study.name
atuchin-m Sep 20, 2023
6a784fe
Improve killswitch detection
atuchin-m Sep 20, 2023
1b77433
Add sanitizeUrl
atuchin-m Sep 26, 2023
efc6892
Fix review issues
atuchin-m Sep 26, 2023
a8aa3b8
Fix sanitizeUrl()
atuchin-m Sep 26, 2023
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
7 changes: 4 additions & 3 deletions .github/workflows/deploy-to-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ main ]
paths:
- 'web/**'
- 'src/**'
workflow_dispatch:

jobs:
Expand All @@ -21,8 +21,9 @@ jobs:
AWS_REGION: us-west-2
CLOUDFRONT_DISTRIBUTION_ID: ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}
run: |
cd ./web
cd ./src
npm install
npm run build
aws s3 sync . s3://brave-production-griffin-origin/ --delete --exclude '*' --include 'index.html' --include 'static/*' --include 'proto/*'
cd ./web/public
aws s3 sync . s3://brave-production-griffin-origin/ --delete --exclude '*' --include 'index.html' --include 'bundle/*'
aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/*"
29 changes: 29 additions & 0 deletions .github/workflows/test-src.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Tracker&Griffin tests

on:
pull_request:
branches: [main, production]
paths:
- 'src/**'
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./src
steps:
- uses: actions/checkout@v4

- name: npm install
run: npm install

- name: build
run: npm run build

- name: run tests
run: npm run test

- name: lint
run: npm run lint
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ See the [Wiki](https://github.com/brave/brave-browser/wiki/Brave-Variations-(Gri
A continuous integration server (CI) serializes and signs the updated seed file before publishing it to a CDN endpoint at https://variations.brave.com/seed. To browse the contents of the seed file a dashboard is hosted at https://griffin.brave.com. The repo is organized as follows:
- `/crypto` contains a util to create key pairs and sign the seed file.
- `/seed` contains the JSON seed definition and serialisation code.
- `/web` contains the web dashboard to browse the seed contents.
- `/src` contains the web dashboard to browse the seed contents and tracker code the track changes. See https://github.com/brave/brave-variations/blob/main/src/README.md for details.

## Git flow
1. Work in feature branch and when done create a PR to `main` branch (which will be picked up by CI for staging).
Expand Down
49 changes: 49 additions & 0 deletions src/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
module.exports = {
settings: {
react: {
version: 'detect',
},
},
extends: ['standard-with-typescript', 'prettier', 'plugin:react/recommended'],
plugins: ['prettier', 'licenses', 'react'],
root: true,
parserOptions: {
project: './tsconfig-lint.json',
tsconfigRootDir: __dirname,
},
ignorePatterns: [
'*.js',
'proto/generated/*',
'node_modules/*',
],
rules: {
'prettier/prettier': [
'error',
{
singleQuote: true,
printWidth: 80,
},
],
'@typescript-eslint/explicit-function-return-type': 'off',
'licenses/header': [
2,
{
tryUseCreatedYear: true,
comment: {
allow: 'both',
prefer: 'line',
},
header: [
'Copyright (c) {YEAR} The Brave Authors. All rights reserved.',
'This Source Code Form is subject to the terms of the Mozilla Public',
'License, v. 2.0. If a copy of the MPL was not distributed with this file,',
'You can obtain one at https://mozilla.org/MPL/2.0/.',
],
},
],
},
};
2 changes: 2 additions & 0 deletions src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
finch_tracker/build/
23 changes: 23 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Griffin & Finch Tracker

## Directory structure

`core` is common Typescript code used by both Tracker and griffin.brave.com.

`finch_tracker` - NodeJS/TS console app to track seed changes. See https://github.com/brave/finch-data-private/#finch-tracker

`web` WebUI hosted on griffin.brave.com. It parses raw seed data and shows them in human readable format. Doesn't use any sophisticated backend, 100% code runs on the client side.

`test` is supporting code/data to use in tests

`proto` chromium protobuf files describing seed data format.

## Commands and actions

`npm run build` to build everything
`npm run lint -- --fix` run lint and try to fix all the problems
`npm run test` to run tests (also used in CI)

[deploy-to-production](https://github.com/brave/brave-variations/actions/workflows/deploy-to-production.yml) GH action to deploy a new version of griffin.brave.com

`npm run tracker -- <finch-data-private-checkout>` to run tracker app
33 changes: 33 additions & 0 deletions src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
module.exports = {
blocklistedFeatures: [
'AutofillUseApi',
'Ukm',
'UkmSamplingRate',
'HappinessTrackingSurveysForDesktopWhatsNew',
'VariationsGoogleGroupFiltering',
'ExpiredHistogramLogic',
'UMANonUniformityLogNormal',
'PostFREFixMetricsReporting',
'UMAPseudoMetricsEffect',
],
blocklistedStudies: [
'UKM',
'MetricsAndCrashSampling',
'MetricsClearLogsOnClonedInstall',
],

// Add your slack ID to get notifications about new kill switches.
// To retrive it use Slack profile => Copy Member ID.
killSwitchNotificationIds: [
'U02DG0ATML3', // @matuchin
'UE87NRK2A', // @iefremov
],
processingErrorNotificationIds: [
'U02DG0ATML3', // @matuchin
'UE87NRK2A', // @iefremov
],
};
17 changes: 17 additions & 0 deletions src/core/base_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

export enum SeedType {
PRODUCTION, // production Brave seed (brave-variations@production)
STAGING, // staging Brave seed (brave-variations@main)
UPSTREAM, // Chrome seed (Finch)
}

export class ProcessingOptions {
// The Chromium used by the current stable Brave (i.e. cr117). Usually is
// taken from API.
// Studies that target to older versions are considered as outdated.
minMajorVersion: number;
}
36 changes: 36 additions & 0 deletions src/core/blocklists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import * as config from '../config';

class Blocklist {
private readonly regexps: RegExp[] = [];

constructor(patterns: string[]) {
for (const line of patterns) {
if (line === '') continue;
const len = line.length;
if (len > 2 && line[0] === '/' && line[len - 1] === '/') {
this.regexps.push(new RegExp(line.substring(1, len - 2)));
} else {
this.regexps.push(new RegExp(`^${line}$`));
}
}
}

matches(str: string): boolean {
return this.regexps.find((v) => v.test(str)) !== undefined;
}
}

const gStudyBlocklist = new Blocklist(config.blocklistedStudies);
const gFeatureBlocklist = new Blocklist(config.blocklistedFeatures);

export function isStudyNameBlocklisted(studyName: string): boolean {
return gStudyBlocklist.matches(studyName);
}

export function isFeatureBlocklisted(featureName: string): boolean {
return gFeatureBlocklist.matches(featureName);
}
71 changes: 71 additions & 0 deletions src/core/serializers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import { variations as proto } from '../proto/generated/proto_bundle';

export function getPlatformNameFromString(protoPlatfrom: string): string {
const PREFIX = 'PLATFORM_';
if (protoPlatfrom.startsWith(PREFIX))
return protoPlatfrom.substring(PREFIX.length);
return protoPlatfrom;
}

export function getPlatfromName(protoPlatfrom: proto.Study.Platform): string {
return getPlatformNameFromString(proto.Study.Platform[protoPlatfrom]);
}

export function getChannelNameFromString(
protoChannel: string,
isBraveSpecific: boolean,
): string {
if (isBraveSpecific) {
if (protoChannel === 'STABLE') return 'RELEASE';
if (protoChannel === 'CANARY') return 'NIGHTLY';
}
return protoChannel;
}

export function getChannelName(
protoChannel: proto.Study.Channel,
isBraveSpecific: boolean,
): string {
return getChannelNameFromString(
proto.Study.Channel[protoChannel],
isBraveSpecific,
);
}

function unixSecondToUTCString(unixTimeSeconds: number): string {
return new Date(unixTimeSeconds * 1000).toUTCString();
}

export function serializePlatforms(platforms?: string[]): string | undefined {
if (platforms === undefined) return undefined;
return platforms.map((v) => getPlatformNameFromString(v)).join(', ');
}

export function serializeChannels(channels?: string[]): string | undefined {
if (channels === undefined) return undefined;
return channels.join(', ');
}

// Converts a study to JSON that is ready to be serialized. Some field are
// removed, some are converted to a human readable format.
export function studyToJSON(study: proto.IStudy): Record<string, any> {
const msg = proto.Study.fromObject(study);
const json = msg.toJSON();
const filter = json.filter;
delete json.consistency;
delete json.activation_type;
if (filter !== undefined) {
if (filter.end_date !== undefined)
filter.end_date = unixSecondToUTCString(filter.end_date);
if (filter.start_date !== undefined) {
filter.start_date = unixSecondToUTCString(filter.start_date);
}
filter.platform = serializePlatforms(filter.platform);
filter.channel = serializeChannels(filter.channel);
}
return json;
}
Loading