Compare commits

...

121 Commits
3.0.0 ... v5.x

Author SHA1 Message Date
dependabot[bot]
e6f2616609 feat: bump actions/github-script from 8 to 9 (#178) 2026-04-14 00:07:56 +02:00
Romain Lespinasse
ef035f61a9 docs: Reorganize documentation with new reference and explanation sections (#176)
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-12 14:02:09 +01:00
Romain Lespinasse
9e7def6155 feat: Pin sub-actions to full commit SHAs (#175) 2026-02-04 10:46:51 +01:00
Copilot
e8d233181c Pin sub-actions to full commit SHAs (#175)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rlespinasse <1280212+rlespinasse@users.noreply.github.com>
2026-02-04 10:37:36 +01:00
dependabot[bot]
6f7a8d2348 feat: bump actions/checkout from 5 to 6 (#172) 2025-11-26 00:49:56 +01:00
dependabot[bot]
ac4a3a2668 feat: bump actions/github-script from 7 to 8 (#170)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2025-10-19 23:37:27 +02:00
Romain Lespinasse
6772bda8f6 docs: fix moved links (#168) 2025-08-29 17:32:02 +02:00
dependabot[bot]
846af0aca2 build(deps): bump actions/checkout from 4 to 5 in the dependencies group (#167) 2025-08-20 19:16:48 +02:00
dependabot[bot]
c33ff65466 feat: bump super-linter/super-linter from 7 to 8 (#166) 2025-07-29 05:40:44 +02:00
Romain Lespinasse
50025f78ad docs(security): document the end of life of the v4.x branch (#165) 2025-06-07 23:17:54 +02:00
Romain Lespinasse
8e1194b8b1 build: use codeowners file (#164)
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2025-06-07 22:48:03 +02:00
Romain Lespinasse
fe13438220 ci(linter): use super-linter/super-linter (#160) 2025-04-12 15:18:19 +02:00
Romain Lespinasse
810e74b089 docs: improve README file (#159) 2025-03-14 06:10:45 +01:00
Romain Lespinasse
26e0654625 docs: update code of conduct (#158) 2025-03-11 20:45:43 +01:00
dependabot[bot]
955b5ba456 feat: bump actions/github-script from 6 to 7 (#157)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 04:15:50 +01:00
Romain Lespinasse
ba00826602 ci(check-variables): print a warning if a GITHUB_* variable from this action already exists (#155) 2025-03-08 01:11:51 +01:00
Romain Lespinasse
797666298f docs: improve warning on short auto sizing (#154) 2024-11-17 21:22:32 +01:00
Romain Lespinasse
56d132125c docs(references): add a new article in the french section (#152)
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-11-10 05:21:04 +01:00
Romain Lespinasse
aba9f8db6e feat: use GITHUB_REF_POINT as variable for the branch name (#149)
BREAKING CHANGE: Change the behavior of GITHUB_REF_NAME to match the default GitHub Action behavior,
BREAKING CHANGE: Introduce GITHUB_REF_POINT as a replacement for GITHUB_REF_NAME to match this GitHub Action behavior in v4.
2024-11-06 00:16:25 +01:00
Romain Lespinasse
63a442f83b build: prepare v5.x branch (#148)
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-11-01 10:11:33 +01:00
dependabot[bot]
c6c92fed42 ci: bump github/super-linter from 6 to 7 (#146)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-02 23:45:16 +02:00
Romain Lespinasse
7c4f489627 build: cleanup old npm packages from GitHub dependency graph
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-07-16 08:54:31 +02:00
Romain Lespinasse
45c9d47db8 docs(security): update supported versions
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-06-24 22:37:23 +02:00
dependabot[bot]
797d688647 feat: bump github/super-linter from 5 to 6 (#145)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-30 22:30:49 +02:00
Romain Lespinasse
55f5982579 ci(build): use personal token (#144) 2024-01-24 17:14:44 +01:00
Romain Lespinasse
5ee5b39fa5 build(dependabot): fix updates groups syntax (#143)
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-01-04 22:26:25 +01:00
Romain Lespinasse
399f2aa780 build(dependabot): update slugify-value and shortify-git-revision as new features (#142)
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2024-01-04 21:58:27 +01:00
dependabot[bot]
87a6de197b build(deps): bump the dependencies group with 1 update (#141) 2023-12-25 17:32:00 +01:00
Romain Lespinasse
6e13412dd5 build(dependabot): move to v2 configuration (#139) 2023-12-25 15:10:58 +01:00
Romain Lespinasse
00d4236bb3 docs(security): fix wrong markdown link
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2023-10-24 15:55:43 +02:00
Romain Lespinasse
e5042e702f docs(security): simplify the end of life process 2023-10-20 12:34:43 +02:00
Romain Lespinasse
d1ca8ffbce ci(linter): setup super linter workflow 2023-06-11 11:34:00 +02:00
Romain Lespinasse
094dd7fdb3 docs(security): improve vulnerability reporting section
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2023-03-14 19:49:15 +01:00
Romain Lespinasse
4bf56f04ea docs(readme): rework article/talk links
Signed-off-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2023-02-28 09:23:48 +01:00
二丫讲梵
552f3c0362 docs(readme): add new link in the article section 2023-02-28 09:19:47 +01:00
Romain Lespinasse
102b1a064a fix: use github.head_ref env var as trusted input 2023-02-20 11:57:12 +01:00
Romain Lespinasse
a362e5fb42 feat: support GHES step output management 2022-10-31 19:55:46 +01:00
Nick Reynolds
b011e83cf8 fix: update dependencies to remove internal warnings
Update slugify-value to 1.3.3
Update shortify-git-revision to 1.5.1

Signed-off-by: Nick Reynolds <nickittynack@users.noreply.github.com>
2022-10-17 21:21:57 +02:00
Vin
00198f8992 fix: use environment file to manage outputs
Co-authored-by: Vin <vin@8sistemas.com>
Co-authored-by: Romain Lespinasse <romain.lespinasse@gmail.com>
2022-10-15 20:56:22 +02:00
Romain Lespinasse
9c3571fd3d feat: generate proper git tag 2022-10-02 22:52:40 +02:00
Romain Lespinasse
0141d9b38d fix: remove trailing hypen if any after cut 2022-06-16 19:55:01 +02:00
rlespinasse
33cd7a701d docs(README): improve the overwrite troubleshooting section 2022-04-16 19:25:44 +02:00
rlespinasse
2c5a627861 fix(GITHUB_REF_NAME): correctly fill the variable on pull request events 2022-04-16 19:25:44 +02:00
Romain Lespinasse
aa95092e35 docs: remove badges 2022-04-09 08:12:02 +02:00
rlespinasse
1615fcb48b fix: preserve dash groups 2022-04-08 23:48:02 +02:00
rlespinasse
812bd42f94 fix: remove underscore from URL-compliant slugs 2022-04-08 23:48:02 +02:00
Romain Lespinasse
6839855732 ci: rename workflow 2022-04-07 20:47:54 +02:00
rlespinasse
53459a86e2 ci: improve workflow 2022-03-24 12:59:58 +01:00
Romain Lespinasse
4177734b38 docs: cleanup 2022-03-24 08:14:21 +01:00
Romain Lespinasse
ad808ea8b2 fix: do not replace group of dashes with a single dash 2022-03-24 08:13:33 +01:00
rlespinasse
7a3b4c1766 fix: set short-length automatically when no checkout 2022-03-22 15:41:41 +01:00
rlespinasse
dbbe21b72b feat: add option to set a different short length than git defaults 2022-03-21 16:47:28 +01:00
Romain Lespinasse
88f3ee8f6f feat: add option to set a different slug length than 63 2022-03-19 22:50:08 +01:00
rlespinasse
cd9871b66e fix(short): populate GITHUB_SHA_SHORT correctly 2022-03-19 11:35:00 +01:00
Romain Lespinasse
1fb0eeb01e docs(readme): reword troubleshooting section 2022-01-01 15:15:35 +01:00
Romain Lespinasse
bd31a9f564 docs(security): add end of life of branch section 2022-01-01 15:06:51 +01:00
Romain Lespinasse
78ed3f92ee ci: enable v4.x release 2022-01-01 14:23:29 +01:00
rlespinasse
c1ec67827c ci: build and release
Also the test part compare v3.x and v4.x exported variables
(when it's possible to do so).
2022-01-01 14:17:59 +01:00
rlespinasse
e91720375f feat: support prefix on exported variables 2022-01-01 14:17:59 +01:00
rlespinasse
e13c7fcc34 refactor: remove all node related files 2022-01-01 14:17:59 +01:00
rlespinasse
4405613430 feat: use composite action instead of node
Using composite with two actions:
- rlespinasse/slugify-value for the SLUG features
- rlespinasse/shortify-git-revision for the SHORT feature

Since the SHORT sha is now based on a shorted git revision,
and no more on a fix substring.

BREAKING CHANGE: use different backend for the action
2022-01-01 14:17:59 +01:00
rlespinasse
5d786b4cd2 docs(security): remove support of v2.x branch 2022-01-01 14:17:59 +01:00
rlespinasse
ba2cfdae8a docs: use v4.x references 2022-01-01 14:17:59 +01:00
rlespinasse
200b9d942b ci: prepare v4.x release branch 2021-12-05 00:27:10 +01:00
rlespinasse
046be07299 build: fix npm vulnerabilities 2021-12-04 22:00:29 +01:00
rlespinasse
38b80287e3 ci: use matrix for os testing 2021-12-04 21:26:47 +01:00
Romain Lespinasse
c559dac9da docs(example): use dedictated domain exemple name 2021-10-30 09:25:40 +02:00
Romain Lespinasse
2f05f8b5cb docs(readme): add Michael Heap article 2021-09-29 16:29:38 +02:00
dependabot[bot]
9f53b89c13 build(deps): bump semver-regex from 3.1.2 to 3.1.3 2021-09-21 17:12:59 +02:00
semantic-release-bot
172fe43594 chore(release): 3.6.0 [skip ci]
# [3.6.0](http://github.com/rlespinasse/github-slug-action/compare/3.5.1...3.6.0) (2021-09-15)

### Features

* add GITHUB_REF_NAME env var ([12a7510](12a7510630))
2021-09-15 15:01:24 +00:00
Antoine Méausoone
12a7510630 feat: add GITHUB_REF_NAME env var
GITHUB_REF_NAME will contain the reference name (branch or tag)
  - based on GITHUB_HEAD_REF in a pull-request event context,
  - based on GITHUB_REF in others event contexts.
2021-09-15 17:00:11 +02:00
rlespinasse
b71a8a1cbc build: fix potential security vulnerabilities 2021-09-02 21:56:17 +02:00
Joshua Chaitin-Pollak
54910e921d docs: minor grammatical fixes for clarity 2021-08-04 23:07:16 +02:00
rlespinasse
35d90c4a71 build: update transitive dependencies 2021-06-14 22:44:11 +02:00
rlespinasse
ada34a0888 docs: fix link to use by badge 2021-04-17 23:19:39 +02:00
rlespinasse
6370faccb7 docs: improve links 2021-04-17 23:16:44 +02:00
rlespinasse
81beb28f90 ci: improve release process 2021-04-17 22:16:49 +02:00
Romain Lespinasse
08cd74e0fa docs: improve overview section 2021-04-17 22:16:49 +02:00
Romain Lespinasse
8c0a3268b6 docs: improve overview section 2021-04-02 16:14:40 +02:00
semantic-release-bot
016823880d chore(release): 3.5.1 [skip ci]
## [3.5.1](http://github.com/rlespinasse/github-slug-action/compare/3.5.0...3.5.1) (2021-03-31)

### Bug Fixes

* update dist files ([e6c550f](e6c550f88c))
2021-03-31 06:58:56 +00:00
Mark Allen
e6c550f88c fix: update dist files 2021-03-31 08:57:45 +02:00
semantic-release-bot
4060fda269 chore(release): 3.5.0 [skip ci]
# [3.5.0](http://github.com/rlespinasse/github-slug-action/compare/3.4.0...3.5.0) (2021-03-30)

### Features

* allow underscore in slug values ([475d293](475d293680))
2021-03-30 20:05:12 +00:00
Mark Allen
475d293680 feat: allow underscore in slug values 2021-03-30 22:04:00 +02:00
semantic-release-bot
0c099abd97 chore(release): 3.4.0 [skip ci]
# [3.4.0](http://github.com/rlespinasse/github-slug-action/compare/3.3.0...3.4.0) (2021-03-02)

### Features

* add _CS suffix to keep value case-sensitive ([6c93fcb](6c93fcbf53))
2021-03-02 23:30:23 +00:00
rlespinasse
6c93fcbf53 feat: add _CS suffix to keep value case-sensitive 2021-03-03 00:29:09 +01:00
rlespinasse
38c43d3f60 build(node): use non-vulnerable version of marked 2021-02-27 22:37:18 +01:00
rlespinasse
275eb0d01d docs(slug): document pull_request slug issue 2021-01-27 19:31:46 +01:00
semantic-release-bot
d1880ea5b3 chore(release): 3.3.0 [skip ci]
# [3.3.0](http://github.com/rlespinasse/github-slug-action/compare/3.2.0...3.3.0) (2021-01-25)

### Bug Fixes

* support pull-request for slug and slug url ([78985f8](78985f84ec))

### Features

* support partial GITHUB_REPOSITORY ([75ce03b](75ce03b6a0))
2021-01-25 22:20:39 +00:00
rlespinasse
66299f72e4 docs: improve readability on tables 2021-01-25 23:16:23 +01:00
rlespinasse
78985f84ec fix: support pull-request for slug and slug url 2021-01-25 22:12:27 +01:00
rlespinasse
75ce03b6a0 feat: support partial GITHUB_REPOSITORY 2021-01-25 22:12:27 +01:00
rlespinasse
49e1056c70 docs(troubleshooting): add naming convention issue 2021-01-25 20:01:05 +01:00
rlespinasse
81bff0391a docs(README): expose documentation and examples 2021-01-25 20:01:05 +01:00
rlespinasse
b956e16ac2 ci: print better testing output 2021-01-25 20:01:05 +01:00
rlespinasse
fad587c035 build: update dependencies 2021-01-25 20:01:05 +01:00
Romain Lespinasse
5f4806451f ci: disable linter about standard js
Since we use Prettier instead
2021-01-12 10:24:06 +01:00
semantic-release-bot
c8d8ee50d0 chore(release): 3.2.0 [skip ci]
# [3.2.0](http://github.com/rlespinasse/github-slug-action/compare/3.1.0...3.2.0) (2021-01-12)

### Features

* expose GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT ([5b9fe60](5b9fe6015d))
2021-01-12 09:23:14 +00:00
Julien Klaer
5b9fe6015d feat: expose GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT 2021-01-12 10:22:14 +01:00
rlespinasse
5629d21ee9 ci(linter): use repo eslint configuration 2021-01-09 09:44:25 +01:00
dependabot[bot]
b6938fb2bd build(deps): bump node-notifier from 8.0.0 to 8.0.1
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-01 18:42:36 +01:00
Romain Lespinasse
d6257a36a9 docs(contributing): fix typo 2020-12-18 17:39:27 +01:00
dependabot[bot]
7ad978282a build(deps): bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-14 08:32:50 +01:00
Romain Lespinasse
9f5fafb8ad docs: add talks/articles section 2020-12-12 18:13:01 +01:00
Romain Lespinasse
750d2f7f48 ci: setup CodeQL GitHub workflow 2020-12-05 19:37:21 +01:00
Alain Hélaïli
2b1034b1fb docs: fix typo in sample 2020-12-05 15:27:19 +01:00
dependabot[bot]
1b1913be6c build(deps-dev): bump semantic-release from 17.0.7 to 17.2.3
Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 17.0.7 to 17.2.3.
- [Release notes](https://github.com/semantic-release/semantic-release/releases)
- [Commits](https://github.com/semantic-release/semantic-release/compare/v17.0.7...v17.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-19 12:59:57 +01:00
Romain Lespinasse
cc560ad7b4 ci: run linter on default branch 2020-11-01 21:31:23 +01:00
rlespinasse
549c11b4e2 ci: improve build workflow 2020-11-01 21:29:52 +01:00
rlespinasse
68eb43656c ci: add dependabot for github-actions 2020-11-01 21:29:52 +01:00
rlespinasse
2aba10a826 ci: add linter workflow 2020-11-01 21:29:52 +01:00
Romain Lespinasse
afcda09378 docs(readme): add license badge 2020-11-01 21:01:37 +01:00
Romain Lespinasse
15f6edebdd docs(readme): improve action scope 2020-11-01 20:52:34 +01:00
semantic-release-bot
e4699e49fc chore(release): 3.1.0 [skip ci]
# [3.1.0](http://github.com/rlespinasse/github-slug-action/compare/3.0.0...3.1.0) (2020-11-01)

### Features

* **action:** improve marketplace information ([3cddc4f](3cddc4f12d))
2020-11-01 19:40:26 +00:00
Romain Lespinasse
3cddc4f12d feat(action): improve marketplace information 2020-11-01 20:39:24 +01:00
rlespinasse
d7817bf204 docs(contributing): improve issue links 2020-10-31 16:12:03 +01:00
Romain Lespinasse
4e3f956c5e docs: add contributing guide 2020-10-31 09:36:05 +01:00
Romain Lespinasse
f79727b5cc docs: improve master EOL section 2020-10-31 08:24:38 +01:00
Romain Lespinasse
a3c7c5c7a1 docs: use v3.x branch in example 2020-10-31 08:22:11 +01:00
rlespinasse
008aa6260d build: bump dev dependencies versions 2020-10-27 09:28:24 +01:00
rlespinasse
3c7ae42a01 ci: activate release on v3.x branch 2020-10-26 21:42:08 +01:00
Romain Lespinasse
ae2430ad57 docs(security): remove v1.1.x from supported versions 2020-10-26 21:29:58 +01:00
55 changed files with 2007 additions and 18522 deletions

2
.codespellrc Normal file
View File

@@ -0,0 +1,2 @@
[codespell]
ignore-words-list = ans

View File

@@ -1,3 +0,0 @@
dist/
lib/
node_modules/

View File

@@ -1,54 +0,0 @@
{
"plugins": ["jest", "@typescript-eslint"],
"extends": ["plugin:github/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 9,
"sourceType": "module",
"project": "./tsconfig.json"
},
"rules": {
"eslint-comments/no-use": "off",
"import/no-namespace": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/explicit-member-accessibility": ["error", {"accessibility": "no-public"}],
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/array-type": "error",
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-comment": "error",
"camelcase": "off",
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/explicit-function-return-type": ["error", {"allowExpressions": true}],
"@typescript-eslint/func-call-spacing": ["error", "never"],
"@typescript-eslint/no-array-constructor": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-extraneous-class": "error",
"@typescript-eslint/no-for-in-array": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-useless-constructor": "error",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "warn",
"@typescript-eslint/prefer-function-type": "warn",
"@typescript-eslint/prefer-includes": "error",
"@typescript-eslint/prefer-string-starts-ends-with": "error",
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"semi": "off",
"@typescript-eslint/semi": ["error", "never"],
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/unbound-method": "error"
},
"env": {
"node": true,
"es6": true,
"jest/globals": true
}
}

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @rlespinasse

View File

@@ -1,9 +1,23 @@
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory
directory: '/'
# Check the npm registry for updates every day (weekdays)
- package-ecosystem: 'github-actions'
directory: '/.github/'
schedule:
interval: 'daily'
interval: 'weekly'
groups:
dependencies:
patterns:
- '*'
labels: []
- package-ecosystem: 'github-actions'
directory: '/'
commit-message:
prefix: 'feat: '
schedule:
interval: 'weekly'
groups:
dependencies:
patterns:
- 'rlespinasse/slugify-value'
- 'rlespinasse/shortify-git-revision'
labels: []

139
.github/workflows/check-variables.yml vendored Normal file
View File

@@ -0,0 +1,139 @@
---
name: Compare GitHub Variables
on:
workflow_dispatch: # Manual trigger
schedule:
- cron: "0 0 * * 1" # Weekly on Monday at midnight
pull_request:
permissions: read-all
jobs:
compare-variables:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Load environment variables for testing
uses: rlespinasse/github-slug-action@v5
with:
prefix: TEST_
- name: Compare GitHub variables
id: compare
run: |
# Initialize arrays to store results
MISMATCHED_VARS=()
TEST_VALUES=()
ACTUAL_VALUES=()
# Get all environment variables
ALL_ENV=$(env)
# Extract TEST_GITHUB variables
TEST_VARS=$(echo "$ALL_ENV" | grep "^TEST_GITHUB_" | cut -d= -f1)
# Check for mismatches
for TEST_VAR in $TEST_VARS; do
# Get the corresponding GITHUB variable name
GITHUB_VAR=${TEST_VAR/TEST_GITHUB_/GITHUB_}
# Get the values
TEST_VALUE="${!TEST_VAR}"
# Check if the GITHUB variable exists
if [[ -n "${!GITHUB_VAR+x}" ]]; then
GITHUB_VALUE="${!GITHUB_VAR}"
# Compare values
if [[ "$TEST_VALUE" != "$GITHUB_VALUE" ]]; then
MISMATCHED_VARS+=("$TEST_VAR vs $GITHUB_VAR")
TEST_VALUES+=("$TEST_VALUE")
ACTUAL_VALUES+=("$GITHUB_VALUE")
echo "Mismatch found: $TEST_VAR=$TEST_VALUE, $GITHUB_VAR=$GITHUB_VALUE"
else
echo "Match: $TEST_VAR=$TEST_VALUE, $GITHUB_VAR=$GITHUB_VALUE"
fi
else
echo "Skipping $TEST_VAR as $GITHUB_VAR does not exist"
fi
done
# Set output for next steps
if [[ ${#MISMATCHED_VARS[@]} -gt 0 ]]; then
echo "has_mismatches=true" >>"$GITHUB_OUTPUT"
# Create a JSON array of mismatched variables for the issue
MISMATCHED_JSON=$(printf '"%s",' "${MISMATCHED_VARS[@]}" | sed 's/,$//')
MISMATCHED_JSON="[$MISMATCHED_JSON]"
echo "mismatched_vars=$MISMATCHED_JSON" >>"$GITHUB_OUTPUT"
# Create a JSON array of test values
TEST_JSON=$(printf '"%s",' "${TEST_VALUES[@]}" | sed 's/,$//')
TEST_JSON="[$TEST_JSON]"
echo "test_values=$TEST_JSON" >>"$GITHUB_OUTPUT"
# Create a JSON array of actual values
ACTUAL_JSON=$(printf '"%s",' "${ACTUAL_VALUES[@]}" | sed 's/,$//')
ACTUAL_JSON="[$ACTUAL_JSON]"
echo "actual_values=$ACTUAL_JSON" >>"$GITHUB_OUTPUT"
# Create summary table
{
echo "## GitHub Variable Mismatches";
echo "| Variable Pair | TEST Value | GITHUB Value |";
echo "| ------------- | ---------- | ------------ |";
} >>"$GITHUB_STEP_SUMMARY"
for i in "${!MISMATCHED_VARS[@]}"; do
echo "| ${MISMATCHED_VARS[$i]} | ${TEST_VALUES[$i]} | ${ACTUAL_VALUES[$i]} |" >>"$GITHUB_STEP_SUMMARY"
done
else
echo "has_mismatches=false" >>"$GITHUB_OUTPUT"
echo "## All GitHub Variables Match" >>"$GITHUB_STEP_SUMMARY"
echo "All action GITHUB_ variables match their official GITHUB_ counterparts." >>"$GITHUB_STEP_SUMMARY"
fi
shell: bash
- name: Create issue for mismatches
if: steps.compare.outputs.has_mismatches == 'true' && github.event_name != 'pull_request'
uses: actions/github-script@v9
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const mismatchedVars = JSON.parse('${{ steps.compare.outputs.mismatched_vars }}');
const testValues = JSON.parse('${{ steps.compare.outputs.test_values }}');
const actualValues = JSON.parse('${{ steps.compare.outputs.actual_values }}');
// Create table for issue body
let tableBody = '| Variable Pair | TEST Value | GITHUB Value |\n';
tableBody += '| ------------- | ---------- | ------------ |\n';
for (let i = 0; i < mismatchedVars.length; i++) {
tableBody += `| ${mismatchedVars[i]} | ${testValues[i]} | ${actualValues[i]} |\n`;
}
// Create the issue
const issueTitle = `GitHub Variable Mismatches Detected - ${new Date().toISOString().split('T')[0]}`;
const issueBody = `## GitHub Variable Mismatches Detected\n\nThe following mismatches were found between the action **GITHUB_** variables and their official **GITHUB_** counterparts:\n\n${tableBody}\n\nPlease review these discrepancies and update the test variables as needed.`;
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: issueTitle,
body: issueBody,
labels: ['bug']
});
console.log('Issue created for GitHub variable mismatches');
- name: Fail workflow if mismatches detected
if: steps.compare.outputs.has_mismatches == 'true' && github.event_name == 'pull_request'
run: |
echo "::error::GitHub variable mismatches detected! See the summary for details."
exit 1

View File

@@ -1,65 +0,0 @@
name: Build
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: |
npm ci
- run: |
npm run all
- uses: cycjimmy/semantic-release-action@v2
with:
semantic_version: 17.0.7
branches: |
[
'v2.x',
'v3.x'
]
extra_plugins: |
@semantic-release/changelog@5.0.1
@semantic-release/git@9.0.0
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
test: # make sure the action works on a clean machine without building
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
steps:
- uses: actions/checkout@v2
- uses: ./
- run: |
echo $GITHUB_REPOSITORY_SLUG
echo $GITHUB_REPOSITORY_SLUG_URL
echo $GITHUB_REF_SLUG
echo $GITHUB_HEAD_REF_SLUG
echo $GITHUB_BASE_REF_SLUG
echo $GITHUB_EVENT_REF_SLUG
echo $GITHUB_REF_SLUG_URL
echo $GITHUB_HEAD_REF_SLUG_URL
echo $GITHUB_BASE_REF_SLUG_URL
echo $GITHUB_EVENT_REF_SLUG_URL
echo $GITHUB_SHA_SHORT
test-win:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- uses: ./
- run: |
echo $env:GITHUB_REPOSITORY_SLUG
echo $env:GITHUB_REPOSITORY_SLUG_URL
echo $env:GITHUB_REF_SLUG
echo $env:GITHUB_HEAD_REF_SLUG
echo $env:GITHUB_BASE_REF_SLUG
echo $env:GITHUB_EVENT_REF_SLUG
echo $env:GITHUB_REF_SLUG_URL
echo $env:GITHUB_HEAD_REF_SLUG_URL
echo $env:GITHUB_BASE_REF_SLUG_URL
echo $env:GITHUB_EVENT_REF_SLUG_URL
echo $env:GITHUB_SHA_SHORT

32
.github/workflows/linter.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
---
name: Lint Code Base
on: pull_request
permissions: read-all
jobs:
build:
name: Lint Code Base
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
statuses: write
steps:
- name: Checkout Code
uses: actions/checkout@v6
with:
# Full git history is needed to get a proper
# list of changed files within `super-linter`
fetch-depth: 0
- name: Lint Code Base
uses: super-linter/super-linter@v8
env:
VALIDATE_ALL_CODEBASE: false
VALIDATE_GITHUB_ACTIONS_ZIZMOR: false
VALIDATE_JSCPD: false
VALIDATE_MARKDOWN_PRETTIER: false
VALIDATE_YAML_PRETTIER: false
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,402 @@
name: "[v5] Test and Release"
on: [push, pull_request]
permissions: read-all
jobs:
check-v4-compatibility:
name: "Check v4 compatibility"
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Load this action from HEAD
uses: ./
- name: Load using v4
uses: rlespinasse/github-slug-action@v4
with:
prefix: V4_
- name: Validate // Partial variables
run: |
[[ "${{ env.GITHUB_REPOSITORY_OWNER_PART }}" == "${{ env.V4_GITHUB_REPOSITORY_OWNER_PART }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_NAME_PART }}" == "${{ env.V4_GITHUB_REPOSITORY_NAME_PART }}" ]]
shell: bash
- name: Validate // Slug variables
run: |
[[ "${{ env.GITHUB_REPOSITORY_SLUG }}" == "${{ env.V4_GITHUB_REPOSITORY_SLUG }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG }}" == "${{ env.V4_GITHUB_REPOSITORY_OWNER_PART_SLUG }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG }}" == "${{ env.V4_GITHUB_REPOSITORY_NAME_PART_SLUG }}" ]]
[[ "${{ env.GITHUB_REF_SLUG }}" == "${{ env.V4_GITHUB_REF_SLUG }}" ]]
[[ "${{ env.GITHUB_HEAD_REF_SLUG }}" == "${{ env.V4_GITHUB_HEAD_REF_SLUG }}" ]]
[[ "${{ env.GITHUB_BASE_REF_SLUG }}" == "${{ env.V4_GITHUB_BASE_REF_SLUG }}" ]]
[[ "${{ env.GITHUB_EVENT_REF_SLUG }}" == "${{ env.V4_GITHUB_EVENT_REF_SLUG }}" ]]
shell: bash
- name: Validate // Slug variables (Case Sensitive)
run: |
[[ "${{ env.GITHUB_REPOSITORY_SLUG_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_OWNER_PART_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_NAME_PART_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_REF_SLUG_CS }}" == "${{ env.V4_GITHUB_REF_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_HEAD_REF_SLUG_CS }}" == "${{ env.V4_GITHUB_HEAD_REF_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_BASE_REF_SLUG_CS }}" == "${{ env.V4_GITHUB_BASE_REF_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_EVENT_REF_SLUG_CS }}" == "${{ env.V4_GITHUB_EVENT_REF_SLUG_CS }}" ]]
shell: bash
- name: Validate // Slug URL variables
run: |
[[ "${{ env.GITHUB_REPOSITORY_SLUG_URL }}" == "${{ env.V4_GITHUB_REPOSITORY_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL }}" == "${{ env.V4_GITHUB_REPOSITORY_OWNER_PART_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL }}" == "${{ env.V4_GITHUB_REPOSITORY_NAME_PART_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_REF_SLUG_URL }}" == "${{ env.V4_GITHUB_REF_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_HEAD_REF_SLUG_URL }}" == "${{ env.V4_GITHUB_HEAD_REF_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_BASE_REF_SLUG_URL }}" == "${{ env.V4_GITHUB_BASE_REF_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_EVENT_REF_SLUG_URL }}" == "${{ env.V4_GITHUB_EVENT_REF_SLUG_URL }}" ]]
shell: bash
- name: Validate // Slug URL variables (Case Sensitive)
run: |
[[ "${{ env.GITHUB_REPOSITORY_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_OWNER_PART_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_REPOSITORY_NAME_PART_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_REF_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_REF_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_HEAD_REF_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_HEAD_REF_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_BASE_REF_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_BASE_REF_SLUG_URL_CS }}" ]]
[[ "${{ env.GITHUB_EVENT_REF_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_EVENT_REF_SLUG_URL_CS }}" ]]
shell: bash
- name: Validate // Ref Point
run: |
[[ "${{ env.GITHUB_REF_POINT }}" == "${{ env.V4_GITHUB_REF_NAME }}" ]]
[[ "${{ env.GITHUB_REF_POINT_SLUG }}" == "${{ env.V4_GITHUB_REF_NAME_SLUG }}" ]]
[[ "${{ env.GITHUB_REF_POINT_SLUG_URL }}" == "${{ env.V4_GITHUB_REF_NAME_SLUG_URL }}" ]]
[[ "${{ env.GITHUB_REF_POINT_SLUG_CS }}" == "${{ env.V4_GITHUB_REF_NAME_SLUG_CS }}" ]]
[[ "${{ env.GITHUB_REF_POINT_SLUG_URL_CS }}" == "${{ env.V4_GITHUB_REF_NAME_SLUG_URL_CS }}" ]]
shell: bash
- name: Validate // Short SHA variables
run: |
[[ "${{ env.GITHUB_SHA_SHORT }}" == "${{ env.V4_GITHUB_SHA_SHORT }}" ]]
[[ "${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}" == "${{ env.V4_GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}" ]]
shell: bash
check-v4-compatibility-without-checkout:
name: "Check v4 compatibility (without checkout)"
needs:
- check-v4-compatibility
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: this-action
ref: ${{ github.ref }}
- name: Load this action from HEAD
uses: ./this-action
- name: Load using v4
uses: rlespinasse/github-slug-action@v4
with:
prefix: V4_
- name: Validate // Short SHA variables
run: |
[[ "${{ env.GITHUB_SHA_SHORT }}" == "${{ env.V4_GITHUB_SHA_SHORT }}" ]]
[[ "${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}" == "${{ env.V4_GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}" ]]
shell: bash
display:
name: "Display produced variables"
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Load this action from HEAD
uses: ./
- name: Partial variables
run: |
echo "repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART }}"
echo "repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART }}"
shell: bash
- name: Slug variables
run: |
echo "repository : ${{ env.GITHUB_REPOSITORY_SLUG }}"
echo "repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG }}"
echo "repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG }}"
echo "ref : ${{ env.GITHUB_REF_SLUG }}"
echo "ref name : ${{ env.GITHUB_REF_NAME_SLUG }}"
echo "head ref : ${{ env.GITHUB_HEAD_REF_SLUG }}"
echo "base ref : ${{ env.GITHUB_BASE_REF_SLUG }}"
echo "event ref : ${{ env.GITHUB_EVENT_REF_SLUG }}"
shell: bash
- name: Slug variables (Case Sensitive)
run: |
echo "repository : ${{ env.GITHUB_REPOSITORY_SLUG_CS }}"
echo "repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_CS }}"
echo "repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_CS }}"
echo "ref : ${{ env.GITHUB_REF_SLUG_CS }}"
echo "ref name : ${{ env.GITHUB_REF_NAME_SLUG_CS }}"
echo "head ref : ${{ env.GITHUB_HEAD_REF_SLUG_CS }}"
echo "base ref : ${{ env.GITHUB_BASE_REF_SLUG_CS }}"
echo "event ref : ${{ env.GITHUB_EVENT_REF_SLUG_CS }}"
shell: bash
- name: Slug URL variables
run: |
echo "repository : ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
echo "repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL }}"
echo "repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL }}"
echo "ref : ${{ env.GITHUB_REF_SLUG_URL }}"
echo "ref name : ${{ env.GITHUB_REF_NAME_SLUG_URL }}"
echo "head ref : ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
echo "base ref : ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
echo "event ref : ${{ env.GITHUB_EVENT_REF_SLUG_URL }}"
shell: bash
- name: Slug URL variables (Case Sensitive)
run: |
echo "repository : ${{ env.GITHUB_REPOSITORY_SLUG_URL_CS }}"
echo "repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL_CS }}"
echo "repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL_CS }}"
echo "ref : ${{ env.GITHUB_REF_SLUG_URL_CS }}"
echo "ref name : ${{ env.GITHUB_REF_NAME_SLUG_URL_CS }}"
echo "head ref : ${{ env.GITHUB_HEAD_REF_SLUG_URL_CS }}"
echo "base ref : ${{ env.GITHUB_BASE_REF_SLUG_URL_CS }}"
echo "event ref : ${{ env.GITHUB_EVENT_REF_SLUG_URL_CS }}"
shell: bash
- name: Ref Point
run: |
echo "raw : ${{ env.GITHUB_REF_POINT }}"
echo "slug : ${{ env.GITHUB_REF_POINT_SLUG }}"
echo "slug url : ${{ env.GITHUB_REF_POINT_SLUG_URL }}"
echo "slug (Case Sensitive) : ${{ env.GITHUB_REF_POINT_SLUG_CS }}"
echo "slug url (Case Sensitive) : ${{ env.GITHUB_REF_POINT_SLUG_URL_CS }}"
shell: bash
- name: Short SHA variables
run: |
echo "sha : ${{ env.GITHUB_SHA_SHORT }}"
echo "pull request sha : ${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}"
shell: bash
display-without-checkout:
name: "Display produced variables (without checkout)"
needs:
- display
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: this-action
ref: ${{ github.ref }}
- name: Load this action from HEAD
uses: ./this-action
- name: Short SHA variables
run: |
echo "sha : ${{ env.GITHUB_SHA_SHORT }}"
echo "pull request sha : ${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}"
shell: bash
input-short-length:
name: "Input 'short-length'"
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
# Test 1
- name: Using correct short length
uses: ./
with:
prefix: "CSL_"
short-length: 4
- name: Using correct length // Validate that all short variables lengths are equals to short-length
run: |
env | grep "CSL_" | grep "_SHORT" | cut -d"=" -f2 | while read -r value; do [ "${#value}" -le 5 ] ; done
shell: bash
# Test 2
- name: Using wrong short length
id: using-wrong-short-length
uses: ./
with:
prefix: "WSL_"
short-length: "wrong"
continue-on-error: true
- name: Using wrong short length // Validate that the action end with an error
run: |
[[ "$(env | grep "WSL_" | grep "_SHORT" -c)" -eq 0 ]]
[[ "${{ steps.using-wrong-short-length.outcome }}" == "failure" ]]
[[ "${{ steps.using-wrong-short-length.conclusion }}" == "success" ]]
shell: bash
input-short-length-without-checkout:
name: "Input 'short-length' (without checkout)"
needs:
- input-short-length
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: this-action
ref: ${{ github.ref }}
# Test 1
- name: Using correct short length
uses: ./this-action
with:
prefix: "CSL_"
short-length: 4
- name: Using correct length // Validate that all short variables lengths are equals to short-length
run: |
env | grep "CSL_" | grep "_SHORT" | cut -d"=" -f2 | while read -r value; do [ "${#value}" -le 5 ] ; done
shell: bash
# Test 2
- name: Using empty short length
id: using-empty-short-length
uses: ./this-action
with:
prefix: "ESL_"
continue-on-error: true
- name: Using empty short length // Validate that the action don't end with an error
run: |
[[ "$(env | grep "ESL_" | grep "_SHORT" -c)" -gt 0 ]]
[[ "${{ steps.using-empty-short-length.outcome }}" == "success" ]]
[[ "${{ steps.using-empty-short-length.conclusion }}" == "success" ]]
shell: bash
# Test 3
- name: Using wrong short length
id: using-wrong-short-length
uses: ./this-action
with:
prefix: "WSL_"
short-length: "wrong"
continue-on-error: true
- name: Using wrong short length // Validate that the action end with an error
run: |
[[ "$(env | grep "WSL_" | grep "_SHORT" -c)" -eq 0 ]]
[[ "${{ steps.using-wrong-short-length.outcome }}" == "failure" ]]
[[ "${{ steps.using-wrong-short-length.conclusion }}" == "success" ]]
shell: bash
input-slug-maxlength:
name: "Input 'slug-maxlength'"
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v6
# Test 1
- name: Using correct slug max length
uses: ./
with:
prefix: "CML_"
slug-maxlength: 1
- name: Using correct max length // Validate that all slug variables lengths are equals or under the slug-maxlength
run: |
env | grep "CML_" | grep "_SLUG" | cut -d"=" -f2 | while read -r value; do [ "${#value}" -le 2 ] ; done
shell: bash
# Test 2
- name: Using wrong slug max length
id: using-wrong-slug-max-length
uses: ./
with:
prefix: "WML_"
slug-maxlength: "wrong"
continue-on-error: true
- name: Using wrong slug max length // Validate that the action end with an error
run: |
[[ "$(env | grep "WML_" | grep "_SLUG" -c)" -eq 0 ]]
[[ "${{ steps.using-wrong-slug-max-length.outcome }}" == "failure" ]]
[[ "${{ steps.using-wrong-slug-max-length.conclusion }}" == "success" ]]
shell: bash
# Test 3
- name: Using empty slug max length
id: using-empty-slug-max-length
uses: ./
with:
prefix: "EML_"
slug-maxlength: ""
continue-on-error: true
- name: Using empty slug max length // Validate that the action end with an error
run: |
[[ "$(env | grep "EML_" | grep "_SLUG" -c)" -eq 0 ]]
[[ "${{ steps.using-empty-slug-max-length.outcome }}" == "failure" ]]
[[ "${{ steps.using-empty-slug-max-length.conclusion }}" == "success" ]]
shell: bash
# Test 4
- name: Using no limit on slug max length
id: using-nolimit-slug-max-length
uses: ./
with:
prefix: "NLML_"
slug-maxlength: "nolimit"
- name: Using no limit on slug max length // Validate that the action end with an error
run: |
[[ "$(env | grep "NLML_" | grep "_SLUG" -c)" -gt 0 ]]
[[ "${{ steps.using-nolimit-slug-max-length.outcome }}" == "success" ]]
[[ "${{ steps.using-nolimit-slug-max-length.conclusion }}" == "success" ]]
shell: bash
release:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
id-token: write
packages: write
concurrency:
group: release-${{ github.ref }}-${{ github.event_name }}
needs:
- display-without-checkout
- input-short-length-without-checkout
- input-slug-maxlength
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Release this GitHub Action
uses: rlespinasse/release-that@v1
with:
github-token: ${{ secrets.GH_TOKEN }}

99
.gitignore vendored
View File

@@ -1,99 +0,0 @@
# Dependency directory
node_modules
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# OS metadata
.DS_Store
Thumbs.db
# Ignore built ts files
__tests__/runner/*
lib/**/*

View File

@@ -1,3 +0,0 @@
dist/
lib/
node_modules/

View File

@@ -1,10 +0,0 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid"
}

View File

@@ -1,25 +0,0 @@
# [3.0.0](http://github.com/rlespinasse/github-slug-action/compare/2.1.0...3.0.0) (2020-10-26)
### Bug Fixes
* upgrade actions core due to CVE fix ([d0549c1](http://github.com/rlespinasse/github-slug-action/commit/d0549c1f85ab9567b439f9d660b01ce1142b9fbe))
### Features
* add support for windows and macos jobs ([13c2f38](http://github.com/rlespinasse/github-slug-action/commit/13c2f38dad5f32529f37c25736412b1e4cf687fe))
### BREAKING CHANGES
* The action implementation move from container action to node.js action
Co-authored-by: Romain Lespinasse <romain.lespinasse@gmail.com>
# [2.1.0](http://github.com/rlespinasse/github-slug-action/compare/2.0.0...2.1.0) (2020-07-28)
### Features
* expose slug variables for github.event.ref ([5a334a8](http://github.com/rlespinasse/github-slug-action/commit/5a334a8573fc27451af5b2a6ee175d8e11579e10))

View File

@@ -1,76 +1,133 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
Examples of behavior that contributes to a positive environment for our
community include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior by participants include:
Examples of unacceptable behavior include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
professional setting
## Our Responsibilities
## Enforcement Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at romain.lespinasse@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
reported to the community leaders responsible for enforcement at
<romain.lespinasse@gmail.com>.
All complaints will be reviewed and investigated promptly and fairly.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

33
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,33 @@
# How to contribute to GitHub Slug Action
## Did you find a bug
* **Do not open up a GitHub issue if the bug is a security vulnerability**, and instead to refer to our [security policy][1].
* **Ensure the bug was not already reported** by searching on GitHub under [Issues][2].
* If you're unable to find an open issue addressing the problem, [open a 'Bug' issue][4].
Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring.
## Did you write a patch that fixes a bug
* Open a new GitHub pull request with the patch.
* Ensure the PR description clearly describes the problem and solution.
Include the relevant issue number if applicable.
## Do you intend to add a new feature or change an existing one
* Suggest your change by [opening a 'Feature request' issue][5]
## Do you have questions about the source code
* [open an issue][3] with your question.
Thanks!
[1]: https://github.com/rlespinasse/github-slug-action/security/policy
[2]: https://github.com/rlespinasse/github-slug-action/issues
[3]: https://github.com/rlespinasse/github-slug-action/issues/new
[4]: https://github.com/rlespinasse/github-slug-action/issues/new?assignees=&labels=bug&template=bug_report.md&title=
[5]: https://github.com/rlespinasse/github-slug-action/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=

View File

@@ -1,26 +0,0 @@
# Developers guide
Install the dependencies
```bash
npm install
```
Build the typescript and package it for distribution
```bash
npm run build && npm run package
```
Run the tests
```bash
$ npm test
PASS ./index.test.js
✓ throws invalid number (3ms)
wait 500 ms (504ms)
test runs (95ms)
...
```

202
README.md
View File

@@ -1,144 +1,128 @@
# GitHub Slug action
# GitHub Slug Action
[![Actions Status][1]][2]
[![Public workflows that use this action.][8]][9]
This GitHub Action exposes slug and short values of [GitHub environment variables][default-environment-variables] inside your workflow.
This action slug and expose some github variables.
`Slug` a variable will
- put the variable content in lower case
- replace any character by `-` except `0-9`, `a-z`, and `.`
- remove leading and trailing `-` character
- limit the string size to 63 characters
Others `Slug`-ish commands are available:
- `Slug URL` a variable will be like the `slug` variable but the `.` character will also be replaced by `-`
- `Short SHA` a variable will limit the string size to 8 characters
## Exposed environment variables
## Quick Start
```yaml
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v2.x
- name: Print slug/short variables
run: |
echo "Slug variables"
echo " ref : ${{ env.GITHUB_REF_SLUG }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG }}"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG }}"
echo "Slug URL variables"
echo " ref : ${{ env.GITHUB_REF_SLUG_URL }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG_URL }}"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
echo "Short SHA variables"
echo " sha : ${{ env.GITHUB_SHA_SHORT }}"
steps:
- uses: actions/checkout@v6
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
```
Read [default environment variables][3] page for more information.
> [!CAUTION]
> Use [Dependabot][dependabot] to maintain your `github-slug-action` version updated in your GitHub workflows.
### GITHUB_REF_SLUG / GITHUB_REF_SLUG_URL
## What It Does
Slug the environment variable **GITHUB_REF**
- **SLUG** -- Lowercase, replace special characters with `-`, limit to 63 characters. _Dots and underscores preserved._
- **SLUG_URL** -- Same as SLUG, but dots and underscores are also replaced. _Safe for URLs and subdomains._
- **SHORT** -- Shorten Git SHA values to a unique prefix.
- **PART** -- Extract portions of a variable (e.g., owner or repository name from `GITHUB_REPOSITORY`).
- **_CS** -- Case-sensitive variants of SLUG and SLUG_URL (original casing preserved).
The branch or tag ref that triggered the workflow.
_If neither a branch or tag is available for the event type, the variable will not exist._
> [!TIP]
> Read the [slug transformation rules](docs/explanation/slug-transformation-rules.md) for the full algorithm and rationale.
| GITHUB_REF | GITHUB_REF_SLUG | GITHUB_REF_SLUG_URL |
| ------------------------------ | ------------------- | ------------------- |
| refs/heads/master | master | master |
| refs/heads/feat/new_feature | feat-new-feature | feat-new-feature |
| refs/tags/v1.0.0 | v1.0.0 | v1-0-0 |
| refs/tags/product@1.0.0-rc.2 | product-1.0.0-rc.2 | product-1-0-0-rc-2 |
| refs/heads/New_Awesome_Product | new-awesome-product | new-awesome-product |
## Inputs
> **NOTE :**
> GITHUB_REF_SLUG_URL is design to be used as subdomain in an URL.
| Input | Default | Description |
| ----- | ------- | ----------- |
| `prefix` | `""` | Value prepended to each generated variable name |
| `slug-maxlength` | `63` | Max length of slugified values (`"nolimit"` to disable) |
| `short-length` | _(Git default)_ | Length of short SHA values (minimum `4`) |
_Additional variables (only set for forked repositories) :_
See the [inputs reference](docs/reference/inputs.md) for details.
- `GITHUB_HEAD_REF_SLUG`/`GITHUB_HEAD_REF_SLUG_URL`, The branch of the head repository **GITHUB_HEAD_REF**
- `GITHUB_BASE_REF_SLUG`/`GITHUB_BASE_REF_SLUG_URL`, The branch of the base repository **GITHUB_BASE_REF**
## Available Variables
_Additional variables (only set for [create][4], and [delete][5] webhook events with `ref` data) :_
| Variable | Type | Description |
| -------- | ---- | ----------- |
| [GITHUB_REF_POINT](docs/reference/variables.md#github_ref_point) | Enhanced | Branch or tag name (consistent across event types) |
| [GITHUB_REPOSITORY_OWNER_PART](docs/reference/variables.md#github_repository_owner_part) | Partial | Owner extracted from repository |
| [GITHUB_REPOSITORY_NAME_PART](docs/reference/variables.md#github_repository_name_part) | Partial | Repository name extracted from repository |
| [GITHUB_REPOSITORY_SLUG](docs/reference/variables.md#github_repository_slug) | Slug | The owner and repository name |
| [GITHUB_REF_SLUG](docs/reference/variables.md#github_ref_slug) | Slug | The branch or tag ref |
| [GITHUB_REF_NAME_SLUG](docs/reference/variables.md#github_ref_name_slug) | Slug | The branch or tag name shown on GitHub |
| [GITHUB_HEAD_REF_SLUG](docs/reference/variables.md#github_head_ref_slug) | Slug | PR head branch |
| [GITHUB_BASE_REF_SLUG](docs/reference/variables.md#github_base_ref_slug) | Slug | PR base branch |
| [GITHUB_EVENT_REF_SLUG](docs/reference/variables.md#github_event_ref_slug) | Slug | Webhook Git ref |
| [GITHUB_SHA_SHORT](docs/reference/variables.md#github_sha_short) | Short | Shortened commit SHA |
| [GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT](docs/reference/variables.md#github_event_pull_request_head_sha_short) | Short | Shortened PR head commit SHA |
- `GITHUB_EVENT_REF_SLUG`/`GITHUB_EVENT_REF_SLUG_URL`, The git reference resource associated to the webhook.
All slug variables also have `_SLUG_URL` and `_CS` variants. See the [full variable reference](docs/reference/variables.md).
### GITHUB_REPOSITORY_SLUG / GITHUB_REPOSITORY_SLUG_URL
> [!TIP]
> If you don't find what you need, read about [available GitHub variables](docs/reference/github-variables.md), [propose a new variable][custom-variable], or use [slugify-value][slugify-value] / [shortify-git-revision][shortify-git-revision] directly.
Slug the environment variable **GITHUB_REPOSITORY**
## Documentation
The owner and repository name.
### Tutorial
| GITHUB_REPOSITORY | GITHUB_REPOSITORY_SLUG | GITHUB_REPOSITORY_SLUG_URL |
| -------------------------- | -------------------------- | -------------------------- |
| octocat/Hello-World | octocat-hello-world | octocat-hello-world |
| rlespinasse/Hello-World.go | rlespinasse-hello-world.go | rlespinasse-hello-world-go |
- [Getting started](docs/getting-started.md) -- Step-by-step guide for first-time users
> **NOTE :**
> GITHUB_REPOSITORY_SLUG_URL is design to be used as subdomain in an URL.
### How-To Guides
### GITHUB_SHA_SHORT
- [Use a prefix](docs/how-to/use-prefix.md)
- [Configure slug max length](docs/how-to/configure-slug-maxlength.md)
- [Configure short SHA length](docs/how-to/configure-short-length.md)
- [Use slug variables in URLs](docs/how-to/use-slugs-in-urls.md)
- More [workflow examples](https://github.com/rlespinasse/github-slug-action/tree/v5.x/examples) (OS-specific usage, URL patterns)
Short the environment variable **GITHUB_SHA**
### Reference
The commit SHA that triggered the workflow
- [Variable reference](docs/reference/variables.md) -- All variables with transformation examples
- [Inputs reference](docs/reference/inputs.md) -- Action inputs specification
- [GitHub variables by event](docs/reference/github-variables.md) -- Which variables are available per event type
| GITHUB_SHA | GITHUB_SHA_SHORT |
| ---------------------------------------- | ---------------- |
| ffac537e6cbbf934b08745a378932722df287a53 | ffac537e |
### Explanation
### Use slug variable in an URL
- [Slug transformation rules](docs/explanation/slug-transformation-rules.md) -- How and why transformations work
In an URL, use `<GITHUB_VARIABLE>_SLUG_URL` instead of **<GITHUB_VARIABLE>\_SLUG** as subdomain to be compliant.
## Migration
> **NOTE :**
> <GITHUB*VARIABLE>\_SLUG can be used in an URL only as part of the \_resource path*.
```yaml
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v2.x
- name: Deploy dummy application using slug in the 'subdomain' part
run: |
./deploy-application.sh --url "https://${{ env.<GITHUB_VARIABLE>_SLUG_URL }}.staging.app.mycompagny.com"
- name: Deploy dummy application using slug in the 'resource path' part
run: |
./deploy-application.sh --url "https://staging.app.mycompagny.com/${{ env.<GITHUB_VARIABLE>_SLUG }}"
```
## Contribute
Follow [Developers guide](DEVELOPERS.md)
- [Migrate from v4 to v5](docs/how-to/migrate-v4-to-v5.md) -- `GITHUB_REF_NAME` behaviour changed on pull request events
- [Migrate from v3 to v4](docs/how-to/migrate-v3-to-v4.md) -- Short SHA length is now determined by Git
## Troubleshooting
### Missing master branch
See the [troubleshooting guide](docs/how-to/troubleshooting.md) for common issues and solutions.
If your workflow fail on the `Set up job` task with this kind of log :
## Thanks for talking about us
```text
Download action repository 'rlespinasse/github-slug-action@master'
##[error]An action could not be found at the URI 'https://api.github.com/repos/rlespinasse/github-slug-action/tarball/master'
```
In English :gb:
Use the current branch `v2.x` or a version tag (see [releases pages][6]).
- [Action spotlight by Michael Heap][article-2]
- [Serverless Deploy Previews on GitHub Actions][article-3]
- [Let's Build a Continuous Delivery and Branching Process with GitHub Actions, Vercel and Heroku][article-4]
- [Celebrating 5 Years of github-slug-action on sfeir.dev][article-7]
The master branch EOL is set on **2020-10-25** after a 6-month deprecation period (more information on the [EOL issue][7])
In French :fr:
[1]: https://github.com/rlespinasse/github-slug-action/workflows/Build/badge.svg
[2]: https://github.com/rlespinasse/github-slug-action/actions
[3]: https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
[4]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#create
[5]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#delete
[6]: https://github.com/rlespinasse/github-slug-action/releases
[7]: https://github.com/rlespinasse/github-slug-action/issues/15
[8]: https://img.shields.io/endpoint?url=https%3A%2F%2Fapi-git-master.endbug.vercel.app%2Fapi%2Fgithub-actions%2Fused-by%3Faction%3Drlespinasse%2Fgithub-slug-action%26badge%3Dtrue
[9]: https://github.com/search?o=desc&q=rlespinasse%2Frlespinasse/github-slug-action+path%3A.github%2Fworkflows+language%3AYAML&s=&type=Code
- [Mettre en place une CI/CD Angular avec GitHub Actions & Netlify][article-1]
- [GitHub Actions : enfin des pipelines accessibles aux développeurs][talk-1]
- [GitHub-slug-action : 5 ans d'open source pour cette GitHub Action essentielle au CI/CD][article-6]
In Chinese :cn:
- [利用github-slug-action暴漏GitHub Action上下文中的关键变量][article-5]
> The next one is you. _Don't hesitate to add yourself to one of these lists._
[custom-variable]: https://github.com/rlespinasse/github-slug-action/issues/new?assignees=&labels=enhancement&template=feature_request.md&title=
[slugify-value]: https://github.com/rlespinasse/slugify-value
[shortify-git-revision]: https://github.com/rlespinasse/shortify-git-revision
[default-environment-variables]: https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
[dependabot]: https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
[article-1]: https://esensconsulting.medium.com/mettre-en-place-une-ci-cd-angular-avec-github-actions-netlify-ca0b59b99ed8
[article-2]: https://michaelheap.com/github-slug-action/
[article-3]: https://barstool.engineering/serverless-deploy-previews-on-github-actions/
[article-4]: https://javascript.plainenglish.io/lets-build-a-continuous-delivery-and-branching-process-c27dae09f0b6
[article-5]: https://eryajf.github.io/HowToStartOpenSource/views/03-github-tips/10-Use-github-slug-action-to-leak-key-variables-in-the-Github-Action-context.html
[article-6]: https://www.sfeir.dev/5-ans-de-github-slug-action-une-aventure-open-source/
[article-7]: https://www.romainlespinasse.dev/posts/celebrating-5-years-of-github-slug-action/
[talk-1]: https://www.youtube.com/watch?v=F5mBDmOQcvE

View File

@@ -2,23 +2,26 @@
## Supported Versions and Branches
| Version | Branch | Supported |
|---------|--------|--------------------|
| 3.x | v3.x | :white_check_mark: |
| 2.x | v2.x | :white_check_mark: |
| 1.1.x | v1.1.x | :white_check_mark: |
| < 1.0.x | master | :x: |
| Version | Supported | End of Support | Branch | Specific Tags |
| ------- | ------------------ | -------------- | ------ | ------------- |
| 5.x | :white_check_mark: | | v5.x | v5 |
| 4.x | :x: | 2025-01-31 | | v4.x, v4 |
| 3.x | :x: | 2024-01-31 | | v3.x, v3 |
| 2.x | :x: | 2021-04-05 | | v2.x, 2.2.0 |
| 1.x | :x: | 2021-04-05 | | v1.1.x, 1.2.0 |
| 1.0.x | :x: | 2019-11-07 | | 1.0.2 |
A GitHub repository can used one of the available branches as action inside its workflows.
A GitHub repository can use one of the available branches as an action inside its workflows.
### End of Life of a branch
Since `2023-10-20`, when a new major version is released,
- The previous one will continue to receive security patches for 3 months,
- After the 3 months, the branch is deleted, and only the tags remain.
## Reporting a Vulnerability
You can report a Vulnerability by [my email](mailto:romain.lespinasse@gmail.com).
In this project, you can report a Vulnerability by creating a [draft security advisory](https://github.com/rlespinasse/github-slug-action/security/advisories).
_Vulnerability stages :_
- Reported,
- Confirmed (or declined),
- Fixed on maintained version series.
After a vulnerability fix, an GitHub issue will be created as document this vulnerability.
If the vulnerability is confirmed, a fix will be produced and the advisory will be published.

View File

@@ -1,10 +0,0 @@
import {shortsha} from '../src/slug'
function test_short_sha(input: string, expected: string) {
let actual = shortsha(input)
expect(actual).toEqual(expected)
}
test('short_sha: long hash', () => {
test_short_sha('a35a1a486a260cfd99c5b6f8c6034a2929ba9b3f', 'a35a1a48')
})

View File

@@ -1,48 +0,0 @@
import {slug} from '../src/slug'
function test_slug(input: string, expected: string) {
let actual = slug(input)
expect(actual).toEqual(expected)
}
test('slug: a word', () => {
test_slug('word', 'word')
})
test('slug: a string', () => {
test_slug('basic-string', 'basic-string')
})
test('slug: a string in camel case', () => {
test_slug('camelCase', 'camelcase')
})
test('slug: a path', () => {
test_slug('path/to/something', 'path-to-something')
})
test('slug: a number', () => {
test_slug('4.2', '4.2')
})
test('slug: special caracter', () => {
test_slug('feat-(!è§-caracter', 'feat------caracter')
})
test('slug: trailing', () => {
test_slug('-feat-trailing-', 'feat-trailing')
})
test('slug: a very long string', () => {
test_slug(
'an-awesome-Feature-Very-Very-Very-Very-Very-Very-Very-Long-moreThan63Characters',
'an-awesome-feature-very-very-very-very-very-very-very-long-more'
)
})
test('slug: short string after trailing', () => {
test_slug(
'-an-awesome-Feature-Very-Very-Very-Very-Very-Very-Very-Long-moreThan63Characters-',
'an-awesome-feature-very-very-very-very-very-very-very-long-more'
)
})

View File

@@ -1,45 +0,0 @@
import {slugref} from '../src/slug'
function test_slug_ref(input: string, expected: string) {
let actual = slugref(input)
expect(actual).toEqual(expected)
}
test('slug_ref:: master branch', () => {
test_slug_ref('refs/heads/master', 'master')
})
test('slug_ref: a feature branch', () => {
test_slug_ref('refs/heads/feat/new_feature', 'feat-new-feature')
})
test('slug_ref: a fix branch', () => {
test_slug_ref('refs/heads/fix/issue_number', 'fix-issue-number')
})
test('slug_ref: a simple tag', () => {
test_slug_ref('refs/tags/v1.0.0', 'v1.0.0')
})
test('slug_ref: a complex tag', () => {
test_slug_ref('refs/tags/product@1.0.0-rc.2', 'product-1.0.0-rc.2')
})
test('slug_ref: a reference with upper case letters', () => {
test_slug_ref('refs/heads/New_Awesome_Product', 'new-awesome-product')
})
test('slug_ref: test trailing', () => {
test_slug_ref('refs/heads/-trailing-feat-', 'trailing-feat')
})
test('slug_ref: test refs inside string', () => {
test_slug_ref('refs/heads/-refs/tags/feature/-', 'refs-tags-feature')
})
test('slug_ref: a very long name', () => {
test_slug_ref(
'refs/heads/an-awesome-Feature-Very-Very-Very-Very-Very-Very-Very-Long-moreThan63Characters',
'an-awesome-feature-very-very-very-very-very-very-very-long-more'
)
})

View File

@@ -1,37 +0,0 @@
import {slugurl} from '../src/slug'
function test_slug_url(input: string, expected: string) {
let actual = slugurl(input)
expect(actual).toEqual(expected)
}
test('slug_url: a word', () => {
test_slug_url('word', 'word')
})
test('slug_url: a string', () => {
test_slug_url('basic-string', 'basic-string')
})
test('slug_url: a string in camel case', () => {
test_slug_url('camelCase', 'camelcase')
})
test('slug_url: a path', () => {
test_slug_url('path/to/something', 'path-to-something')
})
test('slug_url: a number', () => {
test_slug_url('4.2', '4-2')
})
test('slug_url: trailing', () => {
test_slug_url('.path.to.', 'path-to')
})
test('slug_url: a very long string', () => {
test_slug_url(
'an-awesome-Feature-Very-Very-Very-Very-Very-Very-Very-Long-moreThan63Characters',
'an-awesome-feature-very-very-very-very-very-very-very-long-more'
)
})

View File

@@ -1,45 +0,0 @@
import {slugurlref} from '../src/slug'
function test_slug_url_ref(input: string, expected: string) {
let actual = slugurlref(input)
expect(actual).toEqual(expected)
}
test('slug_url_ref: master branch', () => {
test_slug_url_ref('refs/heads/master', 'master')
})
test('slug_url_ref: a feature branch', () => {
test_slug_url_ref('refs/heads/feat/new_feature', 'feat-new-feature')
})
test('slug_url_ref: a fix branch', () => {
test_slug_url_ref('refs/heads/fix/issue_number', 'fix-issue-number')
})
test('slug_url_ref: a simple tag', () => {
test_slug_url_ref('refs/tags/v1.0.0', 'v1-0-0')
})
test('slug_url_ref: a complex tag', () => {
test_slug_url_ref('refs/tags/product@1.0.0-rc.2', 'product-1-0-0-rc-2')
})
test('slug_url_ref: a reference with upper case letters', () => {
test_slug_url_ref('refs/heads/New_Awesome_Product', 'new-awesome-product')
})
test('slug_url_ref: a very long name', () => {
test_slug_url_ref(
'refs/heads/an-awesome-Feature-Very-Very-Very-Very-Very-Very-Very-Long-moreThan63Characters',
'an-awesome-feature-very-very-very-very-very-very-very-long-more'
)
})
test('slug_url_ref: test trailing', () => {
test_slug_url_ref('refs/heads/-an-awesome-Feature-', 'an-awesome-feature')
})
test('slug_url_ref: test trailing with dot', () => {
test_slug_url_ref('refs/heads/.an-awesome-Feature.', 'an-awesome-feature')
})

View File

@@ -1,9 +1,120 @@
name: "GitHub Slug"
description: "Action to slug and expose some github variables"
author: 'rlespinasse'
runs:
using: 'node12'
main: 'dist/index.js'
name: "GitHub Slug Action"
description: "GitHub Action to expose slug value of environment variables inside your GitHub workflow"
author: "Romain Lespinasse"
branding:
icon: "crop"
color: "orange"
icon: "minimize"
color: "blue"
inputs:
prefix:
description: "Value to prepend to each generated variable"
default: ""
required: false
slug-maxlength:
description: "Max length of the slugified values"
default: "63"
required: true
short-length:
description: "Length of the shortify values (git default if empty)"
required: false
runs:
using: "composite"
steps:
- run: $GITHUB_ACTION_PATH/preflight.sh
id: prefligth
shell: bash
env:
INPUT_SLUG_MAXLENGTH: ${{ inputs.slug-maxlength }}
INPUT_SHORT_LENGTH: ${{ inputs.short-length }}
# From Environment Variables
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REPOSITORY
value: ${{ github.repository }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REF
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_HEAD_REF
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_BASE_REF
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
# From Specific values
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_EVENT_REF
value: ${{ github.event.ref }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REF_NAME
value: ${{ github.ref_name }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REF_POINT
value: ${{ env.GITHUB_HEAD_REF_RAW || env.GITHUB_REF_NAME_RAW }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
env:
GITHUB_HEAD_REF_RAW: ${{ github.head_ref }}
GITHUB_REF_NAME_RAW: ${{ github.ref_name }}
# From Calculated values
- id: get-github-repository-owner-part
run: |
ownerpart=$(echo $GITHUB_REPOSITORY | cut -d/ -f1)
if [ -f "$GITHUB_OUTPUT" ]; then
echo "github-repository-owner-part=${ownerpart}" >> "$GITHUB_OUTPUT"
else
echo "::set-output name=github-repository-owner-part::${ownerpart}"
fi
shell: bash
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REPOSITORY_OWNER_PART
value: ${{ steps.get-github-repository-owner-part.outputs.github-repository-owner-part }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
- id: get-github-repository-name-part
run: |
namepart=$(echo $GITHUB_REPOSITORY | cut -d/ -f2)
if [ -f "$GITHUB_OUTPUT" ]; then
echo "github-repository-name-part=${namepart}" >> "$GITHUB_OUTPUT"
else
echo "::set-output name=github-repository-name-part::${namepart}"
fi
shell: bash
- uses: rlespinasse/slugify-value@a4879db1eb3db9bbee01dca36f98a8236c2b8239 # v1.4.0
with:
key: GITHUB_REPOSITORY_NAME_PART
value: ${{ steps.get-github-repository-name-part.outputs.github-repository-name-part }}
prefix: ${{ inputs.prefix }}
slug-maxlength: ${{ inputs.slug-maxlength }}
# From sha
- uses: rlespinasse/shortify-git-revision@c90ba7007ef6c152254d10b9f1a327966ab13077 # v1.6.0
with:
name: GITHUB_SHA
short-on-error: true
length: ${{ steps.prefligth.outputs.PREFLIGHT_SHORT_LENGTH }}
prefix: ${{ inputs.prefix }}
- uses: rlespinasse/shortify-git-revision@c90ba7007ef6c152254d10b9f1a327966ab13077 # v1.6.0
with:
name: GITHUB_EVENT_PULL_REQUEST_HEAD_SHA
revision: ${{ github.event.pull_request.head.sha }}
short-on-error: true
length: ${{ steps.prefligth.outputs.PREFLIGHT_SHORT_LENGTH }}
prefix: ${{ inputs.prefix }}

672
dist/index.js vendored
View File

@@ -1,672 +0,0 @@
require('./sourcemap-register.js');module.exports =
/******/ (function(modules, runtime) { // webpackBootstrap
/******/ "use strict";
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ var threw = true;
/******/ try {
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ threw = false;
/******/ } finally {
/******/ if(threw) delete installedModules[moduleId];
/******/ }
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ __webpack_require__.ab = __dirname + "/";
/******/
/******/ // the startup function
/******/ function startup() {
/******/ // Load entry module and return exports
/******/ return __webpack_require__(109);
/******/ };
/******/
/******/ // run startup
/******/ return startup();
/******/ })
/************************************************************************/
/******/ ({
/***/ 87:
/***/ (function(module) {
module.exports = require("os");
/***/ }),
/***/ 109:
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(186));
const slug_1 = __webpack_require__(565);
/**
* Inputs environments variables keys from Github actions job
* see https://docs.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
*/
const GITHUB_REPOSITORY = 'GITHUB_REPOSITORY';
const GITHUB_REF = 'GITHUB_REF';
const GITHUB_HEAD_REF = 'GITHUB_HEAD_REF';
const GITHUB_BASE_REF = 'GITHUB_BASE_REF';
const GITHUB_SHA = 'GITHUB_SHA';
const GITHUB_EVENT_PATH = 'GITHUB_EVENT_PATH';
/**
* Slugged outputs environments variables keys
*/
const GITHUB_REPOSITORY_SLUG = 'GITHUB_REPOSITORY_SLUG';
const GITHUB_REPOSITORY_SLUG_URL = 'GITHUB_REPOSITORY_SLUG_URL';
const GITHUB_REF_SLUG = 'GITHUB_REF_SLUG';
const GITHUB_HEAD_REF_SLUG = 'GITHUB_HEAD_REF_SLUG';
const GITHUB_BASE_REF_SLUG = 'GITHUB_BASE_REF_SLUG';
const GITHUB_REF_SLUG_URL = 'GITHUB_REF_SLUG_URL';
const GITHUB_HEAD_REF_SLUG_URL = 'GITHUB_HEAD_REF_SLUG_URL';
const GITHUB_BASE_REF_SLUG_URL = 'GITHUB_BASE_REF_SLUG_URL';
const GITHUB_SHA_SHORT = 'GITHUB_SHA_SHORT';
const GITHUB_EVENT_REF_SLUG = 'GITHUB_EVENT_REF_SLUG';
const GITHUB_EVENT_REF_SLUG_URL = 'GITHUB_EVENT_REF_SLUG_URL';
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const eventPath = process.env[GITHUB_EVENT_PATH];
if (eventPath) {
const eventData = yield Promise.resolve().then(() => __importStar(require(eventPath)));
if (eventData.hasOwnProperty('ref')) {
core.exportVariable(GITHUB_EVENT_REF_SLUG, slug_1.slugref(eventData.ref));
core.exportVariable(GITHUB_EVENT_REF_SLUG_URL, slug_1.slugurlref(eventData.ref));
}
}
exportSlug(GITHUB_REPOSITORY, GITHUB_REPOSITORY_SLUG);
exportSlugUrl(GITHUB_REPOSITORY, GITHUB_REPOSITORY_SLUG_URL);
exportSlugRef(GITHUB_REF, GITHUB_REF_SLUG);
exportSlugRef(GITHUB_HEAD_REF, GITHUB_HEAD_REF_SLUG);
exportSlugRef(GITHUB_BASE_REF, GITHUB_BASE_REF_SLUG);
exportSlugUrlRef(GITHUB_REF, GITHUB_REF_SLUG_URL);
exportSlugUrlRef(GITHUB_HEAD_REF, GITHUB_HEAD_REF_SLUG_URL);
exportSlugUrlRef(GITHUB_BASE_REF, GITHUB_BASE_REF_SLUG_URL);
exportShortSha(GITHUB_SHA, GITHUB_SHA_SHORT);
}
catch (error) {
core.setFailed(error.message);
}
});
}
function exportSlug(inputKey, outputKey) {
const envVar = process.env[inputKey];
if (envVar) {
core.exportVariable(outputKey, slug_1.slug(envVar));
}
}
function exportSlugRef(inputKey, outputKey) {
const envVar = process.env[inputKey];
if (envVar) {
core.exportVariable(outputKey, slug_1.slugref(envVar));
}
}
function exportSlugUrl(inputKey, outputKey) {
const envVar = process.env[inputKey];
if (envVar) {
core.exportVariable(outputKey, slug_1.slugurl(envVar));
}
}
function exportSlugUrlRef(inputKey, outputKey) {
const envVar = process.env[inputKey];
if (envVar) {
core.exportVariable(outputKey, slug_1.slugurlref(envVar));
}
}
function exportShortSha(inputKey, outputKey) {
const envVar = process.env[inputKey];
if (envVar) {
core.exportVariable(outputKey, slug_1.shortsha(envVar));
}
}
run();
/***/ }),
/***/ 186:
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const command_1 = __webpack_require__(351);
const file_command_1 = __webpack_require__(717);
const utils_1 = __webpack_require__(278);
const os = __importStar(__webpack_require__(87));
const path = __importStar(__webpack_require__(622));
/**
* The code to exit an action
*/
var ExitCode;
(function (ExitCode) {
/**
* A code indicating that the action was successful
*/
ExitCode[ExitCode["Success"] = 0] = "Success";
/**
* A code indicating that the action was a failure
*/
ExitCode[ExitCode["Failure"] = 1] = "Failure";
})(ExitCode = exports.ExitCode || (exports.ExitCode = {}));
//-----------------------------------------------------------------------
// Variables
//-----------------------------------------------------------------------
/**
* Sets env variable for this action and future actions in the job
* @param name the name of the variable to set
* @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function exportVariable(name, val) {
const convertedVal = utils_1.toCommandValue(val);
process.env[name] = convertedVal;
const filePath = process.env['GITHUB_ENV'] || '';
if (filePath) {
const delimiter = '_GitHubActionsFileCommandDelimeter_';
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
file_command_1.issueCommand('ENV', commandValue);
}
else {
command_1.issueCommand('set-env', { name }, convertedVal);
}
}
exports.exportVariable = exportVariable;
/**
* Registers a secret which will get masked from logs
* @param secret value of the secret
*/
function setSecret(secret) {
command_1.issueCommand('add-mask', {}, secret);
}
exports.setSecret = setSecret;
/**
* Prepends inputPath to the PATH (for this action and future actions)
* @param inputPath
*/
function addPath(inputPath) {
const filePath = process.env['GITHUB_PATH'] || '';
if (filePath) {
file_command_1.issueCommand('PATH', inputPath);
}
else {
command_1.issueCommand('add-path', {}, inputPath);
}
process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`;
}
exports.addPath = addPath;
/**
* Gets the value of an input. The value is also trimmed.
*
* @param name name of the input to get
* @param options optional. See InputOptions.
* @returns string
*/
function getInput(name, options) {
const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || '';
if (options && options.required && !val) {
throw new Error(`Input required and not supplied: ${name}`);
}
return val.trim();
}
exports.getInput = getInput;
/**
* Sets the value of an output.
*
* @param name name of the output to set
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setOutput(name, value) {
command_1.issueCommand('set-output', { name }, value);
}
exports.setOutput = setOutput;
/**
* Enables or disables the echoing of commands into stdout for the rest of the step.
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
*
*/
function setCommandEcho(enabled) {
command_1.issue('echo', enabled ? 'on' : 'off');
}
exports.setCommandEcho = setCommandEcho;
//-----------------------------------------------------------------------
// Results
//-----------------------------------------------------------------------
/**
* Sets the action status to failed.
* When the action exits it will be with an exit code of 1
* @param message add error issue message
*/
function setFailed(message) {
process.exitCode = ExitCode.Failure;
error(message);
}
exports.setFailed = setFailed;
//-----------------------------------------------------------------------
// Logging Commands
//-----------------------------------------------------------------------
/**
* Gets whether Actions Step Debug is on or not
*/
function isDebug() {
return process.env['RUNNER_DEBUG'] === '1';
}
exports.isDebug = isDebug;
/**
* Writes debug message to user log
* @param message debug message
*/
function debug(message) {
command_1.issueCommand('debug', {}, message);
}
exports.debug = debug;
/**
* Adds an error issue
* @param message error issue message. Errors will be converted to string via toString()
*/
function error(message) {
command_1.issue('error', message instanceof Error ? message.toString() : message);
}
exports.error = error;
/**
* Adds an warning issue
* @param message warning issue message. Errors will be converted to string via toString()
*/
function warning(message) {
command_1.issue('warning', message instanceof Error ? message.toString() : message);
}
exports.warning = warning;
/**
* Writes info to log with console.log.
* @param message info message
*/
function info(message) {
process.stdout.write(message + os.EOL);
}
exports.info = info;
/**
* Begin an output group.
*
* Output until the next `groupEnd` will be foldable in this group
*
* @param name The name of the output group
*/
function startGroup(name) {
command_1.issue('group', name);
}
exports.startGroup = startGroup;
/**
* End an output group.
*/
function endGroup() {
command_1.issue('endgroup');
}
exports.endGroup = endGroup;
/**
* Wrap an asynchronous function call in a group.
*
* Returns the same type as the function itself.
*
* @param name The name of the group
* @param fn The function to wrap in the group
*/
function group(name, fn) {
return __awaiter(this, void 0, void 0, function* () {
startGroup(name);
let result;
try {
result = yield fn();
}
finally {
endGroup();
}
return result;
});
}
exports.group = group;
//-----------------------------------------------------------------------
// Wrapper action state
//-----------------------------------------------------------------------
/**
* Saves state for current action, the state can only be retrieved by this action's post job execution.
*
* @param name name of the state to store
* @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function saveState(name, value) {
command_1.issueCommand('save-state', { name }, value);
}
exports.saveState = saveState;
/**
* Gets the value of an state set by this action's main execution.
*
* @param name name of the state to get
* @returns string
*/
function getState(name) {
return process.env[`STATE_${name}`] || '';
}
exports.getState = getState;
//# sourceMappingURL=core.js.map
/***/ }),
/***/ 278:
/***/ (function(__unusedmodule, exports) {
"use strict";
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Sanitizes an input into a string so it can be passed into issueCommand safely
* @param input input to sanitize into a string
*/
function toCommandValue(input) {
if (input === null || input === undefined) {
return '';
}
else if (typeof input === 'string' || input instanceof String) {
return input;
}
return JSON.stringify(input);
}
exports.toCommandValue = toCommandValue;
//# sourceMappingURL=utils.js.map
/***/ }),
/***/ 351:
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(__webpack_require__(87));
const utils_1 = __webpack_require__(278);
/**
* Commands
*
* Command Format:
* ::name key=value,key=value::message
*
* Examples:
* ::warning::This is the message
* ::set-env name=MY_VAR::some value
*/
function issueCommand(command, properties, message) {
const cmd = new Command(command, properties, message);
process.stdout.write(cmd.toString() + os.EOL);
}
exports.issueCommand = issueCommand;
function issue(name, message = '') {
issueCommand(name, {}, message);
}
exports.issue = issue;
const CMD_STRING = '::';
class Command {
constructor(command, properties, message) {
if (!command) {
command = 'missing.command';
}
this.command = command;
this.properties = properties;
this.message = message;
}
toString() {
let cmdStr = CMD_STRING + this.command;
if (this.properties && Object.keys(this.properties).length > 0) {
cmdStr += ' ';
let first = true;
for (const key in this.properties) {
if (this.properties.hasOwnProperty(key)) {
const val = this.properties[key];
if (val) {
if (first) {
first = false;
}
else {
cmdStr += ',';
}
cmdStr += `${key}=${escapeProperty(val)}`;
}
}
}
}
cmdStr += `${CMD_STRING}${escapeData(this.message)}`;
return cmdStr;
}
}
function escapeData(s) {
return utils_1.toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A');
}
function escapeProperty(s) {
return utils_1.toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A')
.replace(/:/g, '%3A')
.replace(/,/g, '%2C');
}
//# sourceMappingURL=command.js.map
/***/ }),
/***/ 565:
/***/ (function(__unusedmodule, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shortsha = exports.slugurlref = exports.slugurl = exports.slugref = exports.slug = void 0;
const MAX_SLUG_STRING_SIZE = 63;
const SHORT_SHA_SIZE = 8;
/**
* slug will take envVar and then :
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`, and `.`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
function slug(envVar) {
return trailHyphen(replaceAnyNonAlphanumericCaracter(envVar.toLowerCase())).substring(0, MAX_SLUG_STRING_SIZE);
}
exports.slug = slug;
/**
* slug will take envVar and then :
* - remove refs/(heads|tags)/
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`, and `.`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
function slugref(envVar) {
return slug(removeRef(envVar.toLowerCase()));
}
exports.slugref = slugref;
/**
* slug will take envVar and then :
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
function slugurl(envVar) {
return slug(replaceAnyDotToHyphen(envVar));
}
exports.slugurl = slugurl;
/**
* slug will take envVar and then :
* - remove refs/(heads|tags)/
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
function slugurlref(envVar) {
return slugurl(slugref(envVar));
}
exports.slugurlref = slugurlref;
/**
* slug will take envVar and then :
* - limit the string size to 8 characters
* @param envVar to be slugged
*/
function shortsha(envVar) {
return envVar.substring(0, SHORT_SHA_SIZE);
}
exports.shortsha = shortsha;
function trailHyphen(envVar) {
return envVar.replace(RegExp('^-*', 'g'), '').replace(RegExp('-*$', 'g'), '');
}
function replaceAnyNonAlphanumericCaracter(envVar) {
return envVar.replace(RegExp('[^a-z0-9.]', 'g'), '-');
}
function replaceAnyDotToHyphen(envVar) {
return envVar.replace(RegExp('[.]', 'g'), '-');
}
function removeRef(envVar) {
return envVar.replace(RegExp('^refs/(heads|tags)/'), '');
}
/***/ }),
/***/ 622:
/***/ (function(module) {
module.exports = require("path");
/***/ }),
/***/ 717:
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
// For internal use, subject to change.
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
const fs = __importStar(__webpack_require__(747));
const os = __importStar(__webpack_require__(87));
const utils_1 = __webpack_require__(278);
function issueCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`];
if (!filePath) {
throw new Error(`Unable to find environment variable for file command ${command}`);
}
if (!fs.existsSync(filePath)) {
throw new Error(`Missing file at path: ${filePath}`);
}
fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, {
encoding: 'utf8'
});
}
exports.issueCommand = issueCommand;
//# sourceMappingURL=file-command.js.map
/***/ }),
/***/ 747:
/***/ (function(module) {
module.exports = require("fs");
/***/ })
/******/ });
//# sourceMappingURL=index.js.map

1
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
# Slug Transformation Rules
This page explains the transformation algorithms used by the GitHub Slug Action, why they exist, and how they differ from each other.
## What is a "slug"?
A slug is a human-readable identifier derived from a string, safe for use in URLs, filenames, DNS labels, and other contexts where special characters are problematic. The term originates from publishing, where a "slug" is a short label used to identify a piece of content.
In CI/CD workflows, branch names, tag names, and repository names often contain characters (`/`, `@`, spaces) that break when used in URLs, Docker tags, Kubernetes labels, or file paths. Slugifying these values makes them safe for such contexts.
## SLUG transformation
The `SLUG` transformation applies the following steps in order:
1. **Lowercase** the entire string
2. **Replace** any character that is not `0-9`, `a-z`, `.`, or `_` with `-`
3. **Remove** leading `-` characters
4. **Truncate** to a maximum length (default: 63 characters)
5. **Remove** trailing `-` characters
### SLUG examples
| Input | Output |
| ----- | ------ |
| `refs/heads/feat/new_feature` | `feat-new-feature` |
| `refs/tags/v1.0.0` | `v1.0.0` |
| `refs/tags/product@1.0.0-rc.2` | `product-1.0.0-rc.2` |
| `octocat/Hello-World` | `octocat-hello-world` |
Note that `.` and `_` are preserved in SLUG output.
## SLUG_URL transformation
The `SLUG_URL` transformation is identical to `SLUG` except that `.` and `_` are also replaced with `-` in step 2. This makes the result safe for use as a URL path segment or subdomain label, where dots and underscores can cause issues.
### SLUG_URL examples
| Input | SLUG | SLUG_URL |
| ----- | ---- | -------- |
| `refs/tags/v1.0.0` | `v1.0.0` | `v1-0-0` |
| `rlespinasse/Hello-World.go` | `rlespinasse-hello-world.go` | `rlespinasse-hello-world-go` |
| `refs/heads/feat/new_feature` | `feat-new-feature` | `feat-new-feature` |
### When to use which
- Use **SLUG** for Docker tags, file paths, and general identifiers (dots and underscores are allowed)
- Use **SLUG_URL** for subdomains, URL path segments, and any context where dots or underscores are problematic
## Why 63 characters?
The default maximum length of 63 comes from the [DNS label length limit](https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4). This is also the maximum length for:
- Kubernetes resource labels
- Many cloud provider resource names
- DNS subdomain components
You can change this limit with the `slug-maxlength` input, or set it to `"nolimit"` to disable truncation entirely.
## SHORT transformation
The `SHORT` transformation truncates Git commit SHAs to a shorter, still-unique prefix. By default, Git determines the optimal length based on your repository size using [`git rev-parse --short`][git-revparse].
| Input | Output |
| ----- | ------ |
| `ffac537e6cbbf934b08745a378932722df287a53` | `ffac537e` |
The length varies by repository because larger repositories need longer prefixes to avoid collisions. You can set a fixed length with the `short-length` input (minimum: 4).
## Case-sensitive variants (_CS)
Every `SLUG` and `SLUG_URL` variable also has a `_CS` (case-sensitive) variant that skips the lowercase step. For example:
| Input | SLUG | SLUG_CS |
| ----- | ---- | ------- |
| `refs/heads/New_Awesome_Product` | `new-awesome-product` | `New-Awesome-Product` |
This is useful when the original casing carries meaning (e.g., product names).
## PART extraction
The `PART` transformation splits a composite value and extracts a portion. Currently used for `GITHUB_REPOSITORY`:
| Input | OWNER_PART | NAME_PART |
| ----- | ---------- | --------- |
| `octocat/Hello-World` | `octocat` | `Hello-World` |
PART variables preserve the original casing. They can be further transformed using SLUG or SLUG_URL suffixes (e.g., `GITHUB_REPOSITORY_OWNER_PART_SLUG`).
[git-revparse]: https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---shortlength

101
docs/getting-started.md Normal file
View File

@@ -0,0 +1,101 @@
# Getting Started with GitHub Slug Action
This tutorial walks you through adding the GitHub Slug Action to a workflow and using slug variables for the first time.
## Prerequisites
- A GitHub repository with [GitHub Actions enabled](https://docs.github.com/en/actions/using-workflows)
## Step 1: Add the action to your workflow
Create or edit a workflow file (e.g., `.github/workflows/deploy.yml`) and add the action after checking out your code:
```yaml
name: Deploy
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
```
> [!TIP]
> The `actions/checkout` step is recommended so that Git can determine the optimal short SHA length for your repository. It is not strictly required for slug variables.
## Step 2: Use slug variables in subsequent steps
After the action runs, all slug variables are available as environment variables. Add a step to use them:
```yaml
- name: Print slug variables
run: |
echo "Repository slug: $GITHUB_REPOSITORY_SLUG"
echo "Branch slug: $GITHUB_REF_SLUG"
echo "Short SHA: $GITHUB_SHA_SHORT"
shell: bash
```
For a branch named `feat/new_feature` on repository `octocat/Hello-World`, this outputs:
```text
Repository slug: octocat-hello-world
Branch slug: feat-new-feature
Short SHA: ffac537e
```
## Step 3: Use a slug variable for a practical purpose
A common use case is naming deployment previews with a URL-safe branch identifier:
```yaml
- name: Deploy preview
run: |
echo "Deploying to https://${GITHUB_REF_SLUG_URL}.preview.example.com"
shell: bash
```
The `SLUG_URL` variant replaces dots and underscores too, making it safe for subdomains.
## Complete workflow
Here is the full workflow file:
```yaml
name: Deploy
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
- name: Deploy preview
run: |
echo "Deploying to https://${GITHUB_REF_SLUG_URL}.preview.example.com"
echo "Commit: ${GITHUB_SHA_SHORT}"
shell: bash
```
## What you learned
- **SLUG** variables convert values to lowercase and replace special characters with `-`
- **SLUG_URL** variables also replace `.` and `_`, making values safe for URLs and subdomains
- **SHORT** variables shorten SHA commit hashes
- All variables are exposed as environment variables for use in subsequent steps
## Next steps
- [How-to guides](how-to/) for specific configuration tasks (prefixes, custom lengths, URL usage)
- [Variable reference](reference/variables.md) for the complete list of available variables
- [Slug transformation rules](explanation/slug-transformation-rules.md) to understand how transformations work

3
docs/github-variables.md Normal file
View File

@@ -0,0 +1,3 @@
# Available GitHub Variables
This page has moved to [reference/github-variables.md](reference/github-variables.md).

View File

@@ -0,0 +1,45 @@
# Configure the length of short SHA values
Set a specific length for shortened commit SHA values instead of letting Git determine it automatically.
## Usage
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
with:
short-length: 7
```
## Common values
| Value | Use case |
| ----- | -------- |
| _(empty)_ | Let Git decide based on repository size (default) |
| `7` | Common "small repository" length |
| `8` | Reproduce `v3` action behaviour |
| `4` | Minimum allowed length |
## Letting Git decide (default)
When `short-length` is left empty, the action uses Git's [`git rev-parse --short`][git-revparse] behaviour. The length depends on the size of your repository and may change over time as the repository grows.
> [!WARNING]
> If you leave `short-length` empty, you need to checkout the source first so Git can determine the length:
>
> ```yaml
> steps:
> - uses: actions/checkout@v6
> - uses: rlespinasse/github-slug-action@v5
> ```
>
> Without a checkout step, the action falls back to the effective value of the [`core.abbrev`][git-core-abbrev] Git configuration variable, or `7` if unavailable.
## See also
- [Inputs reference](../reference/inputs.md) for the full specification
- [SHORT transformation](../explanation/slug-transformation-rules.md#short-transformation) for how short values are computed
[git-revparse]: https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---shortlength
[git-core-abbrev]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev

View File

@@ -0,0 +1,33 @@
# Configure the maximum length for slug values
Change the maximum length of slugified values. The default is 63 characters (the DNS label length limit).
## Usage
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
with:
slug-maxlength: 80
```
## Disable the length limit
Set `slug-maxlength` to `"nolimit"` to disable truncation entirely:
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
with:
slug-maxlength: nolimit
```
> [!WARNING]
> The `slug-maxlength` input must not be empty. If left empty, the action will fail during preflight validation.
## See also
- [Inputs reference](../reference/inputs.md) for the full specification
- [Why 63 characters?](../explanation/slug-transformation-rules.md#why-63-characters) for the rationale behind the default

View File

@@ -0,0 +1,30 @@
# Migrate from v3 to v4
The main breaking change in v4 is that **short SHA length** is now determined by Git instead of being fixed at 8 characters.
## What changed
Since v4, Git manages the short variables using [`git rev-parse`][git-revparse] behaviour. The length of a short SHA depends on the size of your repository and can change over time as the repository grows.
## How to migrate
To reproduce the previous fixed-length behaviour, set `short-length` to `8`:
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
with:
short-length: 8 # Same as v3 and before
```
Other options:
- Set `7` to reproduce small repository behaviour
- Leave empty to let Git decide (recommended)
> [!WARNING]
> The minimum length is `4`. The default is the effective value of the [`core.abbrev`][git-core-abbrev] Git configuration variable.
[git-revparse]: https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---shortlength
[git-core-abbrev]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev

View File

@@ -0,0 +1,30 @@
# Migrate from v4 to v5
The main breaking change in v5 is that **GITHUB_REF_NAME** slug variables now match GitHub's native behaviour on `pull_request*` events.
## What changed
Before v5, the action overrode `GITHUB_REF_NAME` to always contain the branch name, even on pull request events. Starting with v5, `GITHUB_REF_NAME` on pull request events contains `<PR-number>/merge` (matching GitHub's native behaviour). Read the [full story][issue-104].
## How to migrate
If you used `GITHUB_REF_NAME_SLUG` to get the branch name on pull request events, switch to `GITHUB_REF_POINT_SLUG`:
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
- run: |
echo "Branch Name: ${GITHUB_REF_POINT}"
shell: bash
```
`GITHUB_REF_POINT` provides the branch name on pull request events (via `GITHUB_HEAD_REF`) and the ref name on all other events (via `GITHUB_REF_NAME`). All slug suffixes are available: `GITHUB_REF_POINT_SLUG`, `GITHUB_REF_POINT_SLUG_URL`, etc.
## Expression syntax
- `${{ env.GITHUB_REF_POINT }}` and `$GITHUB_REF_POINT` both serve the action's behaviour
- `${{ env.GITHUB_REF_NAME }}` serves the action's behaviour
- `$GITHUB_REF_NAME` serves GitHub Action's native behaviour
[issue-104]: https://github.com/rlespinasse/github-slug-action/issues/104

View File

@@ -0,0 +1,56 @@
# Troubleshooting
## One of the environment variables doesn't work as intended
> [!WARNING]
> When you set a custom environment variable, you [cannot use any of the default environment variable names][naming-conventions]. For a complete list of these, see [Default environment variables][default-environment-variables]. **If you attempt to override the value of one of these default environment variables, the assignment is ignored.**
If a variable starts to be used as a default environment variable by GitHub, the behaviour may differ depending on how you reference it:
- `${{ env.GITHUB_AWESOME_VARIABLE }}` serves the behaviour of this action
- `$GITHUB_AWESOME_VARIABLE` serves the behaviour of GitHub Actions
If both expressions return the same value, the variable is not affected. Use the [`prefix` input](use-prefix.md) to avoid this issue entirely.
> [!IMPORTANT]
> If detected, the maintainers of this action will choose the best course of action depending on the impact.
## An action could not be found at the URI
If your workflow fails on the `Set up job` task with this kind of log:
```text
Download action repository 'rlespinasse/github-slug-action@GIT_REFERENCE'
##[error]An action could not be found at the URI 'https://api.github.com/repos/rlespinasse/github-slug-action/tarball/GIT_REFERENCE'
```
If the `GIT_REFERENCE` value is:
- `v4.x` or after: following the [end-of-life for a branch](../../SECURITY.md#end-of-life-of-a-branch) security process, this branch may have been deleted.
- `master`: this branch no longer exists. Read more on the corresponding issue ([EOL issue][issue-15]).
Use the current **major tag** `v5` or a specific version tag (see [releases][releases]) to fix your workflow.
## Short variables are empty or have unexpected length
If `GITHUB_SHA_SHORT` is empty or shorter than expected, ensure you have checked out your repository before the action runs:
```yaml
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
```
Without a checkout, Git cannot determine the optimal short length for your repository. Alternatively, set a fixed `short-length` to avoid depending on the checkout:
```yaml
steps:
- uses: rlespinasse/github-slug-action@v5
with:
short-length: 7
```
[naming-conventions]: https://docs.github.com/en/actions/reference/workflows-and-actions/variables#naming-conventions-for-configuration-variables
[default-environment-variables]: https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
[issue-15]: https://github.com/rlespinasse/github-slug-action/issues/15
[releases]: https://github.com/rlespinasse/github-slug-action/releases

26
docs/how-to/use-prefix.md Normal file
View File

@@ -0,0 +1,26 @@
# Use a prefix for generated variables
Add a prefix to all generated environment variables to avoid naming conflicts with [GitHub's default environment variables](https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables).
## Usage
```yaml
steps:
- name: Inject enhanced GitHub environment variables
uses: rlespinasse/github-slug-action@v5
with:
prefix: CI_
```
With this configuration, variables are named `CI_GITHUB_REPOSITORY_SLUG`, `CI_GITHUB_REF_SLUG`, `CI_GITHUB_SHA_SHORT`, etc.
## When to use a prefix
- When a variable name collides with a GitHub default environment variable (the assignment would be silently ignored without a prefix)
- When you want to distinguish slug variables from other environment variables in your workflow
- As a preventive measure against future GitHub environment variable additions
## See also
- [Inputs reference](../reference/inputs.md) for the full `prefix` input specification
- [Troubleshooting](troubleshooting.md#one-of-the-environment-variables-doesnt-work-as-intended) for details on variable name collisions

View File

@@ -0,0 +1,36 @@
# Use slug variables in URLs
Use `SLUG_URL` variables (not `SLUG`) when building URLs, because `SLUG_URL` also replaces dots and underscores with hyphens, making values safe for subdomains and URL paths.
## As a subdomain
```yaml
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- run: |
./deploy-application.sh --url "https://${{ env.GITHUB_REF_SLUG_URL }}.staging.app.example.com"
```
For a branch `feat/new_feature`, this produces `https://feat-new-feature.staging.app.example.com`.
## As a URL path segment
```yaml
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- run: |
./deploy-application.sh --url "https://staging.app.example.com/${{ env.GITHUB_REF_SLUG_URL }}"
```
## Why SLUG_URL instead of SLUG?
The `SLUG` transformation preserves `.` and `_` characters. In a subdomain like `v1.0.0.staging.example.com`, the dots from the version tag would create invalid DNS resolution. `SLUG_URL` replaces them: `v1-0-0.staging.example.com`.
See [Slug transformation rules](../explanation/slug-transformation-rules.md#slug_url-transformation) for the full comparison.
## See also
- [Full example workflow](../../examples/url-use.yml)
- [Variable reference](../reference/variables.md) for all available `SLUG_URL` variables

View File

@@ -0,0 +1,3 @@
# Partial Variables
This page has moved to [reference/variables.md](reference/variables.md#partial-variables).

View File

@@ -0,0 +1,87 @@
# Available GitHub Variables
All GitHub variables available in your workflow in addition to ones exposed by this action.
## Default Environment Variables
Read the official documentation about [Default environment variables][1].
### Action-managed Environment Variables
| Action-managed Variables | Can be suffixed by |
| ------------------------ | ------------------ |
| GITHUB_REPOSITORY | `_SLUG`, `_SLUG_URL` |
| GITHUB_REF | `_SLUG`, `_SLUG_URL` |
| GITHUB_REF_NAME | `_SLUG`, `_SLUG_URL` |
| GITHUB_HEAD_REF | `_SLUG`, `_SLUG_URL` |
| GITHUB_BASE_REF | `_SLUG`, `_SLUG_URL` |
| GITHUB_SHA | `_SHORT` |
## Variables from Events
Read the official documentation about [Events that trigger workflows][2].
### Action-managed Event Variables
#### create
Checkout [create][3] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.ref | GITHUB_EVENT_REF_SLUG |
| github.event.ref | GITHUB_EVENT_REF_SLUG_URL |
#### delete
Checkout [delete][4] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.ref | GITHUB_EVENT_REF_SLUG |
| github.event.ref | GITHUB_EVENT_REF_SLUG_URL |
#### pull_request
Checkout [pull_request][5] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.pull_request.head.sha | GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT |
#### pull_request_review
Checkout [pull_request_review][6] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.pull_request.head.sha | GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT |
#### pull_request_review_comment
Checkout [pull_request_review_comment][7] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.pull_request.head.sha | GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT |
#### pull_request_target
Checkout [pull_request][5] webhook payload content
| Action-managed Variables | Available as |
| ------------------------ | ------------ |
| github.event.pull_request.head.sha | GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT |
## See also
- [Variable reference](variables.md) for transformation examples
- [Slug transformation rules](../explanation/slug-transformation-rules.md) for how transformations work
[1]: https://docs.github.com/en/actions/reference/environment-variables#default-environment-variables
[2]: https://docs.github.com/en/actions/reference/events-that-trigger-workflows
[3]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#create
[4]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#delete
[5]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#pull_request
[6]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#pull_request_review
[7]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads#pull_request_review_comment

23
docs/reference/inputs.md Normal file
View File

@@ -0,0 +1,23 @@
# Inputs Reference
The GitHub Slug Action accepts the following inputs in the `with:` block.
| Input | Required | Default | Description |
| ----- | -------- | ------- | ----------- |
| `prefix` | No | `""` | Value prepended to each generated variable name. For example, `prefix: CI_` produces `CI_GITHUB_REPOSITORY_SLUG` instead of `GITHUB_REPOSITORY_SLUG`. |
| `slug-maxlength` | Yes | `63` | Maximum length of slugified values. Accepts a number or `"nolimit"` to disable truncation. Must not be empty. |
| `short-length` | No | _(Git default)_ | Length of shortened SHA values. Minimum `4`. When empty, Git determines the length based on your repository size using [`git rev-parse`][git-revparse]. |
## Notes
- When `short-length` is left empty, the action uses the effective value of the [`core.abbrev`][git-core-abbrev] Git configuration variable. This requires your repository to be checked out first (via `actions/checkout`).
- The `slug-maxlength` default of `63` matches the DNS label length limit, which is also the maximum length for Kubernetes labels.
## See also
- [How to use a prefix](../how-to/use-prefix.md)
- [How to configure slug max length](../how-to/configure-slug-maxlength.md)
- [How to configure short length](../how-to/configure-short-length.md)
[git-revparse]: https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt---shortlength
[git-core-abbrev]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev

312
docs/reference/variables.md Normal file
View File

@@ -0,0 +1,312 @@
# Variable Reference
Complete reference for all environment variables generated by the GitHub Slug Action.
> [!TIP]
> All slug and slug-url variables are also available in case-sensitive (`_CS`) variants. See [Case-sensitive variants](#case-sensitive-variants).
## Summary
| Variable | Type | Description |
| -------- | ---- | ----------- |
| `GITHUB_REF_POINT` | Enhanced | Branch or tag name (consistent across event types) |
| `GITHUB_REPOSITORY_OWNER_PART` | Partial | Owner extracted from `GITHUB_REPOSITORY` |
| `GITHUB_REPOSITORY_NAME_PART` | Partial | Repository name extracted from `GITHUB_REPOSITORY` |
| `GITHUB_REPOSITORY_SLUG` | Slug | Slugified owner/repository name |
| `GITHUB_REPOSITORY_OWNER_PART_SLUG` | Slug | Slugified owner name |
| `GITHUB_REPOSITORY_NAME_PART_SLUG` | Slug | Slugified repository name |
| `GITHUB_REF_SLUG` | Slug | Slugified branch or tag ref |
| `GITHUB_REF_NAME_SLUG` | Slug | Slugified branch or tag name |
| `GITHUB_HEAD_REF_SLUG` | Slug | Slugified PR head branch |
| `GITHUB_BASE_REF_SLUG` | Slug | Slugified PR base branch |
| `GITHUB_EVENT_REF_SLUG` | Slug | Slugified webhook ref |
| `GITHUB_REPOSITORY_SLUG_URL` | Slug URL | URL-safe owner/repository name |
| `GITHUB_REPOSITORY_OWNER_PART_SLUG_URL` | Slug URL | URL-safe owner name |
| `GITHUB_REPOSITORY_NAME_PART_SLUG_URL` | Slug URL | URL-safe repository name |
| `GITHUB_REF_SLUG_URL` | Slug URL | URL-safe branch or tag ref |
| `GITHUB_REF_NAME_SLUG_URL` | Slug URL | URL-safe branch or tag name |
| `GITHUB_HEAD_REF_SLUG_URL` | Slug URL | URL-safe PR head branch |
| `GITHUB_BASE_REF_SLUG_URL` | Slug URL | URL-safe PR base branch |
| `GITHUB_EVENT_REF_SLUG_URL` | Slug URL | URL-safe webhook ref |
| `GITHUB_SHA_SHORT` | Short | Shortened commit SHA |
| `GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT` | Short | Shortened PR head commit SHA |
---
## Enhanced Variables
### GITHUB_REF_POINT
The reference name (branch or tag), consistent across all event types:
- Uses `GITHUB_HEAD_REF` in [`pull_request*`][webhooks] event contexts
- Uses `GITHUB_REF_NAME` in all other event contexts
This provides a stable branch name regardless of event type. On pull request events, `GITHUB_REF_NAME` contains `<PR#>/merge`, while `GITHUB_REF_POINT` contains the actual branch name.
Available with all slug suffixes: `GITHUB_REF_POINT_SLUG`, `GITHUB_REF_POINT_SLUG_URL`, `GITHUB_REF_POINT_SLUG_CS`, `GITHUB_REF_POINT_SLUG_URL_CS`.
---
## Partial Variables
### GITHUB_REPOSITORY_OWNER_PART
Owner part of the environment variable **GITHUB_REPOSITORY**.
| GITHUB_REPOSITORY | GITHUB_REPOSITORY_OWNER_PART |
| ----------------- | ---------------------------- |
| octocat/Hello-World | octocat |
| rlespinasse/Hello-World.go | rlespinasse |
| AnotherPerson/SomeRepository | AnotherPerson |
### GITHUB_REPOSITORY_NAME_PART
Repository name part of the environment variable **GITHUB_REPOSITORY**.
| GITHUB_REPOSITORY | GITHUB_REPOSITORY_NAME_PART |
| ----------------- | --------------------------- |
| octocat/Hello-World | Hello-World |
| rlespinasse/Hello-World.go | Hello-World.go |
| AnotherPerson/SomeRepository | SomeRepository |
---
## Slug Variables
Slug variables apply the [SLUG transformation](../explanation/slug-transformation-rules.md#slug-transformation): lowercase, replace special characters with `-`, preserve `.` and `_`, truncate to max length.
### GITHUB_REPOSITORY_SLUG
Slug of **GITHUB_REPOSITORY** -- the owner and repository name.
| GITHUB_REPOSITORY | GITHUB_REPOSITORY_SLUG |
| ----------------- | ---------------------- |
| octocat/Hello-World | octocat-hello-world |
| rlespinasse/Hello-World.go | rlespinasse-hello-world.go |
| AnotherPerson/SomeRepository | anotherperson-somerepository |
### GITHUB_REPOSITORY_OWNER_PART_SLUG
Slug of **GITHUB_REPOSITORY_OWNER_PART** -- the owner name.
| GITHUB_REPOSITORY_OWNER_PART | GITHUB_REPOSITORY_OWNER_PART_SLUG |
| ---------------------------- | --------------------------------- |
| octocat | octocat |
| rlespinasse | rlespinasse |
| AnotherPerson | anotherperson |
### GITHUB_REPOSITORY_NAME_PART_SLUG
Slug of **GITHUB_REPOSITORY_NAME_PART** -- the repository name.
| GITHUB_REPOSITORY_NAME_PART | GITHUB_REPOSITORY_NAME_PART_SLUG |
| --------------------------- | -------------------------------- |
| Hello-World | hello-world |
| Hello-World.go | hello-world.go |
| SomeRepository | somerepository |
### GITHUB_REF_SLUG
Slug of **GITHUB_REF** -- the branch or tag ref that triggered the workflow.
_If neither a branch or tag is available for the event type, the variable will not exist._
| GITHUB_REF | GITHUB_REF_SLUG |
| ---------- | --------------- |
| refs/heads/main | main |
| refs/heads/feat/new_feature | feat-new-feature |
| refs/tags/v1.0.0 | v1.0.0 |
| refs/tags/product@1.0.0-rc.2 | product-1.0.0-rc.2 |
| refs/heads/New_Awesome_Product | new-awesome-product |
### GITHUB_REF_NAME_SLUG
Slug of **GITHUB_REF_NAME** -- the branch or tag name shown on GitHub.
_If neither a branch or tag is available for the event type, the variable will not exist._
| GITHUB_REF_NAME | GITHUB_REF_NAME_SLUG |
| --------------- | -------------------- |
| main | main |
| feat/new_feature | feat-new-feature |
| v1.0.0 | v1.0.0 |
| product@1.0.0-rc.2 | product-1.0.0-rc.2 |
| New_Awesome_Product | new-awesome-product |
| 42/merge | 42-merge |
### GITHUB_HEAD_REF_SLUG
Slug of **GITHUB_HEAD_REF** -- the branch of the head repository.
_Only set for [`pull_request*`][webhooks] events and forked repositories._
| GITHUB_HEAD_REF | GITHUB_HEAD_REF_SLUG |
| --------------- | -------------------- |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
### GITHUB_BASE_REF_SLUG
Slug of **GITHUB_BASE_REF** -- the branch of the base repository.
_Only set for [`pull_request*`][webhooks] events and forked repositories._
| GITHUB_BASE_REF | GITHUB_BASE_REF_SLUG |
| --------------- | -------------------- |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
### GITHUB_EVENT_REF_SLUG
Slug of **github.event.ref** -- the Git reference resource associated to the triggered webhook.
_Only set for [`create` and `delete`][webhooks] events._
| github.event.ref | GITHUB_EVENT_REF_SLUG |
| ---------------- | --------------------- |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
---
## URL-Safe Slug Variables
URL-safe slug variables apply the [SLUG_URL transformation](../explanation/slug-transformation-rules.md#slug_url-transformation): same as SLUG but `.` and `_` are also replaced with `-`.
### GITHUB_REPOSITORY_SLUG_URL
URL-safe slug of **GITHUB_REPOSITORY** -- the owner and repository name.
| GITHUB_REPOSITORY | GITHUB_REPOSITORY_SLUG_URL |
| ----------------- | -------------------------- |
| octocat/Hello-World | octocat-hello-world |
| rlespinasse/Hello-World.go | rlespinasse-hello-world-go |
| AnotherPerson/SomeRepository | anotherperson-somerepository |
### GITHUB_REPOSITORY_OWNER_PART_SLUG_URL
URL-safe slug of **GITHUB_REPOSITORY_OWNER_PART** -- the owner name.
| GITHUB_REPOSITORY_OWNER_PART | GITHUB_REPOSITORY_OWNER_PART_SLUG_URL |
| ---------------------------- | ------------------------------------- |
| octocat | octocat |
| rlespinasse | rlespinasse |
| AnotherPerson | anotherperson |
### GITHUB_REPOSITORY_NAME_PART_SLUG_URL
URL-safe slug of **GITHUB_REPOSITORY_NAME_PART** -- the repository name.
| GITHUB_REPOSITORY_NAME_PART | GITHUB_REPOSITORY_NAME_PART_SLUG_URL |
| --------------------------- | ------------------------------------ |
| Hello-World | hello-world |
| Hello-World.go | hello-world-go |
| SomeRepository | somerepository |
### GITHUB_REF_SLUG_URL
URL-safe slug of **GITHUB_REF** -- the branch or tag ref that triggered the workflow.
_If neither a branch or tag is available for the event type, the variable will not exist._
| GITHUB_REF | GITHUB_REF_SLUG_URL |
| ---------- | ------------------- |
| refs/heads/main | main |
| refs/heads/feat/new_feature | feat-new-feature |
| refs/tags/v1.0.0 | v1-0-0 |
| refs/pull/42/merge | 42-merge |
| refs/tags/product@1.0.0-rc.2 | product-1-0-0-rc-2 |
| refs/heads/New_Awesome_Product | new-awesome-product |
### GITHUB_REF_NAME_SLUG_URL
URL-safe slug of **GITHUB_REF_NAME** -- the branch or tag name shown on GitHub.
_If neither a branch or tag is available for the event type, the variable will not exist._
| GITHUB_REF_NAME | GITHUB_REF_NAME_SLUG_URL |
| --------------- | ------------------------ |
| main | main |
| feat/new_feature | feat-new-feature |
| v1.0.0 | v1-0-0 |
| 42/merge | 42-merge |
| product@1.0.0-rc.2 | product-1-0-0-rc-2 |
| New_Awesome_Product | new-awesome-product |
### GITHUB_HEAD_REF_SLUG_URL
URL-safe slug of **GITHUB_HEAD_REF** -- the branch of the head repository.
_Only set for [`pull_request*`][webhooks] events and forked repositories._
| GITHUB_HEAD_REF | GITHUB_HEAD_REF_SLUG_URL |
| --------------- | ------------------------ |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
### GITHUB_BASE_REF_SLUG_URL
URL-safe slug of **GITHUB_BASE_REF** -- the branch of the base repository.
_Only set for [`pull_request*`][webhooks] events and forked repositories._
| GITHUB_BASE_REF | GITHUB_BASE_REF_SLUG_URL |
| --------------- | ------------------------ |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
### GITHUB_EVENT_REF_SLUG_URL
URL-safe slug of **github.event.ref** -- the Git reference resource associated to the triggered webhook.
_Only set for [`create` and `delete`][webhooks] events._
| github.event.ref | GITHUB_EVENT_REF_SLUG_URL |
| ---------------- | ------------------------- |
| main | main |
| feat/new_feature | feat-new-feature |
| New_Awesome_Product | new-awesome-product |
---
## Short Variables
### GITHUB_SHA_SHORT
Shortened **GITHUB_SHA** -- the commit SHA that triggered the workflow.
| GITHUB_SHA | GITHUB_SHA_SHORT |
| ---------- | ---------------- |
| ffac537e6cbbf934b08745a378932722df287a53 | ffac537e |
### GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT
Shortened value of `github.event.pull_request.head.sha` -- the last commit on the pull request that triggered the workflow.
| github.event.pull_request.head.sha | GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT |
| ---------------------------------- | ---------------------------------------- |
| ffac537e6cbbf934b08745a378932722df287a53 | ffac537e |
---
## Case-Sensitive Variants
All slug and slug-url variables have a `_CS` suffix variant that preserves the original casing. The `_CS` variant applies the same transformation but skips the lowercase step.
| Standard | Case-Sensitive |
| -------- | -------------- |
| `GITHUB_REPOSITORY_SLUG` | `GITHUB_REPOSITORY_SLUG_CS` |
| `GITHUB_REPOSITORY_SLUG_URL` | `GITHUB_REPOSITORY_SLUG_URL_CS` |
| `GITHUB_REF_SLUG` | `GITHUB_REF_SLUG_CS` |
| `GITHUB_REF_SLUG_URL` | `GITHUB_REF_SLUG_URL_CS` |
| _(and so on for all slug/slug-url variables)_ | |
Example:
| Input | SLUG | SLUG_CS |
| ----- | ---- | ------- |
| `refs/heads/New_Awesome_Product` | `new-awesome-product` | `New-Awesome-Product` |
---
## Variable Availability by Event
Not all variables are set for every event type. See [GitHub variables by event](github-variables.md) for the full matrix.
[webhooks]: https://docs.github.com/en/developers/webhooks-and-events/webhook-events-and-payloads

3
docs/short-variables.md Normal file
View File

@@ -0,0 +1,3 @@
# Short Variables
This page has moved to [reference/variables.md](reference/variables.md#short-variables).

View File

@@ -0,0 +1,3 @@
# Slug URL Variables
This page has moved to [reference/variables.md](reference/variables.md#url-safe-slug-variables).

3
docs/slug-variables.md Normal file
View File

@@ -0,0 +1,3 @@
# Slug Variables
This page has moved to [reference/variables.md](reference/variables.md#slug-variables).

34
examples/linux-usage.yml Normal file
View File

@@ -0,0 +1,34 @@
name: Linux usage
on: push
jobs:
usage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- name: Output
run: |
echo "Partial variables"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART }}"
echo "Slug variables"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG }}"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG }}"
echo " ref : ${{ env.GITHUB_REF_SLUG }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG }}"
echo "Slug URL variables"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL }}"
echo " ref : ${{ env.GITHUB_REF_SLUG_URL }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG_URL }}"
echo "Short SHA variables"
echo " sha : ${{ env.GITHUB_SHA_SHORT }}"
echo " pull request sha : ${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}"

34
examples/macos-usage.yml Normal file
View File

@@ -0,0 +1,34 @@
name: MacOS usage
on: push
jobs:
usage:
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- name: Output
run: |
echo "Partial variables"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART }}"
echo "Slug variables"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG }}"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG }}"
echo " ref : ${{ env.GITHUB_REF_SLUG }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG }}"
echo "Slug URL variables"
echo " repository : ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
echo " repository owner : ${{ env.GITHUB_REPOSITORY_OWNER_PART_SLUG_URL }}"
echo " repository name : ${{ env.GITHUB_REPOSITORY_NAME_PART_SLUG_URL }}"
echo " ref : ${{ env.GITHUB_REF_SLUG_URL }}"
echo " head ref : ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
echo " base ref : ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
echo " event ref : ${{ env.GITHUB_EVENT_REF_SLUG_URL }}"
echo "Short SHA variables"
echo " sha : ${{ env.GITHUB_SHA_SHORT }}"
echo " pull request sha : ${{ env.GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT }}"

20
examples/url-use.yml Normal file
View File

@@ -0,0 +1,20 @@
name: URL use
on: push
jobs:
as_subdomain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- run: |
./deploy-application.sh --url "https://${{ env.GITHUB_REF_SLUG_URL }}.staging.app.example.com"
as_resource_path:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- run: |
./deploy-application.sh --url "https://staging.app.example.com/${{ env.GITHUB_REF_SLUG_URL }}"

View File

@@ -0,0 +1,34 @@
name: Windows usage
on: push
jobs:
usage:
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
- uses: rlespinasse/github-slug-action@v5
- name: Output
run: |
echo "Partial variables"
echo " repository owner : $env:GITHUB_REPOSITORY_OWNER_PART"
echo " repository name : $env:GITHUB_REPOSITORY_NAME_PART"
echo "Slug variables"
echo " repository : $env:GITHUB_REPOSITORY_SLUG"
echo " repository owner : $env:GITHUB_REPOSITORY_OWNER_PART_SLUG"
echo " repository name : $env:GITHUB_REPOSITORY_NAME_PART_SLUG"
echo " ref : $env:GITHUB_REF_SLUG"
echo " head ref : $env:GITHUB_HEAD_REF_SLUG"
echo " base ref : $env:GITHUB_BASE_REF_SLUG"
echo " event ref : $env:GITHUB_EVENT_REF_SLUG"
echo "Slug URL variables"
echo " repository : $env:GITHUB_REPOSITORY_SLUG_URL"
echo " repository owner : $env:GITHUB_REPOSITORY_OWNER_PART_SLUG_URL"
echo " repository name : $env:GITHUB_REPOSITORY_NAME_PART_SLUG_URL"
echo " ref : $env:GITHUB_REF_SLUG_URL"
echo " head ref : $env:GITHUB_HEAD_REF_SLUG_URL"
echo " base ref : $env:GITHUB_BASE_REF_SLUG_URL"
echo " event ref : $env:GITHUB_EVENT_REF_SLUG_URL"
echo "Short SHA variables"
echo " sha : $env:GITHUB_SHA_SHORT"
echo " pull request sha : $env:GITHUB_EVENT_PULL_REQUEST_HEAD_SHA_SHORT"

View File

@@ -1,11 +0,0 @@
module.exports = {
clearMocks: true,
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
testRunner: 'jest-circus/runner',
transform: {
'^.+\\.ts$': 'ts-jest'
},
verbose: true
}

13019
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +0,0 @@
{
"name": "github-slug-action",
"version": "0.0.0",
"license": "MIT",
"private": true,
"description": "Github slug action",
"main": "lib/main.js",
"scripts": {
"release": "semantic-release",
"build": "tsc",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"lint": "eslint src/**/*.ts",
"package": "ncc build --source-map",
"test": "jest",
"all": "npm run build && npm run format && npm run lint && npm run package && npm test"
},
"repository": {
"type": "git",
"url": "http://github.com/rlespinasse/github-slug-action.git"
},
"keywords": [
"actions",
"node",
"setup"
],
"author": "rlespinasse",
"dependencies": {
"@actions/core": "^1.2.6"
},
"devDependencies": {
"@semantic-release/changelog": "5.0.1",
"@semantic-release/git": "9.0.0",
"@types/jest": "^26.0.10",
"@types/node": "^14.6.0",
"@typescript-eslint/parser": "^3.9.1",
"@vercel/ncc": "^0.23.0",
"eslint": "^7.5.0",
"eslint-plugin-github": "^4.1.1",
"eslint-plugin-jest": "^23.20.0",
"jest": "^26.4.2",
"jest-circus": "^26.4.1",
"js-yaml": "^3.14.0",
"prettier": "2.0.5",
"semantic-release": "17.0.7",
"ts-jest": "^26.3.0",
"typescript": "^3.9.7"
},
"release": {
"tagFormat": "${version}",
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/git",
"@semantic-release/github"
],
"branches": [
"v1.1.x",
"v2.x"
]
}
}

38
preflight.sh Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
if [ -z "${INPUT_SLUG_MAXLENGTH}" ]; then
echo "::error ::slug-maxlength cannot be empty"
exit 1
elif [ "${INPUT_SLUG_MAXLENGTH}" != "nolimit" ] && [ ! "${INPUT_SLUG_MAXLENGTH}" -eq "${INPUT_SLUG_MAXLENGTH}" ] 2>/dev/null; then
echo "::error ::slug-maxlength must be a number or equals to 'nolimit'"
exit 1
fi
if [ ! "${INPUT_SHORT_LENGTH}" -eq "${INPUT_SHORT_LENGTH}" ] 2>/dev/null; then
echo "::error ::short-length must be a number"
exit 1
fi
echo "::debug ::Control preflight short-length setup"
PREFLIGHT_SHORT_LENGTH=""
if [ -n "${INPUT_SHORT_LENGTH}" ]; then
PREFLIGHT_SHORT_LENGTH="${INPUT_SHORT_LENGTH}"
echo "::debug ::Use input value: $PREFLIGHT_SHORT_LENGTH"
elif [ "$(git rev-parse --is-inside-work-tree)" == "true" ]; then
echo "::debug ::The action run inside a git repository, short-length can be empty"
else
echo "::debug ::The action run outside a git repository, need to set short-length"
PREFLIGHT_SHORT_LENGTH="$(git config --get core.abbrev)"
if [ -n "${PREFLIGHT_SHORT_LENGTH}" ]; then
echo "::debug ::Git Configuration 'core.abbrev' is set, using it as short-length"
else
PREFLIGHT_SHORT_LENGTH="7"
echo "::debug ::Using fallback value for short-length"
fi
fi
echo "::debug ::Set PREFLIGHT_SHORT_LENGTH=$PREFLIGHT_SHORT_LENGTH"
if [ -f "$GITHUB_OUTPUT" ]; then
echo "PREFLIGHT_SHORT_LENGTH=${PREFLIGHT_SHORT_LENGTH}" >> "$GITHUB_OUTPUT"
else
echo "::set-output name=PREFLIGHT_SHORT_LENGTH::${PREFLIGHT_SHORT_LENGTH}"
fi

View File

@@ -1,97 +0,0 @@
import * as core from '@actions/core'
import {slugref, slug, slugurl, slugurlref, shortsha} from './slug'
/**
* Inputs environments variables keys from Github actions job
* see https://docs.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
*/
const GITHUB_REPOSITORY = 'GITHUB_REPOSITORY'
const GITHUB_REF = 'GITHUB_REF'
const GITHUB_HEAD_REF = 'GITHUB_HEAD_REF'
const GITHUB_BASE_REF = 'GITHUB_BASE_REF'
const GITHUB_SHA = 'GITHUB_SHA'
const GITHUB_EVENT_PATH = 'GITHUB_EVENT_PATH'
/**
* Slugged outputs environments variables keys
*/
const GITHUB_REPOSITORY_SLUG = 'GITHUB_REPOSITORY_SLUG'
const GITHUB_REPOSITORY_SLUG_URL = 'GITHUB_REPOSITORY_SLUG_URL'
const GITHUB_REF_SLUG = 'GITHUB_REF_SLUG'
const GITHUB_HEAD_REF_SLUG = 'GITHUB_HEAD_REF_SLUG'
const GITHUB_BASE_REF_SLUG = 'GITHUB_BASE_REF_SLUG'
const GITHUB_REF_SLUG_URL = 'GITHUB_REF_SLUG_URL'
const GITHUB_HEAD_REF_SLUG_URL = 'GITHUB_HEAD_REF_SLUG_URL'
const GITHUB_BASE_REF_SLUG_URL = 'GITHUB_BASE_REF_SLUG_URL'
const GITHUB_SHA_SHORT = 'GITHUB_SHA_SHORT'
const GITHUB_EVENT_REF_SLUG = 'GITHUB_EVENT_REF_SLUG'
const GITHUB_EVENT_REF_SLUG_URL = 'GITHUB_EVENT_REF_SLUG_URL'
async function run(): Promise<void> {
try {
const eventPath = process.env[GITHUB_EVENT_PATH]
if (eventPath) {
const eventData = await import(eventPath)
if (eventData.hasOwnProperty('ref')) {
core.exportVariable(GITHUB_EVENT_REF_SLUG, slugref(eventData.ref))
core.exportVariable(
GITHUB_EVENT_REF_SLUG_URL,
slugurlref(eventData.ref)
)
}
}
exportSlug(GITHUB_REPOSITORY, GITHUB_REPOSITORY_SLUG)
exportSlugUrl(GITHUB_REPOSITORY, GITHUB_REPOSITORY_SLUG_URL)
exportSlugRef(GITHUB_REF, GITHUB_REF_SLUG)
exportSlugRef(GITHUB_HEAD_REF, GITHUB_HEAD_REF_SLUG)
exportSlugRef(GITHUB_BASE_REF, GITHUB_BASE_REF_SLUG)
exportSlugUrlRef(GITHUB_REF, GITHUB_REF_SLUG_URL)
exportSlugUrlRef(GITHUB_HEAD_REF, GITHUB_HEAD_REF_SLUG_URL)
exportSlugUrlRef(GITHUB_BASE_REF, GITHUB_BASE_REF_SLUG_URL)
exportShortSha(GITHUB_SHA, GITHUB_SHA_SHORT)
} catch (error) {
core.setFailed(error.message)
}
}
function exportSlug(inputKey: string, outputKey: string): void {
const envVar = process.env[inputKey]
if (envVar) {
core.exportVariable(outputKey, slug(envVar))
}
}
function exportSlugRef(inputKey: string, outputKey: string): void {
const envVar = process.env[inputKey]
if (envVar) {
core.exportVariable(outputKey, slugref(envVar))
}
}
function exportSlugUrl(inputKey: string, outputKey: string): void {
const envVar = process.env[inputKey]
if (envVar) {
core.exportVariable(outputKey, slugurl(envVar))
}
}
function exportSlugUrlRef(inputKey: string, outputKey: string): void {
const envVar = process.env[inputKey]
if (envVar) {
core.exportVariable(outputKey, slugurlref(envVar))
}
}
function exportShortSha(inputKey: string, outputKey: string): void {
const envVar = process.env[inputKey]
if (envVar) {
core.exportVariable(outputKey, shortsha(envVar))
}
}
run()

View File

@@ -1,79 +0,0 @@
const MAX_SLUG_STRING_SIZE = 63
const SHORT_SHA_SIZE = 8
/**
* slug will take envVar and then :
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`, and `.`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
export function slug(envVar: string): string {
return trailHyphen(
replaceAnyNonAlphanumericCaracter(envVar.toLowerCase())
).substring(0, MAX_SLUG_STRING_SIZE)
}
/**
* slug will take envVar and then :
* - remove refs/(heads|tags)/
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`, and `.`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
export function slugref(envVar: string): string {
return slug(removeRef(envVar.toLowerCase()))
}
/**
* slug will take envVar and then :
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
export function slugurl(envVar: string): string {
return slug(replaceAnyDotToHyphen(envVar))
}
/**
* slug will take envVar and then :
* - remove refs/(heads|tags)/
* - put the variable content in lower case
* - replace any character by `-` except `0-9`, `a-z`
* - remove leading and trailing `-` character
* - limit the string size to 63 characters
* @param envVar to be slugged
*/
export function slugurlref(envVar: string): string {
return slugurl(slugref(envVar))
}
/**
* slug will take envVar and then :
* - limit the string size to 8 characters
* @param envVar to be slugged
*/
export function shortsha(envVar: string): string {
return envVar.substring(0, SHORT_SHA_SIZE)
}
function trailHyphen(envVar: string): string {
return envVar.replace(RegExp('^-*', 'g'), '').replace(RegExp('-*$', 'g'), '')
}
function replaceAnyNonAlphanumericCaracter(envVar: string): string {
return envVar.replace(RegExp('[^a-z0-9.]', 'g'), '-')
}
function replaceAnyDotToHyphen(envVar: string): string {
return envVar.replace(RegExp('[.]', 'g'), '-')
}
function removeRef(envVar: string): string {
return envVar.replace(RegExp('^refs/(heads|tags)/'), '')
}

View File

@@ -1,12 +0,0 @@
{
"compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"outDir": "./lib", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
},
"exclude": ["node_modules", "**/*.test.ts"]
}