spec icon indicating copy to clipboard operation
spec copied to clipboard

devcontainer-feature.json : Add a new 'alias' property to allow Feature renames

Open samruddhikhandale opened this issue 2 years ago â€ĸ 5 comments

Reported in https://github.com/devcontainers/features/issues/123, there is a request to rename an existing Feature (docker-from-docker to docker-outside-of-docker). Currently, if we simply rename all the docker-from-docker references (ie. source code, and Features metadata) to docker-outside-of-docker , then the CLI will publish this as a new Feature.

In this case, people referencing to docker-from-docker will get stuck and not get any updates until they manually change it to docker-outside-of-docker. In order to prevent this and add backwards compatibility, as discussed in here, we can add a new alias property to devcontainer-feature.json to safely rename a feature.

Adding this new alias property will be beneficial for the community, it will provide an ability to rename any Feature without any dev config breaks.

From https://github.com/devcontainers/features/issues/123#issuecomment-1249890748 👇

We decided to move forward with the alias idea so that we can safely rename a feature, and if the devcontainer-feature.json has an alias property, we will continue to publish it under the aliased name. So the source code and everything can move to the new name, but we will publish both old and new names for backwards compatibility.

When we next bump up the major version, we will likely remove the alias since major version bumps already signify breaking changes and that's a good time to fully stop publishing the old name.

Once we implement alias support, we will rename docker-from-docker to docker-outside-of-docker.

samruddhikhandale avatar Nov 30 '22 17:11 samruddhikhandale

Goal

Allow renaming an existing Feature with dual publishing.

Proposal

Add a new alias property to the devcontainer-feature.json -

Property Type Description
alias string Set if the Feature needs to be published under an aliased name. The property is useful for renaming an already published Feature.

Renaming a Feature

An already published Feature can be renamed by adding an alias property to the devcontainer-feature.json. The source code can be changed to a new name along with devcontainer-feature.json properties (like id, name, documentationURL etc). The value of alias property is the current id of the Feature which needs renaming.

The supporting tools will publish the Feature with both old (using alias property) and new (using id property) names.

Notes

  • As the id of the current Feature will be changed, the devcontainer-collection.json will no longer contain the old id.
  • The value of id and alias properties can not be same in the devcontainer-feature.json file

samruddhikhandale avatar Nov 30 '22 21:11 samruddhikhandale

I'd suggest renaming alias to something less neutral - perhaps a deprecatedIds array that we will still publish to, but that we can handle appropriately in downstream tooling. What do you think?

joshspicer avatar Dec 08 '22 17:12 joshspicer

I'd suggest renaming alias to something less neutral - perhaps a deprecatedIds array that we will still publish to, but that we can handle appropriately in downstream tooling. What do you think?

Yep, I like that name.

samruddhikhandale avatar Dec 08 '22 17:12 samruddhikhandale

When I wrote this proposal of adding this new property for renaming a Feature, it was keeping the registry and namespace intact. It could simply change the id. (eg. ghcr.io/devcontainers/features/x can only be renamed to ghcr.io/devcontainers/features/y).

If we decide to support renaming across namespaces (even across registries in future), then we'd need more authentication. A simple GITHUB_TOKEN won't be sufficient in this scenario. 🤔 Not sure if we'd want to currently support that or wait for a request from the community for cross namespace renames.

What do you think @Chuxel ?

samruddhikhandale avatar Dec 08 '22 17:12 samruddhikhandale

If we decide to support renaming across namespaces

I think a good first pass for this would be re-aliasing inside a single namespace. The property could even just accept an ID (for now),

{
  "id": "docker-outside-of-docker",
  "deprecatedId": [
    "docker-from-docker"
  ]
}

and if we wanted to extend this in the future, we could additionally allow fully-qualified identifiers as well (eg: docker.io/<my_new_namespace>/docker-from-docker).

I think for now, erroring this case would be fine (until we got feedback such behavior would be useful)

joshspicer avatar Dec 08 '22 17:12 joshspicer

Would the tar at the old location have the exact same content as at the new location? I guess the "deprecatedIds" (plural I assume?) can be picked up by the indexer and included in the index, so UIs can decide to show an info/warning when a devcontainer.json uses the old id?

chrmarti avatar Dec 15 '22 08:12 chrmarti

Iterating the proposal to accommodate https://github.com/devcontainers/spec/issues/155 and formalizing a detailed proposal.

Adding two new properties to the devcontainer-feature.json 👇

alias

Example: Let's say we currently have a docker-from-docker Feature 👇

Current devcontainer-feature.json :

{
    "id": "docker-from-docker",
    "version": "2.0.1",
    "name": "Docker (Docker-from-Docker)",
    "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-from-docker",
    ....
}

We'd want to rename this Feature to docker-outside-of-docker. The the source code folder of the Feature will be renamed to docker-outside-of-docker and the updated devcontainer-feature.json will look like 👇

{
    "id": "docker-outside-of-docker",
    "version": "2.0.2",
    "name": "Docker (Docker-outside-of-Docker)",
    "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker",
    ....
}

Note - The semantic version of the Feature defined by the version property should be continued and should not be restarted at 1.0.0.

