Skip to content

Commit d17db78

Browse files
Merge branch 'prebid:master' into master
2 parents a783730 + 7dde2dd commit d17db78

202 files changed

Lines changed: 5202 additions & 1380 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- uses: actions/checkout@v4
1919
with:
2020
fetch-depth: 0
21-
- uses: tj-actions/changed-files@v44
21+
- uses: tj-actions/changed-files@v46
2222
id: changed-files
2323
with:
2424
files: '**/*.md'
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Notify Code Path Changes
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, synchronize]
6+
paths:
7+
- '**'
8+
9+
env:
10+
OAUTH2_CLIENT_ID: ${{ secrets.OAUTH2_CLIENT_ID }}
11+
OAUTH2_CLIENT_SECRET: ${{ secrets.OAUTH2_CLIENT_SECRET }}
12+
OAUTH2_REFRESH_TOKEN: ${{ secrets.OAUTH2_REFRESH_TOKEN }}
13+
GITHUB_REPOSITORY: ${{ github.repository }}
14+
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
17+
permissions:
18+
contents: read
19+
20+
jobs:
21+
notify:
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout Code
25+
uses: actions/checkout@v3
26+
27+
- name: Set up Node.js
28+
uses: actions/setup-node@v3
29+
with:
30+
node-version: '18'
31+
32+
- name: Install dependencies
33+
run: npm install axios nodemailer
34+
35+
- name: Run Notification Script
36+
run: |
37+
node .github/workflows/scripts/send-notification-on-change.js
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# when a changed file paths matches the regex, send an alert email
2+
# structure of the file is:
3+
#
4+
# javascriptRegex : email address
5+
#
6+
# For example, in the Prebid docs repo, the file pattern is generally
7+
#
8+
# /dev-docs/bidders/BIDDERCODE.md
9+
#
10+
# The aim is to find a minimal set of regex patterns that matches any file in these paths
11+
12+
/dev-docs/bidders/rubicon : header-bidding@magnite.com
13+
/dev-docs/bidders/ix : pdu-supply-prebid@indexexchange.com
14+
/dev-docs/bidders/appnexus|/dev-docs/bidders/msft : prebid@microsoft.com
15+
/dev-docs/bidders/pubmatic : header-bidding@pubmatic.com
16+
/dev-docs/bidders/openx : prebid@openx.com
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// send-notification-on-change.js
2+
//
3+
// called by the code-path-changes.yml workflow, this script queries github for
4+
// the changes in the current PR, checks the config file for whether any of those
5+
// file paths are set to alert an email address, and sends email to multiple
6+
// parties if needed
7+
8+
const fs = require('fs');
9+
const path = require('path');
10+
const axios = require('axios');
11+
const nodemailer = require('nodemailer');
12+
13+
async function getAccessToken(clientId, clientSecret, refreshToken) {
14+
try {
15+
const response = await axios.post('https://oauth2.googleapis.com/token', {
16+
client_id: clientId,
17+
client_secret: clientSecret,
18+
refresh_token: refreshToken,
19+
grant_type: 'refresh_token',
20+
});
21+
return response.data.access_token;
22+
} catch (error) {
23+
console.error('Failed to fetch access token:', error.response?.data || error.message);
24+
process.exit(1);
25+
}
26+
}
27+
28+
(async () => {
29+
const configFilePath = path.join(__dirname, 'codepath-notification');
30+
const repo = process.env.GITHUB_REPOSITORY;
31+
const prNumber = process.env.GITHUB_PR_NUMBER;
32+
const token = process.env.GITHUB_TOKEN;
33+
34+
// Generate OAuth2 access token
35+
const clientId = process.env.OAUTH2_CLIENT_ID;
36+
const clientSecret = process.env.OAUTH2_CLIENT_SECRET;
37+
const refreshToken = process.env.OAUTH2_REFRESH_TOKEN;
38+
39+
// validate params
40+
if (!repo || !prNumber || !token || !clientId || !clientSecret || !refreshToken) {
41+
console.error('Missing required environment variables.');
42+
process.exit(1);
43+
}
44+
45+
// the whole process is in a big try/catch. e.g. if the config file doesn't exist, github is down, etc.
46+
try {
47+
// Read and process the configuration file
48+
const configFileContent = fs.readFileSync(configFilePath, 'utf-8');
49+
const configRules = configFileContent
50+
.split('\n')
51+
.filter(line => line.trim() !== '' && !line.trim().startsWith('#')) // Ignore empty lines and comments
52+
.map(line => {
53+
const [regex, email] = line.split(':').map(part => part.trim());
54+
return { regex: new RegExp(regex), email };
55+
});
56+
57+
// Fetch changed files from github
58+
const [owner, repoName] = repo.split('/');
59+
const apiUrl = `https://api.github.com/repos/${owner}/${repoName}/pulls/${prNumber}/files`;
60+
const response = await axios.get(apiUrl, {
61+
headers: {
62+
Authorization: `Bearer ${token}`,
63+
Accept: 'application/vnd.github.v3+json',
64+
},
65+
});
66+
67+
const changedFiles = response.data.map(file => file.filename);
68+
console.log('Changed files:', changedFiles);
69+
70+
// match file pathnames that are in the config and group them by email address
71+
const matchesByEmail = {};
72+
changedFiles.forEach(file => {
73+
configRules.forEach(rule => {
74+
if (rule.regex.test(file)) {
75+
if (!matchesByEmail[rule.email]) {
76+
matchesByEmail[rule.email] = [];
77+
}
78+
matchesByEmail[rule.email].push(file);
79+
}
80+
});
81+
});
82+
83+
// Exit successfully if no matches were found
84+
if (Object.keys(matchesByEmail).length === 0) {
85+
console.log('No matches found. Exiting successfully.');
86+
process.exit(0);
87+
}
88+
89+
console.log('Grouped matches by email:', matchesByEmail);
90+
91+
// get ready to email the changes
92+
const accessToken = await getAccessToken(clientId, clientSecret, refreshToken);
93+
94+
// Configure Nodemailer with OAuth2
95+
// service: 'Gmail',
96+
const transporter = nodemailer.createTransport({
97+
host: "smtp.gmail.com",
98+
port: 465,
99+
secure: true,
100+
auth: {
101+
type: 'OAuth2',
102+
user: 'info@prebid.org',
103+
clientId: clientId,
104+
clientSecret: clientSecret,
105+
refreshToken: refreshToken,
106+
accessToken: accessToken
107+
},
108+
});
109+
110+
// Send one email per recipient
111+
for (const [email, files] of Object.entries(matchesByEmail)) {
112+
const emailBody = `
113+
${email},
114+
<p>
115+
Files owned by you have been changed in open source ${repo}. The <a href="https://github.com/${repo}/pull/${prNumber}">pull request is #${prNumber}</a>. These are the files you own that have been modified:
116+
<ul>
117+
${files.map(file => `<li>${file}</li>`).join('')}
118+
</ul>
119+
`;
120+
121+
try {
122+
await transporter.sendMail({
123+
from: `"Prebid Info" <info@prebid.org>`,
124+
to: email,
125+
subject: `Files have been changed in open source ${repo}`,
126+
html: emailBody,
127+
});
128+
129+
console.log(`Email sent successfully to ${email}`);
130+
console.log(`${emailBody}`);
131+
} catch (error) {
132+
console.error(`Failed to send email to ${email}:`, error.message);
133+
}
134+
}
135+
} catch (error) {
136+
console.error('Error:', error.message);
137+
process.exit(1);
138+
}
139+
})();

