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

Support multiple licensing products #661

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

ejnarvala
Copy link

@ejnarvala ejnarvala commented Aug 7, 2024

Changes

This change enables supporting unity floating license servers with multiple products configured, more info here.

  • adds an action parameter unityLicensingProductIds
  • updates services-config.json.template to set toolset based on unityLicensingProductIds. If this value is set to an empty string, it will use the server's default configuration, the same behavior as if the parameter was not included at alll

Related PRs

Related Issues

Successful Workflow Run Link

PRs don't have access to secrets so you will need to provide a link to a successful run of the workflows from your own
repo.

Checklist

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new optional input parameter for Unity licensing product IDs, enhancing customization for users.
    • Added a new environment variable for Unity licensing product IDs in the setup process, improving integration with Unity operations.
  • Bug Fixes

    • Corrected indentation for improved clarity in configuration files.
  • Tests

    • Added new test cases to ensure proper handling of Unity licensing product IDs and maintain test environment consistency.

Copy link

github-actions bot commented Aug 7, 2024

Cat Gif

@webbertakken
Copy link
Member

I don't have any knowledge about the floating license server or multiple configured products. Would it be possible to link relevant documentation or howtos from Unity?

Could someone verify that this change doesn't affect other use cases?

Copy link

coderabbitai bot commented Oct 10, 2024

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (2)
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduce a new optional input parameter, unityLicensingProductIds, to the action.yml file for the Unity Builder action. This parameter allows for the specification of Unity license product identifiers. Corresponding updates are made in the BuildParameters class to handle this new input, including a new property and test cases. Additionally, the ImageEnvironmentFactory and PlatformSetup classes are modified to incorporate the new environment variable UNITY_LICENSING_PRODUCT_IDS, ensuring proper integration into the existing configuration and setup processes.

Changes

File Path Change Summary
action.yml Added optional input parameter unityLicensingProductIds with a default value; corrected indentation for dockerWorkspacePath.
src/model/build-parameters.test.ts Added test case for unityLicensingProductIds; modified existing test to clean up environment variable.
src/model/build-parameters.ts Introduced new public property unityLicensingProductIds in BuildParameters class.
src/model/image-environment-factory.ts Added handling for new environment variable UNITY_LICENSING_PRODUCT_IDS in getEnvironmentVariables method.
src/model/input.ts Added static getter method unityLicensingProductIds to retrieve input value.
src/model/platform-setup.ts Modified SetupShared method to replace %LICENSE_PRODUCT_IDS% with buildParameters.unityLicensingProductIds.
src/model/platform-setup/setup-mac.ts Added UNITY_LICENSING_PRODUCT_IDS to setEnvironmentVariables method in SetupMac class.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Action
    participant BuildParameters
    participant ImageEnvironmentFactory
    participant PlatformSetup

    User->>Action: Trigger Action with unityLicensingProductIds
    Action->>BuildParameters: Create instance with unityLicensingProductIds
    BuildParameters-->>Action: Return instance with product IDs
    Action->>ImageEnvironmentFactory: Get environment variables
    ImageEnvironmentFactory-->>Action: Return environment variables including UNITY_LICENSING_PRODUCT_IDS
    Action->>PlatformSetup: Setup platform with new variables
    PlatformSetup-->>Action: Complete setup
Loading

🐰 In the meadow, where rabbits play,
New IDs for licenses come our way.
With hops and bounds, we cheer with glee,
For Unity's magic, as bright as can be!
So let’s configure, let’s set the stage,
In our burrows, we’ll write the next page! 🌼


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: 1

🧹 Outside diff range and nitpick comments (6)
src/model/platform-setup.ts (1)

Line range hint 1-42: Consider enhancing error handling and documentation

While the overall implementation is solid, consider the following suggestions for improvement:

  1. Add a comment explaining the purpose of the '%LICENSE_PRODUCT_IDS%' replacement for better code readability.
  2. Consider adding error handling for the case where buildParameters.unityLicensingProductIds might be undefined.
  3. Add logging (using core.debug) for the replacement operation to aid in troubleshooting.

Here's a suggested implementation incorporating these improvements:

 let servicesConfig = fs.readFileSync(servicesConfigPathTemplate).toString();
 servicesConfig = servicesConfig.replace('%URL%', buildParameters.unityLicensingServer);
-servicesConfig = servicesConfig.replace('%LICENSE_PRODUCT_IDS%', buildParameters.unityLicensingProductIds);
+// Replace the license product IDs placeholder with the user-specified values or an empty string if not provided
+const licenseProductIds = buildParameters.unityLicensingProductIds || '';
+servicesConfig = servicesConfig.replace('%LICENSE_PRODUCT_IDS%', licenseProductIds);
+core.debug(`Replaced %LICENSE_PRODUCT_IDS% with: ${licenseProductIds}`);
 fs.writeFileSync(servicesConfigPath, servicesConfig);

These changes will make the code more robust and easier to maintain in the future.

src/model/image-environment-factory.ts (1)

32-35: LGTM! Consider a minor improvement for consistency.

The addition of the UNITY_LICENSING_PRODUCT_IDS environment variable is well-implemented and aligns with the PR objectives to support multiple licensing products. The change is consistent with the existing pattern and doesn't affect other parts of the code.

For consistency with other Unity-related environment variables, consider moving this new variable next to UNITY_LICENSING_SERVER. This grouping could improve readability:

 {
   name: 'UNITY_LICENSING_SERVER',
   value: parameters.unityLicensingServer,
 },
+{
+  name: 'UNITY_LICENSING_PRODUCT_IDS',
+  value: parameters.unityLicensingProductIds,
+},
 { name: 'SKIP_ACTIVATION', value: parameters.skipActivation },
src/model/input.ts (1)

126-128: LGTM! Consider adding a brief comment.

The implementation of unityLicensingProductIds is correct and consistent with other methods in the class. It properly handles the case when the input is not provided.

Consider adding a brief comment to explain the purpose of this new input, for example:

/**
 * Get the Unity licensing product IDs for floating license servers with multiple products.
 * @returns {string} Comma-separated list of product IDs or an empty string if not specified.
 */
static get unityLicensingProductIds(): string {
  return Input.getInput('unityLicensingProductIds') ?? '';
}
action.yml (1)

254-260: LGTM! Consider a minor clarification in the description.

The addition of the unityLicensingProductIds parameter is well-implemented and aligns with the PR objectives. It's correctly set as optional with a default empty string, which maintains backward compatibility.

Consider slightly rewording the description for clarity:

  description:
-     'Comma separated list of license product identifiers to request licenses for from the license server. Not setting
-     this will request the default license product configured on the licensing server. Only applicable if
-     unityLicensingServer is set.'
+     'Comma-separated list of license product identifiers to request from the license server. If not set, the default
+     license product configured on the licensing server will be requested. This parameter is only applicable when
+     unityLicensingServer is set.'

This rewording maintains the same information while improving readability slightly.

src/model/build-parameters.ts (1)

25-25: Summary: Changes align well with PR objectives.

The addition of the unityLicensingProductIds property to the BuildParameters class successfully implements support for multiple licensing products as described in the PR objectives. The changes are minimal, focused, and consistent with the existing codebase structure.

To further improve this PR:

  1. Consider adding a brief comment explaining the purpose of unityLicensingProductIds.
  2. Ensure that this new property is properly utilized in other relevant parts of the codebase (e.g., in the services-config.json.template file mentioned in the PR summary).
  3. Update any relevant documentation to reflect this new capability for Unity floating license servers with multiple products.

Also applies to: 152-152

src/model/build-parameters.test.ts (1)

200-200: Approved: Improved test isolation, but consider broader test setup improvements.

The modification to delete the UNITY_LICENSE environment variable before the test runs is a good practice for ensuring test isolation. However, the comment suggests that this variable is set for every test, which might indicate a need for better overall test isolation.

Consider refactoring the test setup to avoid setting environment variables globally for all tests. Instead, you could use a beforeEach hook to set up the necessary environment for each test, and a afterEach hook to clean up. This would improve test isolation and reduce the need for inline environment variable management. For example:

describe('BuildParameters', () => {
  const originalEnv = process.env;

  beforeEach(() => {
    process.env = { ...originalEnv };
    process.env.UNITY_LICENSE = testLicense;
  });

  afterEach(() => {
    process.env = originalEnv;
  });

  // ... existing tests ...

  it('throws error when no unity license provider provided', async () => {
    delete process.env.UNITY_LICENSE;
    await expect(BuildParameters.create()).rejects.toThrowError();
  });
});

This approach ensures each test starts with a clean environment and reduces the risk of tests interfering with each other.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 461ecf7 and 6ca32fc.

