Skip to content

Commit

Permalink
Merge branch 'master' into refactor/ios-audio-session-manager
Browse files Browse the repository at this point in the history
  • Loading branch information
freeboub authored Sep 6, 2024
2 parents d325c49 + b2fd8d6 commit 8611c0b
Show file tree
Hide file tree
Showing 203 changed files with 13,865 additions and 7,765 deletions.
23 changes: 22 additions & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ body:

- type: dropdown
id: platforms
validations:
required: true
attributes:
label: What platforms are you having the problem on?
multiple: true
Expand All @@ -28,6 +30,25 @@ body:
- visionOS
- Android TV
- Apple tvOS

- type: input
id: system_version
attributes:
label: System Version
description: What version of the system is using device that you are experiencing the issue?
validations:
required: true

- type: dropdown
id: device
validations:
required: true
attributes:
label: On what device are you experiencing the issue?
multiple: true
options:
- Real device
- Simulator

- type: dropdown
id: architecture
Expand All @@ -53,7 +74,7 @@ body:
- type: input
id: reproduction-repo
attributes:
label: Reproduction
label: Reproduction Link
description: Provide a link to a repository with a reproduction of the bug, this is optional but it will make us to fix the bug faster
placeholder: Reproduction Repository
value: "repository link"
Expand Down
7 changes: 7 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,11 @@ body:
validations:
required: false

