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 field to support "license" #218

Closed
Eomm opened this issue Jun 3, 2019 · 36 comments · Fixed by #220
Closed

support field to support "license" #218

Eomm opened this issue Jun 3, 2019 · 36 comments · Fixed by #220
Labels
package-maintenance-agenda Agenda items for package-maintenance team

Comments

@Eomm
Copy link
Member

Eomm commented Jun 3, 2019

In the slack channel there are the raw notes written down by @craftninja 👏 , during the OpenJS Summit.

The main feedback we get is that the support field in our draft could be more attractive if not included in the package.json.

The reasons pointed out are:

  • it affects parsing (micro) performance for new ejs module
  • what should be the semver change for this kind of addition?
  • if there is a licence in package.json and LICENCE file, the last one wins
  • the support changes across versions, but if I use an older version of the module, what is the support field?
  • if a package is abandoned the module need to be released?

So the suggestions received are:

  • Github support SUPPORT.md
  • Wouldn't support have the same "signal" as a license separate JSON for support?
  • How do we create solutions that are language agnostic? Could we do something that has that "signal" like a license?
  • we could approach the OSI about this, think about a bigger scale, package.json could limit our ability to scale
  • tidelift is doing something like this?

Let's reinvent our draft support in a best solution ✌

(I will post my thought in a separate post)

@craftninja
Copy link
Contributor

I added the notes and slides here, and am planning on reviewing next meeting, but definitely pull things out to specifically discuss if it is necessary!

@craftninja
Copy link
Contributor

@Eomm did you want to tag this with package-maintenance-agenda to discuss next meeting?

@wesleytodd
Copy link
Member

wesleytodd commented Jun 3, 2019

what should be the semver change for this kind of addition?

This is one of the most important questions in this I think. IMO a meaningful change in the support model can be a breaking change. This would be a great thing to have strong documentation on before rolling this out.

the support changes across versions, but if I use an older version of the module, what is the support field?

I think there might be some work here around "deprecated support models" on a project. Like if you were supported by a company then left said company, now the old support model cannot be accepted anymore, does that also make the package deprecated? If we tie support and license into semver, we might get a bunch of issues like this. Maybe it would be better to version them separately? Something like "Support model 1 applies <v2.0.0 and support model 2 applies >=v2.0.0". If we could capture that in the single file format it would be great because we could avoid tying them together under semver versioning I think.

if a package is abandoned the module need to be released?

Lol, well the support model changed to unsupported. So yeah it would be optimal to release a version which updates the support field.

think about a bigger scale

While I am all on board for "solving the worlds problems", I am worried about increasing scope beyond reason. I think making it a file instead of a package.json field is a great idea, but if we try to solve this for all people for all time we might end up with some un-usable or incomplete product.


In general I think we should explore what other ecosystems are doing, and maybe companies like Tidelift and Open Collective. If we find that getting consensus with larger groups to be a problem we should keep focus on node. I think that if we can solve the problem in a node specific way, it would satisfy the goals of the working group.

@ljharb
Copy link
Member

ljharb commented Jun 3, 2019

I don’t think I’m convinced by the package.json arguments. Adding a json key won’t meaningfully affect parsing perf, and there’s already tons of other config that lives there.

As far as the license, the file does not necessarily win - it hasn’t been tested in court, and i can absolutely see a spdx compliant license field trumping a separate license file, in some scenarios.

Yes, any change in support will always require a publish, regardless of where it lives, because it’s part of the package - not some side channel metadata.

@wesleytodd
Copy link
Member

I don’t think I’m convinced by the package.json arguments. Adding a json key won’t meaningfully affect parsing perf, and there’s already tons of other config that lives there.

I sort of agree, but I think having a file format might give us more room to grow in the long run.

Yes, any change in support will always require a publish, regardless of where it lives, because it’s part of the package - not some side channel metadata.

You are right, but I was hoping we could find some way to avoid the issue of having to publish tons of extraneous versions when the code parts of a package are not changing. I think probably this is unavoidable though.

@ljharb
Copy link
Member

ljharb commented Jun 3, 2019

Until that’s fixed for readmes, i don’t think it should/can be fixed for other things ¯\_(ツ)_/¯

@mhdawson mhdawson added the package-maintenance-agenda Agenda items for package-maintenance team label Jun 5, 2019
@mhdawson
Copy link
Member

mhdawson commented Jun 5, 2019

I've tagged so its on the agenda for the next meeting. Once we talk through the different options and have agreed on what direction we want to go I'll take a cut at updating our doc.

