Automate resource downloads and updates

Respresso lets you collaboratively manage localizations, images, colors and other resources and generates a variety of platform-specific files for your project. You can download these files as a zip archive, but it is a kind of tedious task we all want to avoid. This is why Respresso has an automated tool for this that can be integrated to your build process or executed manually when you need it.

Install the Respresso CLI

To use the Respresso CLI, you need to install it to you machine. It is a self-contained executable compiled to multiple platforms, so the installation is really easy and quick. Also, you can use it as a portable command if you don't want to install it to you system.

You will find the OS specific install instructions here:

Install the Respresso CLI

Use the Respresso CLI

Once you installed the Respresso CLI, you can use the respresso command from any terminal or console. To create the initial config file, you can use the respresso init command or you can create it manually.

Once you have a proper config, you can use the respresso sync command to download or update your resource files from the Respresso server.

How the Respresso CLI works?

The CLI is a highly customizable synchronization tool that will keep your local resource files up-to-date according to the files generated by Respresso. The Respresso CLI allows you to sync multiple Respresso projects in one command, so you can use a project as a module in a modularized project.

The CLI works somewhat similarly to a dependency manager, like npm. You have to specify the resources and their versions that are needed, and it will make sure that all the referenced files and only those are present locally. The CLI has a config file, named respresso.json that have a similar role to the package.json in npm. This config specifies which Respresso server should be used and which project's should be downloaded and where to place the downloaded files.

Once you run a sync, the Respresso CLI will create a respresso.lock file, that contains references to all the downloaded files and some meta info that it needs to keep track of the synced files. Using this lock file, the CLI is able to minimize the sync duration and network requests while maintaining consistency. It can even work in offline mode if all the necessary resource files are already present.

Let's take a look at a simple config file:

respresso.json
{
  "$schema": "https://app.respresso.io/public/schema/respresso-sync-config.schema.json",
  "projects": [
    {
      "name": "core-project"
      "token": "YOUR_PROJECT_TOKEN",
      "target": "core-project-dir",
      "resources": [
        "localization:json:feature-add-about-page",
        "color:android:1.0.5",
        "image:android:1.1.0",
        "font:android:1.0.0",
        "raw:android:1.0.0"
      ]
    }
  ]
}

To get started with the Respresso CLI, you just need to understand only these options. To learn more about the other config options, you should take a look at the config reference.

Specifying projects

The respresso.json contains a projects array that allows you to specify multiple projects you want to keep in sync at the same time. Using multiple projects comes handy when you have a modularized project structure where you need to handle each module's resources as a separate project in Respresso.
The same project can't be defined multiple times. Each project token and name must be unique.

Project token

The project token is a read only API key you that allows the CLI to download all the generated files from the Respresso server. Adding this token to your version control system is safe, as these files would be part of your sources anyway so leaking it wouldn't leak any more information. Keep in mind that leaking it to the released product may cause information leakage to the public as not yet released resources may include business secrets about your product.

The project token can be found in the Respresso app, on the project dashboard or in the project settings. This project token can be regenerated in the project settings in case you need to change it.
Don't confuse the project token with the integration token which can also be found on the project settings page. The project token is an uuid-v4 token like 16d83926-8d94-4f61-9de8-6a0da156b052, while the much longer JWT token.

Project name

The project name field is an optional name only used by the Respresso CLI when you want to sync only a subset of projects during sync. It also helps your future self or your colleagues to know which project is which.

For more information about the usage of the project name, see the --only-project option of the CLI's sync command.

Project target directory

The optional target field specifies the target directory of the project. It defaults to the same directory where the respresso.json is placed.

This is a simplified target override pattern, that matches all the files with the lowest priority and places all the files to the specified directory keeping the original directory structure generated by the Respresso server.

Specifying the resources you need

Each project has a resources field containing an array of resource specifiers. Each specifier must define the followings:

  1. Resource category. Currently, it must be one of these: localization, image, color, font, appIcon, raw
  2. Resource sync group. This is a platform or format name within the category. It can be customized from the Flow, but a few common values are android, ios, web, swift, objc, json, and jsonflat. You can find your actual sync groups in the version manager of the category.
  3. Resource version. Each category has a separate versioning system, so you need to specify the version of the category you need to sync. This can be a semver like 1.0.0 or a named version like feature-add-about-page.

There are multiple formats that the CLI can handle. The most simple version is the one that is in the above respresso.json example: Like category:group:version. E.g.: localization:json:1.0.0

In case you need to sync the same version of multiple formats as they depend on each other, you can use the following format:

{
  "category": "color",
  "version": "1.0.0",
  "groups": ["ios", "swift"]
}

The same can be achieved by the color:ios,swift:1.0.0 shorthand, but it may be confusing, so you should not use it. (The JSON schema does not allow it.)
Alternatively, you can use the first, simple form multiple times, but using it you must make sure that the versions are the same.

Let's put all of them in a single example:

respresso.json
{
  "projects": [{
      "resources": [
        "localization:json:1.2.5",
        {
          "category": "color",
          "version": "1.0.0",
          "groups": ["ios", "swift"]
        },
        "image:web,scss:1.1.0" // Works, but this is not preferred, please use the other ones
      ]
  }]
}

Add the synced files to VCS or ignore them?

Adding your resource files to your own version-control-system (VCS, like Git) is OK, but not convenient.
Why? Each time you need to merge them, it will be an inconvenience. Probably, you will accept one version, then running the sync again with the proper versions and committing the resource changes in a separate commit. (There is no reason to merge them as the next sync will override the file anyway with the version from the server.) This is why we don't recommend you to track the synced files in your own VCS.

Our recommendation

  1. Include the respresso.json config file to the VCS, so the whole team can sync the resources. When merging it, you will need to choose only between resource versions which is meaningful and easy.
  2. Ignore the respresso.lock file. It will change each time a resource file changes, and it is not meant to be human-readable. If you fail to merge it, the CLI will fail to run. The lock file does not contain any information that cannot be reproduced by the sync. (There is no ci command like in npm, that will reproduce the versions from the lock file. It will always download the most recent matching version.)
  3. We recommend you to ignore all the downloaded resource files.

The CLI can automatically ignore these files with the localGitIgnore option. The only trade-off is that everybody who works on the project will need to run the sync each time they checkout the project.

Although, we recommend ignoring the synced files, you should consider including them. There are many reasons you want to do this even if it is inconvenient. E.g.: You don't have to install the Respresso CLI on each machine you want to use to run/build your project, and you will have a backup of your resources in your own VCS.

Tell us your opinion about this

We know that this topic is highly sensitive, and we want to listen to our users. If you experience any drawbacks due to our recommendations, or you have a better solution, please feel free to contact us and start a discussion about it. You can reach out to us here: info@respresso.io

Need repeatable builds?

We understand that you use the VCS to be able to go back in time and rebuild your project no matter of the external dependencies. Respresso's versioning system gives you that option using the finalized versions feature. You can finalize a version, so it becomes read-only. The generated files are preserved, so you will be able to sync those files until the finalized version is not deleted. (If no changes can be applied, no conversions are executed. Your generated files will remain the same even if Respresso's internal converters change.)

If you need a reproducible checkpoint of your resources - most likely when you release a version of your product - you should copy the version and finalize the previous. This ensures you will be able to get those files when you need them.