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

1.23.0 release caused breaking change in bundle output option when APIs are not specified #1776

Open
imdex-brett-debeer opened this issue Oct 18, 2024 · 7 comments
Labels
Type: Bug Something isn't working

Comments

@imdex-brett-debeer
Copy link

imdex-brett-debeer commented Oct 18, 2024

Describe the bug

Release 1.23.0 introduced #1715. Fix #1717 resolved the issue when API names are provided as arguments but did not correct the problem when no API names are provided.

To Reproduce

We have the following make command to bundle some spec files:

npx @redocly/cli bundle -o ./generated/

As of 1.23.0, it outputs a single file named generated.yaml in the ./ folder:

.
└── generated.yaml

Expected behavior

Before, it would output one file per spec file to the ./generated/ folder.

.
├── generated
    ├── some_spec_file.yaml
    ├── another_spec_file.yaml
    └── ...

OpenAPI description

OAS 3.0.0

Redocly Version(s)

I've tried the following versions but expect it applies to all versions since 1.23.0

  • 1.25.7
  • 1.23.1
  • 1.23.0

Node.js Version(s)

v20.10.0

OS, environment

Ubuntu 22.04.5 LTS in WSL on Windows 11

Additional context

Changing redocly-cli/packages/cli/src/commands/bundle.ts line 78 to the below might solve the problem.

        entries: apis.length,
@imdex-brett-debeer imdex-brett-debeer added the Type: Bug Something isn't working label Oct 18, 2024
@tatomyr
Copy link
Contributor

tatomyr commented Oct 18, 2024

Before, it would output one file per spec file in API_FILES to the ./generated/ folder.

Hi @imdex-brett-debeer, could you clarify what you mean by API_FILES?

Are you using redocly.yaml file with the apis section specified? If yes, you can specify the output filenames for each entry as in this example from the docs:

apis:
  orders@v1:
    root: orders/openapi.yaml
    output: dist/orders.json
  accounts@v1:
    root: accounts/openapi.yaml
    output: dist/accounts.json

imdex-brett-debeer added a commit to imdex-brett-debeer/redocly-bundle-repro that referenced this issue Oct 18, 2024
@imdex-brett-debeer
Copy link
Author

Hi @tatomyr,

Apologies API_FILES was copied from #1715 by mistake.

I've created redocly-bundle-repro as a minimal reproduction.

@tatomyr
Copy link
Contributor

tatomyr commented Oct 18, 2024

Thanks! I’d still recommend defining the output paths explicitly in your config file though. The issue with the previous behaviour is that some might refer to the same API description file multiple times in the apis section with different decorators so they'll be stored under the same name, making it unclear which exact bundle gets stored in the output.

@imdex-brett-debeer
Copy link
Author

Hi @tatomyr,

Setting the output path in the config file is not equivalent to the behaviour previously provided, unfortunately.
Prior to 1.23.0, --output allowed specification of an output path or an output directory, while the config file only allows specification of a path.

@tatomyr
Copy link
Contributor

tatomyr commented Nov 12, 2024

while the config file only allows specification of a path.

Yes, that was a deliberate decision to avoid any ambiguity about which file represents each of the apis entries. We should probably clarify this in the documentation.

In your example, you can achieve the same behaviour as before just by specifying your original apis (e.g. using the glob pattern):

npx @redocly/cli bundle openapi/* -o ./generated/

Please let me know if that works for you.

imdex-brett-debeer added a commit to imdex-brett-debeer/redocly-bundle-repro that referenced this issue Nov 13, 2024
…li#1776 (comment))

- added output properties to the config file.
- updated the command to the recommended one.
- added the museum@json API that uses the same root file as the museum API
@imdex-brett-debeer
Copy link
Author

npx @redocly/cli bundle openapi/* -o ./generated/ doesn't bundle APIs with different names but the same root file.

I've updated my reproduction repository to demonstrate.

The test below should also demonstrate what occurs if added to packages/cli/src/tests/commands/bundle.test.ts

    it('should store bundled API descriptions in the directory specified in argv IF multiple positional api names provided AND --output specified', async () => {
      const apis = {
        foo: {
          root: 'foo.yaml',
          output: 'output/foo.yaml',
        },
        fooJson: {
          root: 'foo.yaml',
          output: 'output/foo.json',
        },
        bar: {
          root: 'bar.yaml',
          output: 'output/bar.json',
        },
      };
      const config = {
        apis,
        styleguide: {
          skipPreprocessors: jest.fn(),
          skipDecorators: jest.fn(),
        },
      } as unknown as Config;
      // @ts-ignore
      getFallbackApisOrExit = jest
        .fn()
        .mockResolvedValueOnce(
          Object.entries(apis).map(([alias, { root, ...api }]) => ({ ...api, path: root, alias }))
        );
      (getTotals as jest.Mock).mockReturnValue({
        errors: 0,
        warnings: 0,
        ignored: 0,
      });

      await handleBundle({
        argv: { apis: ['foo', 'fooJson', 'bar'], output: 'dist' }, // cli options
        version: 'test',
        config,
      });

      expect(saveBundle).toBeCalledTimes(3);
      expect(saveBundle).toHaveBeenNthCalledWith(1, 'dist/foo.yaml', expect.any(String));
      expect(saveBundle).toHaveBeenNthCalledWith(2, 'dist/foo.json', expect.any(String));
      expect(saveBundle).toHaveBeenNthCalledWith(3, 'dist/bar.yaml', expect.any(String));
    });

@tatomyr
Copy link
Contributor

tatomyr commented Nov 13, 2024

doesn't bundle APIs with different names but the same root file.

Yes, and that's one of the reasons the output option was added to redocly.yaml. It allows for much more flexible configuration and granular control over the output destinations. The inline --output option is mostly intended for simple cases when you don't have any sophisticated transformations (especially involving different transformations of the same source file).

The case in your latest example wouldn't work with a version prior to v1.23.0 (unless I'm missing something) because:

  • the output field in the apis section was not supported
  • both museum@json and museum would anyway be stored under the same name

And I still don't get why using the output in apis doesn't work for you 😅.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants