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

Use unity-changeset package to scrape versions #55

Merged
merged 8 commits into from
Nov 18, 2024

Conversation

AndrewKahr
Copy link
Member

@AndrewKahr AndrewKahr commented Nov 17, 2024

Changes

  • Use unity-changeset package to scrape Unity versions with graphQL

Checklist

  • Read the contribution guide and accept the code of conduct
  • Readme (updated or not needed)
  • Tests (added, updated or not needed)

Summary by CodeRabbit

  • New Features

    • Added a new dependency, graphql, enhancing data handling capabilities.
  • Improvements

    • Streamlined the process for retrieving Unity version information, improving efficiency and reliability.
    • Updated various dependencies to their latest versions for better performance and security.
  • Bug Fixes

    • Updated logic to ensure only valid Unity versions are returned, preventing errors from non-qualifying versions.
  • Chores

    • Removed the outdated utility function for fetching HTML documents, simplifying the codebase.
    • Updated GitHub Actions workflow to use the latest version of firebase-action.

Copy link

coderabbitai bot commented Nov 17, 2024

Walkthrough

The pull request updates the functions/package.json file with several dependency version changes and the addition of a new dependency, graphql. The scrapeVersions function in scrapeVersions.ts has been modified to streamline the retrieval of Unity version information by utilizing the unity-changeset module instead of fetching documents from a URL. The utility function getDocumentFromUrl has been removed as it is no longer necessary for this process. Updates to the GitHub Actions workflow file reflect the version upgrade of firebase-action.

Changes

File Path Change Summary
functions/package.json Updated dependencies: @octokit/auth-app to ^6.1.3, firebase-admin to ^12.7.0, firebase-functions to ^6.1.0, added graphql ^16.9.0, updated semver to ^7.6.3, updated @types/node to ^22.9.0, updated @types/ws to ^8.5.13, updated typescript to ^5.6.3.
functions/src/logic/ingestUnityVersions/scrapeVersions.ts Modified scrapeVersions function to use unity-changeset for retrieving Unity versions; updated regex for version parsing; simplified filtering logic.
functions/src/logic/utils/get-document-from-url.ts Removed utility function getDocumentFromUrl(archiveUrl: string) as it is no longer needed.
.github/workflows/main.yml Updated w9jds/firebase-action version from v13.10.2 to v13.25.0 in multiple jobs.

Poem

🐇 In the garden of code, new blooms arise,
With unity-changeset, we reach for the skies.
Scraping versions with ease, no more tangled threads,
A hop and a skip, where the old logic treads.
Let’s dance through the changes, with joy we embrace,
For every new line, brings a smile to our face! 🌼

Warning

Rate limit exceeded

@AndrewKahr has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 23 minutes and 14 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 71c3e05 and c421140.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
functions/src/logic/ingestUnityVersions/scrapeVersions.ts (2)

4-4: Consider using a named regex pattern for better maintainability

The regex pattern correctly captures Unity version components, but readability could be improved.

Consider using a named regex pattern:

-const unity_version_regex = /^(\d+)\.(\d+)\.(\d+)([a-zA-Z]+)(-?\d+)$/;
+const unity_version_regex = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?<lifecycle>[a-zA-Z]+)(?<build>-?\d+)$/;

This would make the version parsing more explicit and self-documenting.


9-33: Add error handling for empty or undefined unityVersions

The current error handling could be more informative.

Consider enhancing the error handling:

-if (unityVersions?.length > 0) {
+if (!unityVersions) {
+  throw new Error('Failed to fetch Unity versions: received undefined response');
+}
+
+if (unityVersions.length === 0) {
+  throw new Error('No Unity versions found in the response');
+}
+
+const parsedVersions = unityVersions
   .map((unityVersion) => {
     // ... existing mapping logic
   })
   .filter((versionInfo): versionInfo is EditorVersionInfo => versionInfo !== null);
+
+if (parsedVersions.length === 0) {
+  throw new Error('No valid Unity versions found after filtering');
+}
+
+return parsedVersions;
-}
-
-throw new Error('No Unity versions found!');
functions/package.json (1)

29-29: Consider pinning the unity-changeset version

Since this package is crucial for the core functionality of scraping Unity versions, consider pinning the exact version instead of using the caret range (^2.3.0). This would prevent unexpected breaking changes from minor version updates.

-    "unity-changeset": "^2.3.0"
+    "unity-changeset": "2.3.0"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fe20df7 and 71c3e05.

⛔ Files ignored due to path filters (1)
  • functions/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • functions/package.json (1 hunks)
  • functions/src/logic/ingestUnityVersions/scrapeVersions.ts (1 hunks)
  • functions/src/logic/utils/get-document-from-url.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • functions/src/logic/utils/get-document-from-url.ts
🔇 Additional comments (1)
functions/src/logic/ingestUnityVersions/scrapeVersions.ts (1)

7-7: Verify SearchMode.Default behavior

The code uses SearchMode.Default without documenting the expected behavior or potential limitations.

Let's verify the available search modes and their documentation:

Comment on lines +11 to +29
.map((unityVersion) => {
const match = RegExp(unity_version_regex).exec(unityVersion.version);
if (match) {
const [_, major, minor, patch, lifecycle, build] = match;

const allVersions = new Map<string, EditorVersionInfo>();

for (const script of scripts) {
if (script.textContent) {
const matches = [...script.textContent.matchAll(unity_version_regex)];
if (matches.length > 0) {
const versions = matches
.filter((match) => {
// Filter out prerelease and unsupported versions
const [_, major, minor, patch, changeSet] = match;
return patch.includes('f') && Number(major) >= 2017;
})
.map((match) => {
const [_, major, minor, patch, changeSet] = match;
const version = `${major}.${minor}.${patch}`;
if (!allVersions.has(version)) {
return {
version,
changeSet,
major: Number(major),
minor: Number(minor),
patch,
};
}

// Return null if version is not unique
if (lifecycle !== 'f' || Number(major) < 2017) {
return null;
})
.filter((version) => version !== null) as EditorVersionInfo[];

versions.forEach((it) => {
allVersions.set(it.version, it);
});
}
}
}

if (allVersions.size > 0) {
return Array.from(allVersions.values());
}

return {
version: unityVersion.version,
changeSet: unityVersion.changeset,
major: Number(major),
minor: Number(minor),
patch,
} as EditorVersionInfo;
}
return null;
})
Copy link

@coderabbitai coderabbitai bot Nov 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider improving version filtering logic and error handling

The current implementation has several areas for improvement:

  1. The filtering logic (lifecycle !== 'f' || Number(major) < 2017) seems to exclude final releases after 2017
  2. Failed regex matches silently return null
  3. No logging for rejected versions

Consider this improved implementation:

 .map((unityVersion) => {
   const match = RegExp(unity_version_regex).exec(unityVersion.version);
   if (match) {
     const [_, major, minor, patch, lifecycle, build] = match;
 
-    if (lifecycle !== 'f' || Number(major) < 2017) {
+    const majorVersion = Number(major);
+    // Include final releases (f) for versions >= 2017
+    if (lifecycle === 'f' && majorVersion >= 2017) {
+      return {
+        version: unityVersion.version,
+        changeSet: unityVersion.changeset,
+        major: majorVersion,
+        minor: Number(minor),
+        patch,
+      } as EditorVersionInfo;
+    }
+    console.debug(`Skipping version ${unityVersion.version}: ${lifecycle !== 'f' ? 'non-final release' : 'old version'}`);
     return null;
-    }
-
-    return {
-      version: unityVersion.version,
-      changeSet: unityVersion.changeset,
-      major: Number(major),
-      minor: Number(minor),
-      patch,
-    } as EditorVersionInfo;
   }
+  console.warn(`Failed to parse version string: ${unityVersion.version}`);
   return null;
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.map((unityVersion) => {
const match = RegExp(unity_version_regex).exec(unityVersion.version);
if (match) {
const [_, major, minor, patch, lifecycle, build] = match;
const allVersions = new Map<string, EditorVersionInfo>();
for (const script of scripts) {
if (script.textContent) {
const matches = [...script.textContent.matchAll(unity_version_regex)];
if (matches.length > 0) {
const versions = matches
.filter((match) => {
// Filter out prerelease and unsupported versions
const [_, major, minor, patch, changeSet] = match;
return patch.includes('f') && Number(major) >= 2017;
})
.map((match) => {
const [_, major, minor, patch, changeSet] = match;
const version = `${major}.${minor}.${patch}`;
if (!allVersions.has(version)) {
return {
version,
changeSet,
major: Number(major),
minor: Number(minor),
patch,
};
}
// Return null if version is not unique
if (lifecycle !== 'f' || Number(major) < 2017) {
return null;
})
.filter((version) => version !== null) as EditorVersionInfo[];
versions.forEach((it) => {
allVersions.set(it.version, it);
});
}
}
}
if (allVersions.size > 0) {
return Array.from(allVersions.values());
}
return {
version: unityVersion.version,
changeSet: unityVersion.changeset,
major: Number(major),
minor: Number(minor),
patch,
} as EditorVersionInfo;
}
return null;
})
.map((unityVersion) => {
const match = RegExp(unity_version_regex).exec(unityVersion.version);
if (match) {
const [_, major, minor, patch, lifecycle, build] = match;
const majorVersion = Number(major);
// Include final releases (f) for versions >= 2017
if (lifecycle === 'f' && majorVersion >= 2017) {
return {
version: unityVersion.version,
changeSet: unityVersion.changeset,
major: majorVersion,
minor: Number(minor),
patch,
} as EditorVersionInfo;
}
console.debug(`Skipping version ${unityVersion.version}: ${lifecycle !== 'f' ? 'non-final release' : 'old version'}`);
return null;
}
console.warn(`Failed to parse version string: ${unityVersion.version}`);
return null;
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too sure about this suggestion, but on the other hand, the previous implementation used to be this:

patch.includes('f') && Number(major) >= 2017

So that little bunny might have found something here. Not exactly sure what are the implications tho.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GabLeRoux, the suggestion aims to clarify the version filtering logic and improve error handling.

In the previous implementation, the filtering condition was:

patch.includes('f') && Number(major) >= 2017

In the current code, the condition is:

if (lifecycle !== 'f' || Number(major) < 2017) {
  return null;
}

This means that any version where the lifecycle is not 'f' (final release) or the major version is less than 2017 will be excluded.

The suggested change flips the logic to:

if (lifecycle === 'f' && majorVersion >= 2017) {
  // include the version
  return {
    version: unityVersion.version,
    changeSet: unityVersion.changeset,
    major: majorVersion,
    minor: Number(minor),
    patch,
  } as EditorVersionInfo;
}
console.debug(`Skipping version ${unityVersion.version}: ${lifecycle !== 'f' ? 'non-final release' : 'old version'}`);
return null;

Implications:

  • Clarity: The inclusion criteria are made explicit by checking for versions where lifecycle === 'f' and majorVersion >= 2017. This enhances readability and understanding.
  • Logging: By adding debug statements, you gain visibility into which versions are being skipped and why. This can be helpful for troubleshooting and ensuring the filtering logic is working as intended.
  • Error Handling: Logging a warning when a version string fails to parse helps identify unexpected version formats returned by the unity-changeset package.

Overall, the suggestion doesn't change the inclusion criteria but refines the logic for better clarity and adds helpful logging. It should function the same as the previous implementation but with improved maintainability.

Let me know if you have any questions or if you'd like to proceed with these changes!

functions/package.json Outdated Show resolved Hide resolved
@AndrewKahr AndrewKahr linked an issue Nov 17, 2024 that may be closed by this pull request
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
.github/workflows/main.yml (1)

Line range hint 65-71: Consider optimizing cleanup steps.

The cleanup of testFunction appears in both testDeploy and deploy jobs. Since deploy job runs after testDeploy (as specified in needs), and testDeploy already includes cleanup, the second cleanup in the deploy job might be redundant.

Consider removing the redundant cleanup step from the deploy job to simplify the workflow.

  deploy:
    name: ✨ Deploy
    needs: [test, build, testDeploy]
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'yarn'
      - name: install dependencies
        run: yarn && yarn --cwd ./functions
      - name: Deploy to Firebase
        uses: w9jds/[email protected]
        with:
          args: deploy
        env:
          GCP_SA_KEY: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_UNITY_CI_VERSIONS }}'
-     - name: Cleanup Firebase Test
-       uses: w9jds/[email protected]
-       if: always()
-       with:
-         args: functions:delete testFunction --force
-       env:
-         GCP_SA_KEY: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_UNITY_CI_VERSIONS }}'

Also applies to: 92-98

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 71c3e05 and c421140.

⛔ Files ignored due to path filters (2)
  • functions/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (2)
  • .github/workflows/main.yml (3 hunks)
  • functions/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • functions/package.json
🔇 Additional comments (1)
.github/workflows/main.yml (1)

56-56: Verify firebase-action version upgrade implications.

The upgrade from w9jds/[email protected] to v13.25.0 appears consistent across all jobs. However, it's important to verify the changes between these versions.

Also applies to: 66-66, 87-87, 93-93

✅ Verification successful

Firebase action version upgrade appears safe

The version upgrade from v13.10.2 to v13.25.0 consists of only minor version bumps of the underlying firebase-tools package, with no breaking changes or security concerns reported. All changes are routine version updates that maintain backward compatibility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the changelog and releases between v13.10.2 and v13.25.0

# Fetch release information between the versions
gh api repos/w9jds/firebase-action/releases --paginate | \
  jq -r '.[] | select(.tag_name | contains("v13.")) | select(.tag_name >= "v13.10.2" and .tag_name <= "v13.25.0") | "Version: \(.tag_name)\nDate: \(.published_at)\nChanges:\n\(.body)\n---"'

# Check if the new version is widely adopted (by checking recent dependent workflows)
gh api search/code -f q='path:.github/workflows w9jds/[email protected]' | \
  jq -r '.items | length'

Length of output: 3785

Copy link
Member

@GabLeRoux GabLeRoux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not try this locally and I'm a bit curious about the versions comparison as noted here there's a small discussion about readability: https://github.com/game-ci/versioning-backend/pull/55/files#r1845401236

I think it's better to give this a try than keeping a non-working workflow anyway. Nice work Andrew, thanks for taking the time to fix that 🙏
LGTM 🚀 :shipit:

@AndrewKahr AndrewKahr merged commit 016f95a into main Nov 18, 2024
5 checks passed
@AndrewKahr AndrewKahr deleted the fix-unity-version-scrape branch November 18, 2024 00:44
@GabLeRoux
Copy link
Member

GabLeRoux commented Nov 18, 2024

We got notified of these in our internal logs:

3 new Unity editor versions detected.
(6000.0.27f1, 6000.0.26f1, 2022.3.52f1)

That looks good 👍

581 updated Unity editor versions detected.

I assume this is updated metadata. I can confirm only the missing images are being built 👍 :

CleanShot 2024-11-17 at 19 54 04@2x

Nicely done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update Unity Versions Crawler Due to Changes on Unity Archive Page
2 participants