_data/sidebar.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,15 @@
316316
sectionTitle:
317317
subgroup: 1
318318

319+
- sbSecId: 1
320+
title: In-renderer Integration
321+
link: /dev-docs/examples/in-renderer-integration.html
322+
Item: 1
323+
isHeader: 0
324+
isSectionHeader: 0
325+
sectionTitle:
326+
subgroup: 1
327+
319328
- sbSecId: 1
320329
title: Troubleshooting
321330
link:
@@ -441,6 +450,14 @@
441450
sectionTitle:
442451
subgroup: 4
443452

453+
- sbSecId: 1
454+
title: How to Add A User ID submodule
455+
link: /dev-docs/userId-module.html
456+
isHeader: 0
457+
isSectionHeader: 0
458+
sectionTitle:
459+
subgroup: 4
460+
444461
- sbSecId: 1
445462
title: How to Add a Prebid.js Video submodule
446463
link: /dev-docs/add-video-submodule.html
@@ -806,6 +823,14 @@
806823
sectionTitle:
807824
subgroup: 2
808825

826+
- sbSecId: 2
827+
title: API Reference
828+
link: /prebid-mobile-ios/index.html
829+
isHeader: 0
830+
isSectionHeader: 0
831+
sectionTitle:
832+
subgroup: 2
833+
809834
- sbSecId: 2
810835
title: "For Android"
811836
link:
@@ -895,6 +920,14 @@
895920
sectionTitle:
896921
subgroup: 3
897922

923+
- sbSecId: 2
924+
title: API Reference
925+
link: /prebid-mobile-android/index.html
926+
isHeader: 0
927+
isSectionHeader: 0
928+
sectionTitle:
929+
subgroup: 3
930+
898931
#--------------Ad Ops--------------|
899932

900933
- sbSecId: 3

_includes/astjs.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
type="text/plain"
44
class="cmplazyload"
55
data-cmp-purpose="c51"
6-
data-cmp-src="https://acdn.adnxs.com/ast/ast.js"></script>
6+
data-cmp-src="https://adsdk.microsoft.com/ast/ast.js"></script>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<ul class="nav nav-tabs" role="tablist">
2+
<!-- GMA SDK v12 Tab -->
3+
<li class="nav-item ui-tab" role="presentation">
4+
<button
5+
class="nav-link active"
6+
id="{{ include.id }}-gma12-tab"
7+
data-toggle="tab"
8+
data-target="#{{ include.id }}-gma12"
9+
type="button"
10+
role="tab"
11+
aria-controls="gma12"
12+
aria-selected="true"
13+
>
14+
GMA SDK v12
15+
</button>
16+
</li>
17+
<!-- GMA SDK v11 Tab -->
18+
<li class="nav-item ui-tab" role="presentation">
19+
<button
20+
class="nav-link"
21+
id="{{ include.id }}-gma11-tab"
22+
data-toggle="tab"
23+
data-target="#{{ include.id }}-gma11"
24+
type="button"
25+
role="tab"
26+
aria-controls="gma11"
27+
aria-selected="false"
28+
>
29+
GMA SDK v11
30+
</button>
31+
</li>
32+
</ul>
33+
34+
<div class="tab-content" id="gma-sdk-tab-content">
35+
<!-- GMA SDK v12 Content -->
36+
<div
37+
class="tab-pane fade show active"
38+
id="{{ include.id }}-gma12"
39+
role="tabpanel"
40+
aria-labelledby="{{ include.id }}-gma12-tab"
41+
>
42+
<div class="highlight">
43+
<pre
44+
class="highlight language-swift"
45+
><code class="language-swift">{{ include.gma12 | xml_escape }}</code></pre>
46+
</div>
47+
</div>
48+
<!-- GMA SDK v11 Content -->
49+
<div
50+
class="tab-pane fade"
51+
id="{{ include.id }}-gma11"
52+
role="tabpanel"
53+
aria-labelledby="{{ include.id }}-gma11-tab"
54+
>
55+
<div class="highlight">
56+
<pre
57+
class="highlight language-swift"
58+
><code class="language-swift">{{ include.gma11 | xml_escape }}</code></pre>
59+
</div>
60+
</div>
61+
</div>

_includes/code/web-example.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
&lt;!-- required scripts --&gt;
6565
{% assign scripts = include.scripts | split: "," %}{% for script in scripts %}{% if script == "pbjs" %}&lt;script async src=&quot;https://cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js&quot;&gt;&lt;/script&gt;
6666
{% elsif script == "gpt" %}&lt;script async src=&quot;https://securepubads.g.doubleclick.net/tag/js/gpt.js&quot;&gt;&lt;/script&gt;
67-
{% elsif script == "astjs" %}&lt;script async src=&quot;https://acdn.adnxs.com/ast/ast.js&quot;&gt;&lt;/script&gt;{% else %}&lt;!-- unknown script tag '{{ script }}' required --&gt;{% endif %}{% else %}&lt;script async src=&quot;//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js&quot;&gt;&lt;/script&gt;
67+
{% elsif script == "astjs" %}&lt;script async src=&quot;https://adsdk.microsoft.com/ast/ast.js&quot;&gt;&lt;/script&gt;{% else %}&lt;!-- unknown script tag '{{ script }}' required --&gt;{% endif %}{% else %}&lt;script async src=&quot;//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js&quot;&gt;&lt;/script&gt;
6868
&lt;script async src=&quot;https://securepubads.g.doubleclick.net/tag/js/gpt.js&quot;&gt;&lt;/script&gt;{% endfor %}
6969
&lt;/head&gt;
7070
&lt;body&gt;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{: .alert.alert-info :}
2+
Prebid note: please review with your legal counsel before enabling storageAllowed. Bidders utilizing browser storage may trigger the need for additional disclosures in your privacy policy and may imply that the bid adapter is performing an activity redundant with user ID systems like SharedID. See the ePrivacy Directive article 5(3) reference to 'comprehensive information'.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{: .alert.alert-warning :}
2+
Prebid.org recommends working with a privacy lawyer before making enforcement exceptions for any vendor.
3+
{% if include.gvlId %}We recommend publishers let Prebid.js make use of their registered GVL ID {{ include.gvlId }} instead of a vendor exception.{% endif %}

0 commit comments

Comments
 (0)