这篇文档基于官方的发版指南做提取和精简, 关注我们在发版过程中最容易忽视/犯错的部分, 所有参与发版的同学, 尤其是每个仓库/模块的负责人都需要完整, 仔细的通读一遍, 有不确定的地方务必及时沟通询问
注: 下文主要以已加入 incubator 项目为背景通俗描述, 不针对毕业项目和专有名词做额外解释说明
名词
一些文中出现的常见缩写:
- ASF: Apache Software Foundation
- APL2.0: Apache License 2.0
LICENSE
这里容易产生许多小问题, 请务必逐条确认检查: (不确定的一律以官方说明为准)
- 每个源码/二进制包(包括发行的 jar 包)都都必须提供
LICENSE + NOTICE + DISCLAIMER文件- 源码(source)包必须位于项目根目录下
- 二进制包呢? (参考其他项目一般也在根下, 但不清楚 ASF 是否有硬性要求)
LICENSE文件原始版本必须格式/内容完整正确, 请直接下载官方提供版本然后放在项目中LICENSE/NOTICE文件不可包含不必要的信息, 如果移除/更新了依赖则必须及时更新/移除对应的LICENSE/NOTICE信息- 引用的第三方/其他 license, 必须将详细信息附加到我们的
LICENSE文件后, 如果引用的LICENSE很长, 则需要单独存储并指向它们 - 二进制包还需要特别注意, 通常它携带的
LICENSE+NOTICE文件内容和源码包有巨大区别, 请勿直接复用同一文件- 源码包通常不携带二进制/jar 包等依赖, 所以它的 LICESEN 和 NOTICE 会干净简单许多, 但它通常需要对源码引用做声明
- 二进制包主要是要对大量引入的依赖做声明, 那它是否需要保持源码中引用的第三方代码声明呢? (这个)
- (待定) 一个依赖如果允许多个
LICENSE, (例如 apache & gpl), 建议引入LICENSE的依赖选择一个LICENSE, 而不是列出所有 (不方便他人 review?)- 同理, 如果这个依赖的 LICENSE 文件是独立存在的, 也应该只选取其中所选的内容 (例如去掉 GPL 的声明引用, 待确定? 是这个意思么?)
- 有些 ASF 项目在
LICENSE文件中引入依赖是列出了所有可选 LICENSE 条目, 但应该不是一个很建议的写法 (应避免参考)
除了阅读文档外, 最好的办法之一就是参考官方示例/其他 incubator 项目, 然后仍不确定的地方及时询问导师/社区 (不要自己猜测)
License Header
首先, Apache 要求每个源文件都有合适的 License, 考虑到简洁性它就规定在文件头部引用一个简略版本, 简称 header, 然后完整版本放在根下(LICESEN文件)中, 其实是这样的引用关系.
- 自己项目 License 文件头中不能包含
Copyright声明, 这部分应该考虑:- 如果不必要, 例如捐赠之前的 Copyright 自愿舍弃, 那直接移除即可
- 如果需要, 则在
NOTICE文件中声明
- 同时要注意, 如果是引用了第三方的代码 + License 头, 请不要删除/修改对方的
Copyright声明, 更不要通过插件添加了额外的APL2.0- 小修改/增加(对第三方代码), 一般应使用原本一样的 license, 不修改原本的 license/author 内容
- 大修改, ASF 建议是 PMC 具体讨论处理 (这里没有严格定义”大/小”修改的区分方式, 所以如无必要就视作小修改处理吧)
- 如果是在一个大(上千行)的文件中引用了一个内部结构体/类 (几十行), 我们此时该如何保留它的 license 头引用呢?
- 可以在代码的中间引用部分加上注释么? 还是必须在头部声明
- 如果在头部声明, 怎么和自有的
APL2.0兼容或者排版呢?
- 如果引用了其他开源项目的代码, 请不要修改原始的 License Header, 哪怕它格式/语法等有问题, 或者不够完整(精简版)
- 如果一个软件/代码包含多个可选许可, 请考虑以下二选一:
- 优先选择 Apache 最适配的A 类宽松许可, 避免不必要麻烦
- 如果原 license header 中已经同时提到了多种可选许可, 则不用修改
部分文件不需要添加 License Header, 原则是基于”内容/结构上没有任何创造性”, 如果不能确定, 则需要添加, 以下是参考各大社区项目和官方说明的几个典型不需要添加的例子:
- 简短的文本信息 (典型
READEME,CONTRIBUTING,*.txt,*.md,*.log以及各种 lint 配置文件) - 增加了头注释可能会报错的文件 (典型
json,svg文件) - 源码打包时可排除的文件, 例如
.github下的专用 action 文件,.git或类似的
以下是比较典型的建议但非强制添加的例子, 简而言之, ASF 建议除开不需要/很难添加的例子外, 应考虑一律加上 license header 以减少麻烦
- 包管理/依赖配置文件, 例如
Makefile/pom.xml等, ASF 建议如无必要, 都加一下免得引入纠纷 - 程序生成的模板/用户使用的
*.conf, *.properties文件可视具体情况 PMC 讨论, 不确定的或单元测试中使用的配置文件建议建议默认都带上 (或向上咨询)
另外如果存在压缩的 css/js 等文件, 如果是自己项目开发产生的, 则建议使用较短版本的声明, 而不建议使用原始的 header 版本
NOTICE
License 存放自己 + 第三方的许可证比较容易理解, NOTICE 文件又是做啥的呢? 简单说它可以存放 Copyright + (法律)强制性许可要求
- NOTICE 文件必须遵循 ASF 的标准规范, 不可随意修改格式 (建议参考已发版过的
incubating项目, 毕业项目可能有历史原因请勿直接照搬) - NOTICE 文件的
Copyright年份需要严格统一(例如有多个repo), 并且最终年份应该随发版时更新 - 如果我们引用了其他 ASF 的项目, 参考 (注意这和引用了
Apache2.0协议的项目不是等同的) - 尽可能保持
NOTICE简洁, 不确定的引用请咨询社群/导师, 别先假定需要, 因为它会给使用方(下游)带来负担 (传递性) - BSD/MIT 许可证内嵌的 Copyright 通知不需要重新引用 (LEGAL-59)
- 如果第三方依赖的
NOTICE文件错误的引用了LICENSE或者其他信息, 我们该如何选择?- 照搬原本的错误写法?
- 移除掉不正确的部分, 只保留合规的声明? (然后再予以说明?)
官方 + incubator示例:
- 最简模板 (推荐)
- seatunnel (推荐)
- HTTP Server (不太推荐)
Disclaimer
孵化中的项目的任何发行包(包括网站)都需要携带 DISCLAIMER (免责声明)文件, 这个听起来很法务化的文件有两个选择: (详见官方说明)
- 标准版: 可以遵循 ASF 的所有发布政策的孵化项目, 命名为
DISCLAIMER文件 - WIP 版本 (Work In Progress): 意味着发版过程中会有部分不能满足 ASF 要求的发布政策, 命名为
DISCLAIMER-WIP
两个说明的模板内容是不一样的, WIP 版本需要具体列出”已知问题列表“, 也就是提醒使用方这些地方可能需要留意检查, 另外要注意的是, 孵化项目在毕业前需要转为标准的 DISCLAIMER 声明 (也就意味着相关发布问题都被解决了)
但是哪些情况是 WIP 版本的免责声明可以容忍/携带的呢? 例如说 GPL 或是 CC-By 协议的二进制依赖可以么? 还是说它只适用于一些比较模糊的许可或者是合规性问题呢? (这个需要确认一下)
Copyright
版权的许可, ASF 的项目要求都放在 NOTICE 中而不能是 header 中, 这个是 ASF 单独要求的, 和其他自由使用并添加 Copyright 的项目无关, 并不是 Apache License 原本的要求, 特别说明一下以免误会
GPL
以 GPL 许可为代表的代码/二进制引用基本都不能被包含在 Apache 项目中, 或者简单说, 严格限制分发/商业化/的许可证基本都不能被引入, 详细列表参考官方禁止引用列表
这里的不能被包含就不止是说源码中不包含, 编译产生的二进制包理论上也不能包含, 所以使用了类似依赖/插件的部分代码需要移除/重构, 否则会非常棘手, 那有以下可供参考的常见做法:
- 将这种 Apache 不允许携带的引用变为可选项, 例如 oracle 的
ojdbc.jar包, 你可以写文档告诉需要的用户去自行下载然后关联/启用上 - 如果一个项目协议多种许可里只是包含了 GPL/LGPL, 那是不会影响你使用的
- 另外要注意
CC (Creative Commons)license, 如果单独出现 Apache 也是不允许的 (这个可能大家很容易忽视, 这里强烈建议使用插件扫描)
Binary/Archive
二进制文件 + 单独的 jar 包(视作 Archive 文件) 需要特别关注, 可规避大量不必要麻烦:
- 二进制文件在源码包中尽量不要出现, 如果 已存在的考虑通过编译/测试时通过下载 or 临时生成代替 (新 PR 应避免重新引入)
- tar 包解压出的普通文件 (例如
swagger-ui可提供 Apache 许可的前端包), 也尽量不要直接引入到源码, 而应在编译时下载代替 - 部分图片可能也会被视为二进制文件, 这部分如非源码必要, 可考虑打包时排除
- 如果是必要的图片/二进制, 则需要有清晰的引用说明 (这部分的示例需要找一下)
Hard Question
这里是一些暂时悬而未定的问题, 大多并没有从 ASF 官网上找到足够清晰的定义, 需要和导师/社区一起讨论:
如果引用第三方的代码(源码)后, 需要同时在 source & binary release 的不同
LICENSE文件中都添加引用么A: 是的, 都需要 (refer issue)
如果引入的第三方代码的
NOTICE原始文件就存在错误/不正确引用, 我们是否需要照搬A: 看情况应不用照搬错误部分, 只需要选取需要/合规的部分即可 (refer issue)
如果引入的第三方代码
license header中存在Copyright xx, 我们是否应该保留, 还是应该去掉然后在NOTICE中体现- 我们应尽保留原有
license header(不去修改它的格式/内容) - 只有捐给 ASF 的项目才会触发
Copyright转移到NOTICE的设定 (Copyright notices are only relocated if they are donated to the ASF as part of a software grant.)
- 我们应尽保留原有
如果引入的第三方代码只是某个代码文件中的一小部分, 是否应该用它的 license header 作为整个文件的头 (待定)
- 如果引入的是一个接口定义/子类/结构体, 可否直接在这部分代码片段上引入它的
license header - 如果不能在代码中间位置引入
license header, 那么头部是否允许保留两个license header(一个是 ASF 的, 一个是引入的) - 如果建议如无必要, 仅保留一个
license header, 是否需要在LICENSE文件中说明引入的代码行范围, 不引入的话似乎有点模糊(其他人不知道哪部分代码是 refer 的)
- 如果引入的是一个接口定义/子类/结构体, 可否直接在这部分代码片段上引入它的
持续更新 ing