I like the suggestion that the entry in the package.json point to a file (remote or part of the package). Allowing it to be remote allows the support info to be changed without a release. I think @sam-github's point that support is not necessarily tied to a particular release is valid. In addition in many cases the support qualities are not specific to a particular version. For example if the backing is COMPANY and that company decides to no longer invest in the module that likely applies to ALL versions of the module, not just the latest one which is what would be implied if a new version of the module was published with a 'Support-backing' entry in the package.json

I guess I'm saying that I don't agree with:

Yes, any change in support will always require a publish, regardless of where it lives, because it’s part of the package - not some side channel metadata.

and instead the support info is more likely tied to the overall module. I do agree that it might be different for ranges of versions but even in that case the support level might change for a range separately from when those versions were published.

@Eomm
Copy link
Member Author

Eomm commented Jun 5, 2019

I mainly agree that moving the info in a separate file is ok.
In the package.json I would add only a link as per bug field that usually link the /issues of the repo:

  "support": {
    "url": "https://github.com/user/repo#SUPPORT"
  },

Let's say that this "support licence" should explain:

  • how is the support for range version from a specific version*
  • how the support can be contacted
  • an agreement on how long could be the notice in case of support changes (it could become better 24-7 or worse)
  • how to pay (vpay, paypal, bitcoin 😜)
  • what happens if the support is not respected (?)
  • example:
    from 0 to 2 = support none
    from 3 to 4 = support BEST-EFFORT
    from 5 = support REGULAR-1

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

we'd need something programmatic, not a link to a human-readable markdown section.

For what it's worth tho, I still think support is tied to each version of a module. If you release v1.2.3 under a certain support commitment, you should have to provide that support to that version forever, just like a license applies forever. If we want to build in expiration, or updating, that should be part of the support claim, and not implicit.

@Eomm
Copy link
Member Author

Eomm commented Jun 5, 2019

we'd need something programmatic, not a link to a human-readable markdown section.

the second one doesn't exclude the first one: I saw, for example, a special format for issue templating in Github and also in some headless CMS that apply:

---
metadata: hello
metadata2: world
...
---
readable markdown

(IDK if it is standard or defacto standard)

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

very true, but it seems much more awkward if we insist people bury HTML comments or similar in their prose.

@pi0
Copy link
Contributor

pi0 commented Jun 5, 2019

One other point about why not distributing support via NPM package is that the support terms of a package may change at any time by the maintainer/company and not predicted ahead of time.

Agree with @Eomm that we can point support field to an external live URL so package managers can always fetch the latest state like this:

{
  "support": "gh:org/repo/branch/support.json"
}

The JSON file (or any other format that describes support status) describes support in two terms: General and Version specific:

{
  "contact": {
    "bugs": "https://github.com/org/repo/issues/new",
    "security": "mailto:security@nodejs.com"
  },
  "funding": {
    "open_collective": "",
    "btc": ""
  },
  "versions": {
    "^1.0.0": {
      "status": "unsupported"
    },
    "^2.0.0": {
      "status": "lts",
      "expires": "1/1/2025"
    },
    "^3.0.0": {
      "status": "bugs-only",
      "expires": "1/1/2020"
    },
    "^3.2.0": {
      "status": "active",
      "expires": "1/1/2020"
    }
  }
}

(not sure about version ranges. maybe major would be enough but would be also a good idea to open SPEC for minor support status as well)

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

To me that's the exact reason it shouldn't be a file - support for a version is something you should commit to for the forseeable future, not something you should be able to revoke at any time. this, bu Whether it's part of the package tarball or not, it would need to have some sort of irrevocable/immutable way to communicate and update this information (like npm publishing), and neither a git repo, nor a URL, are those things.

@pi0
Copy link
Contributor

pi0 commented Jun 5, 2019

@ljharb Agree and see your point about making it permanent/immutable across releases. This probably involves adding another release in that range if maintainer decides to change support policy for a specific range but probably worth as of simplification.

What do you think about allow inlining like this:

{
  "support": {
    "status": "lts",
    "expires": "1 year",
    "contact": {
      "security": "mailto:security@nodejs.com"
    },
    "funding": {
      "open_collective": "",
      "btc": ""
    }
  }
}

The expires field is optional and can help to ensure automatically invalidating support promise if there is no update for a specific range for a long time.

@Eomm
Copy link
Member Author

Eomm commented Jun 5, 2019

I think that forever support in the package.json for a version it would be practicable only for companies.

And for example, if I have:

  • v1 support regular7
  • v2 support regular1

and I want to change the v1 support to none, I'm restricted to release as minor or patch.

How maintainers could apply forever support?
A licence may change across version, but it is about how the client uses the source code, with the support we are talking about how the client uses the time of the maintainer.

@pi0
Copy link
Contributor