How backwards compatibility can be handled for the installsAfter property when a Feature is renamed

  • Currently the installsAfter property is defined as an array consisting of the Feature id that should be installed before the given Feature.
  • The Feature to be renamed could be already defined by other Feature authors in their installsAfter property. Renaming the id could change the installation order for them if the installsAfter property is not updated with the new id. In order to avoid this unexpected behavior and to support back compat, the CLI tooling will be updated to also look at the alias property along with the id for determining the installation order.

Few ways in which the alias property will be used by the supporting tools

isDeprecated

  • Type: boolean and default value: false
  • If this property is set to true, then it indicates that the Feature is deprecated and won't be receiving any further updates/support. The OCI artifacts would exist, hence, the current dev configs will continue to work.
  • This property could be used by the supporting tools to indicate Feature deprecation in few ways -

samruddhikhandale avatar Dec 15 '22 19:12 samruddhikhandale

Would the tar at the old location have the exact same content as at the new location?

@chrmarti Yes, same exact tgz of the new id will pushed to the old id. Described it in detail in https://github.com/devcontainers/spec/issues/146#issuecomment-1353625555

I'd suggest renaming alias to something less neutral - perhaps a deprecatedIds array that we will still publish to, but that we can handle appropriately in downstream tooling. What do you think?

In an offline discussion, decided to keep the property name as alias. As interpreted from https://github.com/devcontainers/spec/issues/155 and from a group discussion, we've realized that the term deprecated could be perceived in two different ways. Deprecated either means there will be no support for some piece of code or some code is deprecated in favor of something else. To avoid this misinterpretation, decided to stick with alias // cc @joshspicer

I guess the "deprecatedIds" (plural I assume?) can be picked up by the indexer and included in the index, so UIs can decide to show an info/warning when a devcontainer.json uses the old id?

@chrmarti Yep, Yep! Added details in the comment above.

samruddhikhandale avatar Dec 15 '22 19:12 samruddhikhandale

alias (or rather aliases?) to me means "equally valid ids". Do we want users to move off of these? If so, maybe oldIds or legacyIds would be clearer?

Maybe deprecated is more common than isDeprecated? (E.g., JSON schema itself uses deprecated.)

chrmarti avatar Dec 16 '22 12:12 chrmarti

Example: Let's say we currently have a docker-in-docker Feature 👇

Probably docker-from-docker?

eitsupi avatar Dec 16 '22 13:12 eitsupi

alias (or rather aliases?) to me means "equally valid ids". Do we want users to move off of these? If so, maybe oldIds or legacyIds would be clearer?

Yep, makes sense to me. I like legacyIds 👍

Maybe deprecated is more common than isDeprecated? (E.g., JSON schema itself uses deprecated.)

Good call 👍 sounds good.

samruddhikhandale avatar Dec 16 '22 18:12 samruddhikhandale

Formalized to a PR --> https://github.com/devcontainers/spec/pull/163

samruddhikhandale avatar Dec 19 '22 19:12 samruddhikhandale

Closing as completed with https://github.com/devcontainers/cli/pull/346 & https://github.com/devcontainers/cli/pull/335 🚀

samruddhikhandale avatar Jan 03 '23 22:01 samruddhikhandale

Thank you for implementing this. I tried setting deprecated, but is deprecated still not included in the metadata? Or is it just a problem with the display on the log? https://github.com/eitsupi/devcontainer-features/actions/runs/3834679292/jobs/6527285373#step:3:61 image

eitsupi avatar Jan 04 '23 02:01 eitsupi

For deprecated we haven't changed any CLI logic, or updated the metadata. The flag will only be used by the supporting tools to highlight its deprecation.

We are still allowing publishing this Feature, in case of a security vulnerability.

More details: https://github.com/devcontainers/spec/pull/163/files#diff-af72b90352b50d5f93c0dc94d88eba484e95de30f4c6fa6797ae2a1debe33034R75

samruddhikhandale avatar Jan 04 '23 17:01 samruddhikhandale

Thanks, however, it was not my intention to republish this Feature in the index. (See #155) Will deprecated Features be removed from the index in the future?

image

eitsupi avatar Jan 04 '23 17:01 eitsupi

Yes, I am planning to update the indexing logic to make use of deprecated flag.

â„šī¸ For the devcontainers/action, I merged a change to update the README file with this info --> https://github.com/devcontainers/action/commit/977880a0a17dd1f95b04cba35bf1b6722d9e75be

samruddhikhandale avatar Jan 04 '23 17:01 samruddhikhandale

Sounds good! The action now works fine. https://github.com/eitsupi/devcontainer-features/blob/main/src/just/README.md

eitsupi avatar Jan 04 '23 17:01 eitsupi

Yes, I am planning to update the indexing logic to make use of deprecated flag.

PR --> https://github.com/devcontainers/devcontainers.github.io/pull/120

samruddhikhandale avatar Jan 04 '23 22:01 samruddhikhandale

@eitsupi https://containers.dev/features no longer lists the deprecated just Feature! 🎉

samruddhikhandale avatar Jan 04 '23 22:01 samruddhikhandale