silverstripe/silverstripe-graphql

SPIKE Investigate making default location of .graphql-generated folder inside /tmp

Closed this issue · 4 comments

Timebox: 2 days

Defaulting the .graphql-generated folder in the project root could be problem because this folder needs to be writable. Existing webservers may suddently break on upgrade if they are configured in a way that does not allow this folder to be created or be writable.

A safer/better alternative for the majority of use cases may be to default the .graphql-generated folder somewhere in /tmp (TEMP_FOLDER), possibly within the regular /tmp/silverstripe-cache-* where other files such as template files converted to php files are stored

There may be some reasons for wanting to have the .graphql-generated folder in the project root, for instance if the schema is generated in CI/CD as part of a packaged deployment. So we would need the ability to configure if the folder is stored in /tmp or in the project root. There is already configuration available through CodeGenerationStore.$dirName to configure the name of the folder.

Likely that there would only need to be minimal code changes in CodeGenerationStore.php made

ACs

  • Investigate if having the .graphql-generated located the /tmp folder is viable.
  • Schemas for multiple independent websites on the same server must not collide
  • Test on on prod-like webservers, including multi-server environments where the temp folder may not be shared by the instances behind a load balancer
  • If this seems doable, create a PR to 4.0 (which is still pre-stable)

Questions

  • Would we want to define a folder in the web root for new projects (i.e. via silverstripe/installer)?
    • This would make the schema more reliably available for these projects since it won't be cleared out whenever the temp dir is cleared
    • This would mean new projects need different permissions by default than existing projects at launch

PRs

There may be some reasons for wanting to have the .graphql-generated folder in the project root, for instance if the schema is generated in CI/CD as part of a packaged deployment. So we would need the ability to configure if the folder is stored in /tmp of in the project root. There is already configuration available through CodeGenerationStore.$dirName to configure the name of the folder.

That was our use case, generating on CI server and packaging it all up with composer dependencies installed and FE files compiled in a deployable package, so that the webserver can serve it right away.

I would also add to the ACs to test it in multi-server environments where the temp folder may not be shared by the instances behind a load balancer whereas assets folder would be.

Have added to ACs

Looks like CodeGenerationStore does already use TEMP_DIR as an intermediary step - this might be as simple as saying "if $this->config()->get('dirName') is empty, just leave the schema in the temp dir and use that" and then setting that config to null or an empty string initially.

Installer then might add yml config that sets it to .graphql-generated as a 'best practice'.

TEMP_DIR seems to check for where the silverstripe-cache directory is first though which is weird. So theoretically if you create a silverstripe-cache directory in your project root we're back to the same permissions issue again. We may not want to rely on that constant.

EDIT: We've talked a bit about this on slack. The short version is that the above is okay if we're defaulting to putting the generated schema inside the silverstripe-cache directory instead of next to it, which is okay because it is effectively a type of cache (and no different to, for example, cached template output).

The decision was made to leave this as-is in order to retain our release schedule. We will need to ensure our documentation clearly indicates that a change may be required for all projects which don't currently have a writable project root.