pi0 commented Jun 5, 2019

I believe we can support both methods (distributed with pkg or external reference) and individuals/companies can choose between them. They can even switch method in any release/time and we can observe what method will be more adopted.

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

I'm not a company, and I will be supporting all 100+ packages I maintain forever. Most of them require effectively zero ongoing maintenance cost. (in your example, it's trivial to publish a backport patch to v1 that alters the support imo)

@vweevers
Copy link

vweevers commented Jun 5, 2019

I'm not a company, and I will be supporting all 100+ packages I maintain forever.

There's intent, and then there's reality.

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

@vweevers very true, but so far they're the same :-) and i think it's reasonable that i have to publish a new version when that changes.

@dominykas
Copy link
Member

I'm not a company, and I will be supporting all 100+ packages I maintain forever.

I must 🙇 down to you for the spirit (genuinely), but let's face it - the whole reason this group exists is because very few people have the same commitment as you do. Nor should they.


Do we need to take a step back and revisit why do we even have this support field? What are its use cases?

  • The way I see it - it's an indicator, so that people who are looking to chose a package can make a somewhat educated decision. These people are unlikely to look into the package.json - I'd guess they would just look at the badge in the README.
  • There's a case for tooling that businesses might use to get an overall picture of how well their packages are (or aren't...) supported.
  • There's a case of using it for some ecosystem stats, but that's only if there's adoption (and is there?)

I think the currently specified draft serves these purposes well enough and while the concerns raised are valid, I'm wondering if we're heading towards overengineering before we get feedback from actual maintainers trying to use it on their packages?


There's no way to enforce the support commitment - it's nowhere near a legal contract (nor should it be). So as an indicator, all it does is give an overview of a situation at a give point in time, i.e. at the moment you're looking at it, so I doubt semver even plays into this. So here's some updates we can make in the spec:

  • it might be worth adding a timestamp field? The timestamp would basically say "this is the support level at that given moment in time", which would hopefully imply that "this might have changed since, and nobody bothered to update it" - similar to how you have a (c) year in a license.
  • I like the idea of adding an expiry field, with a default.
  • not updating the field when situation changes is fair play (and maintainer getting hit by a bus is not the only valid excuse for degraded support), so we should probably add that "npm deprecate notice trumps the support field" to avoid the need to re-publish.
  • we might want to add a note to the spec, that latest version support trumps earlier versions.
  • we might want to add a note on which versions are covered by support. I would say the default could be "latest major", but we could have separate fields to cover other cases, e.g. "latest 2 majors", "majors released in the last 12 months", "all non-deprecated majors".

While I do feel that from the purity perspective, a pointer to a separate file at a canonical URL to define the support level is probably a better choice, I think that asking people to add yet another file might be too much and that the simple field in package.json would gain more adoption.

@ljharb
Copy link
Member

ljharb commented Jun 5, 2019

i like a timestamp field (maybe as_of?), along with an optional expiry field, both ISO date strings.

Agreed that npm deprecate can trump the support notice, that way an individual version can be unsupported even if it was published with support.

I'm not convinced about "latest trumps earlier versions", i think "support field + deprecate" is sufficient to cover older versions.

I like those enhancements - ie, describing a moving window of support.

@sam-github
Copy link

@ljharb

I'm not a company, and I will be supporting all 100+ packages I maintain forever.

Whatever your good intentions, that's simply not true, unless you live forever!

Whether we think people should abandon support for a module or not, people do, so building a mechanism that doesn't allow what people actually do to be communicated seems like its destined for difficulty. Also, some people might decide they want to offer MORE support for old versions, perhaps they decide to offer paid support for old versions, forcing a republish of a new version to change support for an old version seems awkward.

I love the simplicity of embedding support info in the npm package, its very attractive, but given the package is immutable, and support is mutable, that isn't going to work well.

@wesleytodd
Copy link
Member

we'd need something programmatic, not a link to a human-readable markdown section.

I agree with this in general, but I think some flexibility here is good. I think we could adopt a yaml block like @Eomm points out, which is both human and machine readable. Then we could also allow a more verbose description field which people can give their more details support info. I do think we could restrict it to a whole SUPPORT.md file, instead of a partial from another file like README.md#support. Would make parsing much more simple, as we can just do the --- yaml document separator between the structured header and the open ended description.

(IDK if it is standard or defacto standard)

It is a standard part of yaml. https://yaml.org/spec/1.2/spec.html#id2760395

like a timestamp field (maybe as_of?), along with an optional expiry field, both ISO date strings.

I really like the expires, but I think the as_of is just the package publish date right? Which we can already get from the registry metadata.