⛔ Files ignored due to path filters (3)
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/unity-config/services-config.json.template is excluded by !**/dist/**
📒 Files selected for processing (7)
  • action.yml (1 hunks)
  • src/model/build-parameters.test.ts (1 hunks)
  • src/model/build-parameters.ts (2 hunks)
  • src/model/image-environment-factory.ts (1 hunks)
  • src/model/input.ts (1 hunks)
  • src/model/platform-setup.ts (1 hunks)
  • src/model/platform-setup/setup-mac.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (10)
src/model/image-environment-factory.ts (1)

32-35: Verify integration and maintain backwards compatibility

While the implementation looks good, consider the following points to ensure smooth integration and backwards compatibility:

  1. Verify that the unityLicensingProductIds parameter is properly handled in other parts of the codebase where DockerParameters is used.
  2. Ensure that the default behavior (when unityLicensingProductIds is not provided) remains unchanged to maintain backwards compatibility.

To help with verification, you can run the following script:

This script will help identify other places in the codebase where unityLicensingProductIds is used and where DockerParameters is implemented, allowing you to verify proper integration and default behavior handling.

✅ Verification successful

Verification Successful: No Issues Found

All usages of unityLicensingProductIds and DockerParameters have been verified across the codebase. The default behavior remains unchanged, ensuring backwards compatibility.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of unityLicensingProductIds and DockerParameters

# Test 1: Check for other occurrences of unityLicensingProductIds
echo "Checking for other occurrences of unityLicensingProductIds:"
rg "unityLicensingProductIds" --type typescript

# Test 2: Check for usage of DockerParameters
echo "\nChecking for usage of DockerParameters:"
rg "DockerParameters" --type typescript

# Test 3: Check for potential default value handling
echo "\nChecking for potential default value handling:"
rg "unityLicensingProductIds.*=.*undefined" --type typescript

Length of output: 585


Script:

#!/bin/bash
# Description: Check usage of unityLicensingProductIds and DockerParameters

# Test 1: Check for other occurrences of unityLicensingProductIds
echo "Checking for other occurrences of unityLicensingProductIds:"
rg "unityLicensingProductIds" --type ts

# Test 2: Check for usage of DockerParameters
echo "\nChecking for usage of DockerParameters:"
rg "DockerParameters" --type ts

# Test 3: Check for potential default value handling
echo "\nChecking for potential default value handling:"
rg "unityLicensingProductIds\\s*=\\s*undefined" --type ts

Length of output: 2165

src/model/platform-setup/setup-mac.ts (1)

171-171: LGTM with suggestions for improvement

The addition of the UNITY_LICENSING_PRODUCT_IDS environment variable aligns well with the PR objective of supporting multiple licensing products. The implementation follows the existing pattern and naming conventions, which is good for consistency.

However, I have a couple of suggestions to enhance this change:

  1. Consider adding validation for the unityLicensingProductIds value before setting the environment variable. This could help prevent potential issues with invalid input.

  2. It would be beneficial to verify that this change doesn't negatively impact existing functionality, especially for users who don't specify licensing product IDs.

To ensure this change doesn't affect existing functionality, we can check for any conditional logic related to this new environment variable:

This will help us understand how this new environment variable is being used and if there are any potential issues with existing code.

✅ Verification successful

Change Verified Successfully

The addition of the UNITY_LICENSING_PRODUCT_IDS environment variable has been verified. No conditional usages or impacts on existing functionality were found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of UNITY_LICENSING_PRODUCT_IDS in the codebase
rg "UNITY_LICENSING_PRODUCT_IDS" --type ts

Length of output: 252


Script:

#!/bin/bash
# Display the contents of src/model/image-environment-factory.ts for further analysis
cat src/model/image-environment-factory.ts

Length of output: 4934


Script:

#!/bin/bash
# Search for conditional usages of UNITY_LICENSING_PRODUCT_IDS
rg "UNITY_LICENSING_PRODUCT_IDS" --type ts | rg -e "if\s*\(" -e "\?\?" -A2

# Search for tests referencing UNITY_LICENSING_PRODUCT_IDS
rg "UNITY_LICENSING_PRODUCT_IDS" --glob "*.{test,spec}.ts"

Length of output: 133


Script:

#!/bin/bash
# Search for any conditional usages of UNITY_LICENSING_PRODUCT_IDS in TypeScript files
rg "UNITY_LICENSING_PRODUCT_IDS" --type ts | rg -e "if\s*\(" -e "switch\s*\(" -e "\?\?" -e "&&" -e "||" -A2

# Additionally, search for any function calls or manipulations involving UNITY_LICENSING_PRODUCT_IDS
rg "UNITY_LICENSING_PRODUCT_IDS" --type ts | rg -e "\." -e "=" -e "\+" -e "-"

Length of output: 601

src/model/input.ts (1)

126-128: Verify usage of the new input in related files.

The addition of unityLicensingProductIds is correct and doesn't affect existing functionality. However, to ensure full implementation:

Please run the following script to check for proper usage of the new input in other relevant files:

Ensure that:

  1. unityLicensingProductIds is properly defined as an input in action.yml.
  2. The new input is used in relevant TypeScript files where license-related logic is handled.
  3. Documentation is updated to mention this new capability.
action.yml (2)

Line range hint 261-264: LGTM! Indentation correction improves readability.

The indentation correction for the dockerWorkspacePath description improves the overall consistency and readability of the file.


254-260: Changes align with PR objectives and address raised concerns.

The addition of the unityLicensingProductIds parameter fully aligns with the PR objectives to support multiple licensing products for Unity floating license servers. This implementation addresses the core functionality described in the PR summary.

Regarding the concern raised by @webbertakken about the impact on other use cases:

  1. The parameter is optional, maintaining backward compatibility.
  2. When not set, it defaults to the server's default configuration, preserving existing behavior.

To further verify the impact on existing functionalities, we can run the following script to check for any unintended changes in other parts of the codebase:

This script will help ensure that the changes are isolated to the intended functionality and haven't inadvertently affected other parts of the codebase.

src/model/build-parameters.ts (3)

25-25: LGTM: New property declaration is consistent with existing code style.

The unityLicensingProductIds property is correctly declared as public and uses the non-null assertion operator, which is consistent with other properties in the class. The string type is appropriate for storing product IDs.


152-152: LGTM: New property correctly integrated into the create method.

The unityLicensingProductIds property is properly added to the return object in the create method. Its value is correctly sourced from Input.unityLicensingProductIds, consistent with how other properties are handled.


25-25: Consider adding documentation for the new property.

While the addition of unityLicensingProductIds is implemented correctly, it would be beneficial to add a comment explaining its purpose and expected usage. This would improve code maintainability and help other developers understand its role in the system.

Additionally, to ensure this change is fully integrated:

Let's verify if this new property is used in other parts of the codebase:

Also applies to: 152-152

src/model/build-parameters.test.ts (2)

203-209: LGTM: New test case for unityLicensingProductIds is well-implemented.

The new test case correctly verifies that the BuildParameters.create() method returns the unityLicensingProductIds as expected. It follows the established pattern of other tests in this file, mocking the input and asserting the output appropriately.


Line range hint 1-238: Summary: Good additions and improvements, with a suggestion for further enhancement.

The changes in this file appropriately support the PR objective of handling multiple licensing products. The new test case for unityLicensingProductIds is well-implemented and increases test coverage. The modification to the existing unity license provider test improves isolation.

However, there's an opportunity to enhance the overall test setup to ensure better isolation between all tests. Consider implementing a more robust setup/teardown mechanism as suggested in the previous comment.

Overall, these changes are approved with the recommendation to consider the suggested improvement for test isolation.

🧰 Tools
🪛 Biome

[error] 213-213: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

src/model/platform-setup.ts Show resolved Hide resolved
@ejnarvala
Copy link
Author

ejnarvala commented Oct 25, 2024

@webbertakken

I don't have any knowledge about the floating license server or multiple configured products. Would it be possible to link relevant documentation or howtos from Unity?

Yeah so here's Unity's docs on floating licensing servers: https://docs.unity.com/licensing/en-us/manual

I had linked this page which explains how to a floating licensing server can be configured to have multiple 'products' AKA 'toolsets' (I like to think of these as license pools).

This is also a good one to explain the configuration options for the client services-config.json: https://docs.unity.com/licensing/en-us/manual/ClientConfig

I think the relevant things to know here are that you can self-host a floating licensing server and that server can house multiple products which each have certain number of licenses/seats.

Clients can lease a license from the server as long as they have the services-config.json file which mainly defines the address of the licensing server so it knows where to make that request. The server is configured with a default product that it chooses the license from when no toolset is specified in the config file (or when the value is empty). This is what happens in unity-builder and unity-test-runner currently. In order to request license from multiple products/pools, the services-config.json needs to specify all the products (as a csv) it wants to consider getting licenses from.

Could someone verify that this change doesn't affect other use cases?

This is just an anecdote, but I've tested that having the toolset field as empty will result in using the default toolset, which is the same as the default behavior

@GabLeRoux
Copy link
Member

@coderabbitai draw a flow chart for these changes

Copy link

coderabbitai bot commented Oct 27, 2024

Tip

For best results, initiate chat on the files or code changes.

@GabLeRoux, here's a flowchart illustrating the changes introduced in this PR:

flowchart TD
    subgraph Action Input
        A[Add 'unityLicensingProductIds' to action.yml]
        A --> B[Create Input getter 'unityLicensingProductIds' in input.ts]
    end
    B --> C[Update BuildParameters with 'unityLicensingProductIds' property]
    C --> D[Modify ImageEnvironmentFactory to include 'UNITY_LICENSING_PRODUCT_IDS' env variable]
    D --> E[Update PlatformSetup to replace '%LICENSE_PRODUCT_IDS%' in services-config.json]
    E --> F[Update SetupMac to set 'UNITY_LICENSING_PRODUCT_IDS' environment variable]
    F --> G[Unity Builder now supports multiple licensing products]
Loading

Let me know if you have any questions!

# Conflicts:
#	dist/index.js.map
@GabLeRoux
Copy link
Member

GabLeRoux commented Oct 27, 2024

I've fixed the merge conflicts by simply merging origin/main into main and running npm run build again. Conflict was with dist folder.

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

Successfully merging this pull request may close these issues.

4 participants