- type: markdown
attributes:
value: |
## Support
If this functionality is important to you and you need it, contact [TheWidlarzGroup](https://thewidlarzgroup.com) - [`[email protected]`](mailto:[email protected])
282 changes: 282 additions & 0 deletions .github/scripts/validate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
const FIELD_MAPPINGS = {
Platform: 'What platforms are you having the problem on?',
Version: 'Version',
SystemVersion: 'System Version',
DeviceType: 'On what device are you experiencing the issue?',
Architecture: 'Architecture',
Description: 'What happened?',
ReproductionLink: 'Reproduction Link',
Reproduction: 'Reproduction',
};

const PLATFORM_LABELS = {
iOS: 'Platform: iOS',
visionOS: 'Platform: iOS',
'Apple tvOS': 'Platform: iOS',
Android: 'Platform: Android',
'Android TV': 'Platform: Android',
Windows: 'Platform: Windows',
web: 'Platform: Web',
};

const BOT_LABELS = [
'Missing Info',
'Repro Provided',
'Missing Repro',
'Waiting for Review',
'Newer Version Available',
...Object.values(PLATFORM_LABELS),
];

const SKIP_LABEL = "No Validation"

const MESSAGE = {
FEATURE_REQUEST: `Thank you for your feature request. We will review it and get back to you if we need more information.`,
BUG_REPORT: `Thank you for your bug report. We will review it and get back to you if we need more information.`,
MISSING_INFO: (missingFields) => {
return `Thank you for your issue report. Please note that the following information is missing or incomplete:\n\n${missingFields
.map((field) => `- ${field.replace('missing-', '')}`)
.join(
'\n',
)}\n\nPlease update your issue with this information to help us address it more effectively.
\n > Note: issues without complete information have a lower priority`;
},
OUTDATED_VERSION: (issueVersion, latestVersion) => {
return (
`There is a newer version of the library available. ` +
`You are using version ${issueVersion}, while the latest stable version is ${latestVersion}. ` +
`Please update to the latest version and check if the issue still exists.` +
`\n > Note: If the issue still exists, please update the issue report with the latest information.`
);
},
};

const checkLatestVersion = async () => {
try {
const response = await fetch(
'https://registry.npmjs.org/react-native-video/latest',
);
const data = await response.json();
return data.version;
} catch (error) {
console.error('Error checking latest version:', error);
return null;
}
};

const getFieldValue = (body, field) => {
if (!FIELD_MAPPINGS[field]) {
console.warn('Field not supported:', field);
return '';
}

const fieldValue = FIELD_MAPPINGS[field];

const sections = body.split('###');
const section = sections.find((section) => {
// Find the section that contains the field
// For Reproduction, we need to make sure that we don't match Reproduction Link
if (field === 'Reproduction') {
return (
section.includes(fieldValue) && !section.includes('Reproduction Link')
);
}

return section.includes(fieldValue);
});

return section ? section.replace(fieldValue, '').trim() : '';
};

const validateBugReport = async (body, labels) => {
const selectedPlatforms = getFieldValue(body, 'Platform')
.split(',')
.map((p) => p.trim());

if (selectedPlatforms.length === 0) {
labels.add('missing-platform');
} else {
selectedPlatforms.forEach((platform) => {
const label = PLATFORM_LABELS[platform];
if (label) {
labels.add(label);
} else {
console.warn('Platform not supported', platform);
}
});
}

const version = getFieldValue(body, 'Version');
if (version) {
const words = version.split(' ');
const versionPattern = /\d+\.\d+\.\d+/;
const isVersionValid = words.some((word) => versionPattern.test(word));

if (!isVersionValid) {
labels.add('missing-version');
}

const latestVersion = await checkLatestVersion();
if (latestVersion && latestVersion !== version) {
labels.add(`outdated-version-${version}-${latestVersion}`);
}
}

const fields = [
{
name: 'SystemVersion',
invalidValue:
'What version of the system is using device that you are experiencing the issue?',
},
{name: 'DeviceType'},
{name: 'Architecture'},
{name: 'Description', invalidValue: 'A bug happened!'},
{name: 'Reproduction', invalidValue: 'Step to reproduce this bug are:'},
{name: 'ReproductionLink', invalidValue: 'repository link'},
];

fields.forEach(({name, invalidValue}) => {
const value = getFieldValue(body, name);
if (!value || value === invalidValue) {
const fieldName = FIELD_MAPPINGS[name];
labels.add(`missing-${fieldName.toLowerCase()}`);
}
});
};

const validateFeatureRequest = (body, labels) => {
// Implement feature request validation logic here
};

const handleIssue = async ({github, context}) => {
const {issue} = context.payload;
const {body} = issue;
const labels = new Set(issue.labels.map((label) => label.name));

if(labels.has(SKIP_LABEL)) {
console.log("Skiping Issue Validation")
return;
}

// Clear out labels that are added by the bot
BOT_LABELS.forEach((label) => labels.delete(label));

const isBug = labels.has('bug');
const isFeature = labels.has('feature');

if (isFeature) {
await handleFeatureRequest({github, context, body, labels});
} else if (isBug) {
await handleBugReport({github, context, body, labels});
} else {
console.warn('Issue is not a bug or feature request');
}

await updateIssueLabels({github, context, labels});
};

const handleFeatureRequest = async ({github, context, body, labels}) => {
validateFeatureRequest(body, labels);

const comment = MESSAGE.FEATURE_REQUEST;
await createComment({github, context, body: comment});
};

const handleBugReport = async ({github, context, body, labels}) => {
await validateBugReport(body, labels);

if (Array.from(labels).some((label) => label.startsWith('missing-'))) {
await handleMissingInformation({github, context, labels});
} else {
await handleValidReport({github, context, labels});
}
};

const handleMissingInformation = async ({github, context, labels}) => {
const missingFields = Array.from(labels).filter((label) =>
label.startsWith('missing-'),
);

const outdatedVersionLabel = Array.from(labels).find((label) =>
label.startsWith('outdated-version'),
);

if (missingFields.length > 0) {
let comment = MESSAGE.MISSING_INFO(missingFields);

if (outdatedVersionLabel) {
const [, , issueVersion, latestVersion] = outdatedVersionLabel.split('-');
comment += `\n\n ${MESSAGE.OUTDATED_VERSION(
issueVersion,
latestVersion,
)}`;
}

await createComment({github, context, body: comment});
}

updateLabelsForMissingInfo(labels);
};

const updateLabelsForMissingInfo = (labels) => {
if (labels.has('missing-reproduction')) {
labels.add('Missing Repro');
labels.delete('Repro Provided');
} else {
labels.delete('Missing Repro');
labels.add('Repro Provided');
}

if (
Array.from(labels).find((label) => label.startsWith('outdated-version'))
) {
labels.add('Newer Version Available');
} else {
labels.delete('Newer Version Available');
}

labels.add('Missing Info');
labels.delete('Waiting for Review');
};

const handleValidReport = async ({github, context, labels}) => {
let comment = MESSAGE.BUG_REPORT;

const outdatedVersionLabel = Array.from(labels).find((label) =>
label.startsWith('outdated-version'),
);

if (outdatedVersionLabel) {
const [, , issueVersion, latestVersion] = outdatedVersionLabel.split('-');
comment += `\n\n ${MESSAGE.OUTDATED_VERSION(issueVersion, latestVersion)}`;
labels.add('Newer Version Available');
}

await createComment({github, context, body: comment});
labels.add('Repro Provided');
labels.add('Waiting for Review');
};

const createComment = async ({github, context, body}) => {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
body,
});
};

const updateIssueLabels = async ({github, context, labels}) => {
const labelsToAdd = Array.from(labels).filter(
(label) => !label.startsWith('missing-') && !label.startsWith('outdated-'),
);

await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: labelsToAdd,
});
};

module.exports = handleIssue;
Loading

0 comments on commit 8611c0b

Please sign in to comment.