we might want to add a note on which versions are covered by support.

I think any specification we make needs to support multiple support blocks for differing version ranges. If we did a yaml document like we mentioned above it could be like:

---
target: ABANDONED
response: NONE
backing: NONE
versions: <3
---
target: SUPERSET
response: BEST-EFFORT
backing: SPONSORED
versions: >=3
...

given the package is immutable, and support is mutable, that isn't going to work well.

I think this is a reality we must embrace. If for nothing else exactly the point @sam-github brings up about offering paid support for older versions, which is something we should promote!

@mhdawson
Copy link
Member

mhdawson commented Jun 6, 2019

What I was initially thinking is that we could use the same json we'd defined, simply export it to a separate file instead of having it in the package.json. I've heard many complaints about yaml files so not sure on switching to that.

EDIT: although I do agree we might want to extend it to that we can have an entry per version range.

I also agree with

given the package is immutable, and support is mutable, that isn't going to work well.

@wesleytodd
Copy link
Member

I've heard many complaints about yaml files

I guess my thinking there was that at least yaml has comments and is relatively human readable. But I don't strongly care, JSON is good with me.

@ljharb
Copy link
Member

ljharb commented Jun 7, 2019

toml > > > yaml, but json is probably simplest.

@pi0
Copy link
Contributor

pi0 commented Jun 7, 2019

Is there anything preventing us to support json5 comments? :D

@ljharb
Copy link
Member

ljharb commented Jun 7, 2019

no need, json has comments:

{
  "some field": "this is a comment!", 
  "some field": "this is the real value of the field"
}

tools that cause the comment to be discarded are broken :-p

@Eomm
Copy link
Member Author

Eomm commented Jun 7, 2019

Starting from the @pi0 proposal I would try to propose this version:

{
  "support": [
    {
      "version": "<=1", // semver range
      "target": "abandoned",
      "response": "none",
      "response-paid": "regular-1",
      "backing": [
        "paid-support",
        "sponsored"
      ],
      "expires": "2019-08-01T20:47:27.840Z"
    },
    {
      "version": ">=2.0.0",
      "target": "lts",
      "response": "regular-7",
      "response-paid": "regular-1",
      "backing": "hobby",
      "expires": "2021-08-01T20:47:27.840Z"
    }
  ],
  "contact": {
    "url": "http://support.it/issue",
    "security": "mailto:security@nodejs.com",
    "paid-channel": "mailto:iwantmoney@nodejs.com"
  },
  "funding": {
    "open-collective": "",
    "btc": ""
  }
}

@wesleytodd
Copy link
Member

Should we move funding and contact into the support key? Seems like funding is part of the support model.

PS lol iwantmoney@nodejs.com

@Eomm
Copy link
Member Author

Eomm commented Jun 7, 2019

My idea was to define an array of support based on the versions range and I thought the contacts and funding were constant across all the versions.

@wesleytodd
Copy link
Member

wesleytodd commented Jun 7, 2019

the contacts and funding were constant across all the versions

Are they? What I meant was that sometimes if the maintainer changes the funding or contact info changes along with it. Maybe we could support both ways and let the version one supersede the global one?

EDIT: or maybe it is alright to throw away the old info when it changes? I don't know.

@mhdawson
Copy link
Member

I think moving the contact info into the support key is the safest approach and I don't think there will be so many variations that any duplication will matter.

@mhdawson
Copy link
Member

Should have also said I also think moving the funding into the support key also makes sense.

@Eomm
Copy link
Member Author

Eomm commented Jun 11, 2019

Do you mean like this (without replicating the funding and contacts for each versions)?

{
  "support": {
    "versions": [
      {
        "version": "<=1", // semver range
        "target": "abandoned",
        "response": "none",
        "response-paid": "regular-1",
        "backing": [
          "paid-support",
          "sponsored"
        ],
        "expires": "2019-08-01T20:47:27.840Z"
      },
      {
        "version": ">=2.0.0",
        "target": "lts",
        "response": "regular-7",
        "response-paid": "regular-1",
        "backing": "hobby",
        "expires": "2021-08-01T20:47:27.840Z"
      }
    ],
    "contact": {
      "url": "http://support.it/issue",
      "security": "mailto:security@nodejs.com",
      "paid-channel": "mailto:iwantmoney@nodejs.com"
    },
    "funding": {
      "open-collective": "",
      "btc": ""
    }
  }
}

Then I will try to make a PR as the next step

@mhdawson
Copy link
Member

@Eomm I meant moving contact and funding into the objects in the"versions" section to that each of those entries could have different contacts and funding info. It covers the most different situations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package-maintenance-agenda Agenda items for package-maintenance team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants