Compare commits

...

1171 Commits

Author SHA1 Message Date
hurl-bot ed92031d87
Update crates 2025-12-17 03:27:02 +00:00
hurl-bot 00f9b08f98
Update actions 2025-12-15 04:19:20 +00:00
Jean-Christophe Amiel 8570167037
Update CHANGELOG. 2025-12-14 17:50:54 +01:00
Jean-Christophe Amiel 8894fcabc0
Use string slice instaed of owned string in SSL certificate attributes. 2025-12-14 16:55:50 +01:00
Jean-Christophe Amiel d7d7fbf917
Expose subejct alt name certificate getter. 2025-12-14 13:07:41 +01:00
Jean-Christophe Amiel d7cd04f5af
Expose serial number certificate getter. 2025-12-14 13:06:07 +01:00
Jean-Christophe Amiel 7067201976
Make serial number certificate optional. 2025-12-14 13:03:49 +01:00
Jean-Christophe Amiel 25fade1fad
Expose expire date certificate getter. 2025-12-14 12:51:45 +01:00
Jean-Christophe Amiel be3f658fbd
Make expire date certificate optional. 2025-12-14 12:50:27 +01:00
Jean-Christophe Amiel 802ef42ab5
Expose start date certificate getter. 2025-12-14 12:45:24 +01:00
Jean-Christophe Amiel c5f866738e
Make start date certificate optional. 2025-12-14 12:41:35 +01:00
Jean-Christophe Amiel 11c5829b6b
Expose issuer certificate getter. 2025-12-14 12:28:18 +01:00
Jean-Christophe Amiel 00cdaad3e2
Make issuer certificate optional. 2025-12-14 12:26:46 +01:00
Jean-Christophe Amiel 10e56ff441
Expose subject certificate getter. 2025-12-14 12:00:28 +01:00
Jean-Christophe Amiel cd3534e411
Make subject certificate optional. 2025-12-14 11:51:27 +01:00
Jean-Christophe Amiel 28d3544269
Patch flaky test with retry, on HTTP/3 with google.com. 2025-12-12 13:23:17 +01:00
Fabrice Reix e00f6bc34e
Refacto JSONPath literal parsing 2025-12-12 07:24:09 +00:00
hurl-bot f6d8c88969
Update crates 2025-12-12 06:52:45 +00:00
Rajiv Aaron Manglani c6e73e0892
Add Subject Alt Name (SAN) attribute for certificate assertions.
Co-authored-by: Rajiv Aaron Manglani <rajiv@alum.mit.edu>
2025-12-11 17:29:52 +01:00
Jean-Christophe Amiel 27d529b6c2
Fix cookie integration test. 2025-12-11 13:28:35 +01:00
Jean-Christophe Amiel c5b77cbedd
Update Python dev dependencies. 2025-12-10 06:41:21 +00:00
hurl-bot 556ea3c813
Update crates 2025-12-10 03:28:17 +00:00
Fabrice Reix 6b1ff56bc1
Add JSONPath functions 2025-12-09 09:23:49 +01:00
hurl-bot ea87045f7c
Update actions 2025-12-08 04:12:43 +00:00
Jean-Christophe Amiel e620c2d415
Update CHANGELOG 2025-12-05 17:19:04 +01:00
Jean-Christophe Amiel 9b7b150d6b
Fix truncating existing output file when response is tiny 2025-12-05 16:10:54 +01:00
Jean-Christophe Amiel 2480304699
Update python dev dependencies. 2025-12-03 14:37:01 +01:00
hurl-bot 7a1ea6c68a
Update crates 2025-12-03 03:24:53 +00:00
hurl-bot 6b4139a490
Update crates 2025-12-02 03:25:54 +00:00
Jean-Christophe Amiel 647cf76e25
Update Hurl sample with 7.1.0 version. 2025-12-01 13:54:30 +01:00
hurl-bot 29f34e87e8
Update crates 2025-12-01 09:40:37 +00:00
Filipe PINTO 08cc799f2c
Disable integration tests on test.yml workflow for Windows 2025-12-01 09:29:12 +01:00
hurl-bot 323535e4cb
Update actions 2025-12-01 04:23:28 +00:00
Fabrice Reix 37bff429c7
Add JSONPath number 2025-11-30 14:55:54 +01:00
Jean-Christophe Amiel c509a0504a
Use `std::process::ExitCode` in main instead of `std::process:exit` to fix valgrind errors.
See <https://github.com/jfrimmel/cargo-valgrind/issues/131>
2025-11-30 13:54:32 +01:00
hurl-bot f540e2e735
Update crates 2025-11-30 03:29:15 +00:00
Fabrice Reix f3a09ebf49
Parse spaces in JSONPath logical expressions 2025-11-29 08:28:13 +00:00
Fabrice Reix 26323ecac0
Parse spaces between JSONPath selectors 2025-11-29 08:28:12 +00:00
hurl-bot 2d1a37d8e8
Update crates 2025-11-29 03:21:21 +00:00
hurl-bot 45f7e025a7
Update crates 2025-11-28 12:19:49 +00:00
Filipe PINTO 49a4c7fd96
Fix Ubuntu install doc 2025-11-28 07:42:04 +00:00
Jean-Christophe Amiel 0aef313fff
Publish npm 7.1.0 package. 2025-11-27 21:09:06 +00:00
hurl-bot 9817a273b5
Update crates 2025-11-27 03:21:16 +00:00
Fabrice Reix a28bc8c091
Ship whitespace in JSONPath comparison 2025-11-25 20:24:49 +01:00
Fabrice Reix 6b8d2f475b
Ignore Test in JSONPath CTS 2025-11-25 20:24:49 +01:00
hurl-bot 19deca6137
Update actions 2025-11-24 04:14:07 +00:00
Fabrice Reix 6fed3975b3
Ignore non-standard tests from JSONPath CTS 2025-11-23 20:27:25 +00:00
Filipe PINTO e81eecdc0f
Reorg releasing steps in RELEASING.md 2025-11-22 20:40:11 +00:00
Filipe PINTO 6df5fc13ff
Fix Ubuntu minimum version for ppa installation 2025-11-22 19:47:22 +01:00
Filipe PINTO adb50a9a2f
Fix tarball in ppa contrib 2025-11-22 18:57:30 +01:00
Filipe PINTO 8080545d5f
Execute update-action workflow once a week 2025-11-22 17:05:13 +01:00
Filipe PINTO 9c66dc12b4
Reduce MacOS runners usage by running integration tests only on package workflow 2025-11-22 17:03:59 +01:00
Filipe PINTO 80f187d3ee
Auto cancel redundant workflows 2025-11-22 16:59:13 +01:00
hurl-bot 2ff0257dd4
Update hurl version to 7.2.0-SNAPSHOT 2025-11-20 12:45:42 +00:00
hurl-bot 7779842490
Create 7.1.0 release 2025-11-18 12:44:56 +00:00
Jean-Christophe Amiel b9e0cd0f33
Fix CHANGELOG. 2025-11-18 13:42:13 +01:00
Jean-Christophe Amiel 0e5d5eefc7
Update changelog. 2025-11-18 13:34:47 +01:00
hurl-bot 46ba79561a
Update actions 2025-11-18 09:26:29 +00:00
Fabrice Reix c66cd2f11d
Update Rust to 1.91.1 2025-11-18 09:15:11 +01:00
Jean-Christophe Amiel 2accfd67bb
Rewrite imports to group related imports with super::. 2025-11-17 09:34:13 +01:00
Jean-Christophe Amiel 105f7f4451
Add function docs. 2025-11-17 08:51:10 +01:00
Jean-Christophe Amiel d6e3fa033b
Delete unused code. 2025-11-17 08:45:36 +01:00
Jean-Christophe Amiel 67d5fa8253
Fix curl debug command with dot-prefixed cookie domain 2025-11-16 17:59:44 +01:00
hurl-bot 0d32708daf
Update crates
Co-authored-by: jcamiel <jeanchristophe.amiel@orange.com>
2025-11-16 15:56:46 +00:00
Fabrice Reix 5c9ca69fc2
Add JSONPath not expr 2025-11-16 09:01:55 +01:00
Fabrice Reix 444feef736
Add JSONPath or expression 2025-11-15 20:21:20 +01:00
Fabrice Reix 919e9a6f2b
Add JSONPath and expression 2025-11-15 09:31:19 +01:00
hurl-bot 222b5795af
Update crates 2025-11-15 03:18:40 +00:00
Jean-Christophe Amiel 2ed1e59058
Update changelog. 2025-11-14 17:35:25 +01:00
Jean-Christophe Amiel b898c8ac14
Fix parsing cookie attributes. 2025-11-14 16:19:17 +01:00
Jean-Christophe Amiel e3dbe03d11
Support ascii_whitespaces separator in importing cookie. 2025-11-14 11:47:24 +01:00
Jean-Christophe Amiel 31bf0a699d
Introduce a cookie store to manage cookies of an exchange. 2025-11-14 11:14:19 +01:00
Fabrice Reix ea2cc14201
Plug comparison-expr into logical-expr 2025-11-14 09:06:07 +01:00
Fabrice Reix 33bc4757b7
Refacto JSONPath absolute/relative query 2025-11-13 08:46:45 +01:00
hurl-bot 7795121fd1
Update crates 2025-11-13 03:22:26 +00:00
Fabrice Reix 0c82a77b83
Make the JSONPath Compliance Test Suite blocking 2025-11-12 14:51:47 +01:00
Fabrice Reix 233bb9c94f
Refacto JSONPath expr 2025-11-12 13:37:00 +01:00
hurl-bot 12fd83bb52
Update crates 2025-11-12 03:21:13 +00:00
Jean-Christophe Amiel 7b1e93c116
Use explicit method names to import/export from Netscape cookie file format. 2025-11-11 14:15:29 +01:00
Jean-Christophe Amiel 9b184cd33c
Move Cookie struct in cookie.rs 2025-11-11 14:02:22 +01:00
Jean-Christophe Amiel d6e3e6bd0e
Move RequestCookie struct in request_cookie.rs file. 2025-11-11 13:59:21 +01:00
Jean-Christophe Amiel 2dfe800614
Move Param struct in param.rs file. 2025-11-11 13:52:50 +01:00
Jean-Christophe Amiel cb32b30e0c
Rewrite imports to group related imports with super::. 2025-11-11 13:37:27 +01:00
Jean-Christophe Amiel fd8ae6c510
Update CHANGELOG 2025-11-10 17:22:39 +01:00
Jean-Christophe Amiel 39986a9be2
Some refacto on RunContext to better manage color/no_color. 2025-11-10 16:00:25 +00:00
Jean-Christophe Amiel 1e96255d2c
Accept more path names when appending HTML reports 2025-11-10 14:26:12 +01:00
Jean-Christophe Amiel 8db29b7410
Update docs. 2025-11-10 12:36:14 +00:00
Jean-Christophe Amiel b7becf1faa
Update CHANGELOG. 2025-11-10 11:04:29 +01:00
hurl-bot 0ee3cb4830
Update crates 2025-11-10 03:25:52 +00:00
Jean-Christophe Amiel 2a070fad3e
Add integration test for adding secret with env variables. 2025-11-09 13:59:02 +01:00
Jean-Christophe Amiel 619b35222f
Support adding secret with HURL_SECRET_foo env variable. 2025-11-09 12:01:51 +01:00
hurl-bot 6ecd314036
Update crates 2025-11-09 03:21:10 +00:00
hurl-bot 6128ecd275
Update crates 2025-11-08 03:16:20 +00:00
hurl-bot 40ad4c4ae3
Update crates 2025-11-07 19:21:41 +00:00
Fabrice Reix 91206f79e5
Refacto parsing JSONPath segment spec to match spec 2025-11-07 18:46:05 +01:00
Fabrice Reix 0f074ce561
Fix unresolved link 2025-11-07 11:29:07 +01:00
Fabrice Reix c5582387d7
Update Rust to 1.91.0 2025-11-07 08:58:26 +01:00
Jean-Christophe Amiel 58138140b0
Fix typos. 2025-11-06 12:58:36 +00:00
hurl-bot 2964d71af2
Update crates 2025-11-06 03:22:42 +00:00
Jean-Christophe Amiel 7ae81bc339
Implements isObject predicate. 2025-11-05 17:47:49 +01:00
Jean-Christophe Amiel ca482dc36f
Update grammar with isObject predicate. 2025-11-05 17:25:28 +01:00
Jean-Christophe Amiel a02339b121
Implements isList predicate. 2025-11-05 08:31:04 +01:00
Jean-Christophe Amiel be0b93cf44
Update grammar with isList predicate. 2025-11-04 18:11:13 +01:00
Jean-Christophe Amiel cacc94b53d
Add Caddy Hurl tests. 2025-11-04 17:24:18 +01:00
Jean-Christophe Amiel 3d91fb70cd
Add Hurl tutorial regression tests. 2025-11-04 17:24:17 +01:00
Jean-Christophe Amiel 4c080fc340
Add Python infra regression tests. 2025-11-04 17:24:16 +01:00
Jean-Christophe Amiel 0846e4c0a8
Update CHANGELOG. 2025-11-03 22:25:00 +01:00
Jean-Christophe Amiel 33a1783487
Fix implicit "Content-Type" headers when following redirections. 2025-11-03 19:24:02 +01:00
Fabrice Reix 92df579744
Fix JSONPath slice selector 2025-11-03 08:14:27 +01:00
hurl-bot ee7eda436e
Update crates 2025-11-02 03:22:25 +00:00
hurl-bot 1d571c0da4
Update crates 2025-11-01 03:20:29 +00:00
hurl-bot 1ddd00c432
Update crates 2025-10-31 03:20:40 +00:00
hurl-bot 0086f8585a
Update crates 2025-10-30 03:20:26 +00:00
hurl-bot 707baa976a
Update crates 2025-10-29 03:23:04 +00:00
hurl-bot 51ec81e1cd
Update crates 2025-10-28 03:18:40 +00:00
hurl-bot 7b95fd4acf
Update actions 2025-10-27 04:05:58 +00:00
Jean-Christophe Amiel 6cf11dbf23
Update CHANGELOG. 2025-10-26 22:10:08 +01:00
Jean-Christophe Amiel 4402afceaf
Add early returns for empty entries. 2025-10-26 20:42:49 +01:00
Jean-Christophe Amiel acd85a5876
Add retry count in the progress bar (only if retry >= 1) 2025-10-26 20:42:49 +01:00
hurl-bot bf91b7ef5b
Update crates 2025-10-26 03:19:20 +00:00
hurl-bot 901d58a5c1
Update crates 2025-10-25 03:16:12 +00:00
Jean-Christophe Amiel 59e025abb3
Use Count type in job_queue. 2025-10-24 21:07:39 +02:00
hurl-bot 56176f83e4
Update crates 2025-10-24 03:14:46 +00:00
hurl-bot fce829ea0f
Update crates 2025-10-23 03:16:39 +00:00
Fabrice Reix d9c4bef6a8
Increase number of testcases to be run 2025-10-22 13:34:05 +02:00
Fabrice Reix a375243fd1
Parse unicode in member name shorthand 2025-10-22 13:34:05 +02:00
Fabrice Reix 597e47dcc9
Do not accept trailing spaces in jsonpath queries 2025-10-22 13:34:04 +02:00
hurl-bot 1ded8d1fe0
Update crates 2025-10-22 03:20:22 +00:00
hurl-bot 94a3ad7350
Update crates 2025-10-21 03:17:43 +00:00
hurl-bot f21deed07f
Update crates 2025-10-20 03:23:08 +00:00
Fabrice Reix 66b7b5b1e6
Add SingularQuery type 2025-10-19 11:18:30 +00:00
Jean-Christophe Amiel 76b4ef8b0c
Reexport old type to not break compatibility. 2025-10-19 09:40:07 +00:00
Jean-Christophe Amiel 0bb5b964cf
Add new type Index for 1-based indices. 2025-10-19 09:40:07 +00:00
Jean-Christophe Amiel 2a8096b507
Rename module hurl_core::typing::Count to hurl_core::types::Count. 2025-10-19 09:40:06 +00:00
hurl-bot c9a642c369
Update crates 2025-10-19 07:11:59 +00:00
Jean-Christophe Amiel 9fbf64be51
Fix the number of threads for waitress. 2025-10-19 06:42:52 +00:00
Ashish Reddy 443fd9d022
Enhance logging for retry 2025-10-18 23:21:08 +00:00
Filipe PINTO 211696485d
Use Macos-15 github runners 2025-10-19 00:58:04 +02:00
hurl-bot 5d65e75f5e
Update crates 2025-10-16 03:16:38 +00:00
hurl-bot de7f2a0f4d
Update crates 2025-10-15 03:16:44 +00:00
hurl-bot 4bc3ef432b
Update crates 2025-10-14 03:14:46 +00:00
hurl-bot 34d11ae27b
Update crates 2025-10-13 03:19:33 +00:00
hurl-bot 0ef7184790
Update crates 2025-10-11 03:09:32 +00:00
Ashish Reddy 2346942e7a
Update docs to mention supported time units 2025-10-10 12:21:54 +00:00
Ashish Reddy d527b66aaf
Update intergation tests for hulfmt to include all time units 2025-10-10 12:21:54 +00:00
Ashish Reddy 0a06cb7cee
Add support for hour time unit 2025-10-10 12:21:53 +00:00
hurl-bot 743b8128e7
Update crates 2025-10-10 03:14:30 +00:00
Ashish Reddy b2ebdc9483
Enhance --test duration logging 2025-10-08 19:37:19 +05:30
Jean-Christophe Amiel f1cb9f36f6
Update changelog 2025-10-08 09:43:51 +02:00
Filipe PINTO a44816372f
Update PPA contrib with libxml2 build 2025-10-07 17:05:05 +02:00
hurl-bot 433e61dc15
Update crates 2025-10-07 09:01:27 +00:00
Jean-Christophe Amiel b0f564f4bd
Defer set verbose mode on libcurl handle to patch noisy logs from libcurl
See <https://github.com/Orange-OpenSource/hurl/issues/4406>
2025-10-07 09:44:36 +02:00
Jean-Christophe Amiel c750aa1a98
Update running tests doc with performance section. 2025-10-06 09:56:54 +02:00
Jean-Christophe Amiel c420e2f5ce
Use happy path with http/https scheme for URL parsing. 2025-10-05 21:57:28 +02:00
hurl-bot 2f9be6f7ed
Update crates 2025-10-05 03:16:54 +00:00
Jean-Christophe Amiel e8d45da351
Fix filtering of Authorization: and Cookie: headers when following redirection. 2025-10-04 14:36:49 +02:00
Jean-Christophe Amiel a8bd2c8725
Add more logs when stderr mismatch in integration test to diagnose flacky test. 2025-10-04 13:04:35 +02:00
Jean-Christophe Amiel a3fde1f285
Update CHANGELOG. 2025-10-04 06:06:37 +00:00
hurl-bot a970467716
Update crates 2025-10-04 03:07:38 +00:00
Ashish Reddy 8d6ceca06e
Show start date for each request in html report 2025-10-03 19:12:09 +00:00
Ashish Reddy 9f15dd2003
Show full request url on hover in waterfall section in report 2025-10-03 19:12:08 +00:00
Jean-Christophe Amiel 982653e8d3
Add comment on toDate filter implementation. 2025-10-03 18:38:59 +00:00
hurl-bot fb1464e3f7
Update crates 2025-10-03 18:00:27 +00:00
Ashish Reddy 49768b12a3
Update unit tests for toDate filter 2025-10-03 17:47:54 +05:30
Ashish Reddy e3a878c083
Update integration tests for toDate filter 2025-10-03 17:47:03 +05:30
Ashish Reddy 8bc7fe72d0
Add support for toDate filter to parse more types of date-time strings 2025-10-03 16:28:30 +05:30
Jean-Christophe Amiel 1c0677d5f7
Show invisible chars in stderr integration tests. 2025-10-01 17:59:36 +02:00
hurl-bot 18ef75ac1c
Update crates 2025-10-01 03:19:49 +00:00
hurl-bot 8921bc708e
Update crates 2025-09-30 03:12:47 +00:00
hurl-bot 55f0b1c16f
Update actions 2025-09-29 07:59:09 +00:00
Fabrice Reix dbc392c229
Update Let's Encrypt CN 2025-09-29 09:01:33 +02:00
Fabrice Reix 4ed06d565f
Add JSONPath comparison expression 2025-09-29 08:04:18 +02:00
Fabrice Reix 417503d9e1
Update Rust 1.90.0 2025-09-26 11:10:45 +02:00
hurl-bot 4f52291a84
Update crates 2025-09-26 03:13:34 +00:00
Filipe PINTO 2f54903dcd
Fix Windows build 2025-09-25 11:09:41 +00:00
Jean-Christophe Amiel 48e20ecc48
Add tutorial project GitHub URL in doc. 2025-09-24 18:06:34 +02:00
Fabrice Reix 1df5d7e70a
Parse singular segment 2025-09-24 10:58:08 +00:00
Jean-Christophe Amiel fb3a67531a
Update utf8Encode/Decode doc. 2025-09-23 17:59:30 +00:00
Jean-Christophe Amiel e2a7bb0582
Update CHANGELOG 2025-09-23 17:41:41 +02:00
Fabrice Reix 72bab12e1e
Refacto AST in jsonpath module 2025-09-20 14:11:04 +02:00
Fabrice Reix 5da1f00b2c
Handle error at end of file 2025-09-20 09:39:08 +02:00
hurl-bot 610cbf7038
Update crates 2025-09-20 03:10:03 +00:00
Fabrice Reix 1b344ded80
Add JSONPath literal 2025-09-19 08:29:16 +02:00
Fabrice Reix d9a114e1b2
Rename literal primitive parsers
The term 'literal' s already used in the JSONPath spec.
It also includes other types than strings.
2025-09-19 08:04:59 +02:00
hurl-bot 41169ce4b1
Update crates 2025-09-18 20:16:15 +00:00
Martin Stααel 6e6175800e
Spelling correction
Spelling correction
2025-09-18 13:05:09 +10:00
Jean-Christophe Amiel 63d9cfe4eb
Add integration tests for utf8Encode/utf8Decode filters. 2025-09-17 18:53:50 +02:00
Jean-Christophe Amiel 4394eaf87f
Add unit tests on utf8Encode. 2025-09-17 18:23:30 +02:00
Jean-Christophe Amiel b756e18468
Add integration tests for utf8Encode/utf8Decode filters. 2025-09-17 18:23:30 +02:00
Jean-Christophe Amiel 11a36d7b83
Add utf8Encode and utf8Decode filter to grammar. 2025-09-17 18:23:11 +02:00
hurl-bot fcf233e646
Update crates 2025-09-17 03:10:06 +00:00
hurl-bot 5a4994959b
Update crates 2025-09-16 03:11:01 +00:00
Jean-Christophe Amiel f7bb906902
Add comments to next_utf8_char method. 2025-09-15 14:15:05 +00:00
Jean-Christophe Amiel 5d14ebc2b2
Replace unmaintained encoding crate with encoding_rs crate. 2025-09-15 15:17:57 +02:00
Fabrice Reix f91ed7c2cd
Implement JSONPath multiple selectors 2025-09-15 13:11:17 +02:00
Fabrice Reix 9de2099f65
Ignore temporarily error/warnings from latest libcurl 2025-09-14 18:59:46 +02:00
Fabrice Reix 8a7fdbde7d
Implement jsonpath descendant segment 2025-09-12 14:00:54 +02:00
Fabrice Reix 8aab832a4b
Refacto jsonpath eval / segment module 2025-09-12 14:00:47 +02:00
Fabrice Reix 9c8edf7462
Add JSONPath compliance test suite 2025-09-10 13:26:27 +02:00
hurl-bot 613e842aa6
Update crates 2025-09-10 03:09:40 +00:00
Fabrice Reix 54248f842e
Add shorthand notation 2025-09-09 12:57:38 +02:00
hurl-bot a84cb939f2
Update crates 2025-09-09 03:14:46 +00:00
Fabrice Reix f89f08a832
Add filter selector 2025-09-08 20:17:04 +02:00
Fabrice Reix 209583b1bd
Refacto Query/Segment 2025-09-08 20:08:11 +02:00
Fabrice Reix c13ffa75a1
Add jsonpath array slice selector 2025-09-07 10:32:27 +02:00
hurl-bot c8fc37fcc6
Update crates 2025-09-07 03:15:31 +00:00
Fabrice Reix de89346ef5
Refacto test for valid jsonpath expr 2025-09-06 09:59:18 +02:00
Fabrice Reix f01f33d4a7
Add wildcard selector 2025-09-06 09:36:45 +02:00
Fabrice Reix 080674299f
Move selector eval to its own module 2025-09-06 08:59:59 +02:00
hurl-bot e3031c8265
Update crates 2025-09-06 03:09:39 +00:00
Fabrice Reix 8773dfbe13
Add eval module for jsonpath 2025-09-05 13:53:40 +02:00
hurl-bot 035bc86efd
Update actions 2025-09-05 04:00:37 +00:00
Filipe PINTO 58dc348933
Fix package anatomy owner for x64 generic linux package 2025-09-04 11:38:54 +02:00
hurl-bot ba1816da4e
Update crates 2025-09-02 03:17:36 +00:00
hurl-bot 69ee61be77
Update crates 2025-09-01 03:26:28 +00:00
Jean-Christophe Amiel b8e3fb32a9
Add some --pretty integration tests. 2025-08-29 21:19:29 +02:00
Jean-Christophe Amiel 02c8cfbafb
Add --no-pretty command line flag. 2025-08-29 14:47:36 +02:00
Jean-Christophe Amiel 1aefabd749
Prettify JSON response. 2025-08-29 14:34:58 +02:00
Jean-Christophe Amiel 1b23529f4f
Add --pretty noop option. 2025-08-29 13:15:32 +02:00
Jean-Christophe Amiel 0f715f9e73
Add run context to capture the execution environement (env vars, is stdin term etc...) 2025-08-29 09:52:04 +02:00
hurl-bot c5f3ec10c5
Update crates 2025-08-29 03:15:42 +00:00
hurl-bot 9455853d6c
Update crates 2025-08-27 03:16:05 +00:00
hurl-bot c4bd34a4c7
Update crates 2025-08-25 03:22:28 +00:00
hurl-bot 8b7591819a
Update crates 2025-08-24 10:59:10 +00:00
Tyler Brockmeyer 12ca0de857
deprecate `format` for `dateFormat` 2025-08-24 09:42:59 +00:00
hurl-bot ab33df2426
Update crates 2025-08-23 03:16:02 +00:00
hurl-bot 545326c7ed
Update crates 2025-08-22 03:18:29 +00:00
hurl-bot a9cea22d7f
Update crates 2025-08-21 03:18:08 +00:00
hurl-bot 8634deaf41
Update crates 2025-08-20 03:18:33 +00:00
Filipe PINTO b1874a83e2
Fix package anatomy owner for aarch64 generic linux package 2025-08-19 19:14:18 +01:00
hurl-bot 2567f7d451
Update actions 2025-08-19 16:45:07 +00:00
hurl-bot d266955d14
Update crates 2025-08-19 03:19:33 +00:00
hurl-bot 2c93493418
Update crates 2025-08-18 03:29:56 +00:00
hurl-bot 2ff48ae540
Update crates 2025-08-17 03:28:44 +00:00
hurl-bot 900f5a0815
Update crates 2025-08-16 03:22:04 +00:00
hurl-bot 61fa8a19c7
Update crates 2025-08-15 03:26:44 +00:00
Jean-Christophe Amiel 627bcccb57
Desactivate HTTP/3 test on Debian Trixie. 2025-08-13 12:02:28 +02:00
Jean-Christophe Amiel 90c6150ffb
Remove software-properties-common dependencies. 2025-08-13 11:41:59 +02:00
Jean-Christophe Amiel f55326baac
Delete python3-distutils dependencies. 2025-08-13 11:34:21 +02:00
hurl-bot 3e042440c1
Update crates 2025-08-13 03:25:43 +00:00
hurl-bot 8e180a5473
Update crates 2025-08-12 03:23:22 +00:00
Jean-Christophe Amiel e9faa6db9c
Rework parallel module import. 2025-08-11 22:41:40 +02:00
Jean-Christophe Amiel 2e6186674f
Update CHANGELOG 2025-08-11 07:57:16 +00:00
hurl-bot 2ce8280073
Update crates 2025-08-11 03:30:44 +00:00
Mikhail cbbd4ed626
Parse --negotiate option in hurlfmt 2025-08-10 17:35:20 +00:00
Mikhail c2e103dd6b
Parse --ntlm option in hurlfmt 2025-08-10 17:35:19 +00:00
Mikhail 0005ffd841
Parse --user option in hurlfmt 2025-08-10 17:35:18 +00:00
Fabrice Reix a4c8da133b
Add selector parser module 2025-08-10 17:32:56 +02:00
Fabrice Reix 0c8ecfb75e
Add new jsonpath module
It will implement the RFC 9535 spec
2025-08-10 10:46:44 +02:00
hurl-bot f8a11c9efe
Update crates 2025-08-10 03:31:11 +00:00
Jean-Christophe Amiel c4e2d79805
Update CHANGELOG. 2025-08-09 20:57:49 +00:00
Jean-Christophe Amiel a784ac3be7
Small code improvments. 2025-08-09 20:35:06 +00:00
Mikhail 17feef422a
Add --negotiate option per request 2025-08-09 20:09:42 +03:00
Mikhail 149bc5bf66
Add --ntlm option per request 2025-08-09 16:21:15 +00:00
Fabrice Reix ccb129e0b8
Fix clippy warning needless_return 2025-08-09 10:30:13 +00:00
Fabrice Reix 44481aae22
Update Rust to 1.89.0 2025-08-09 10:30:12 +00:00
hurl-bot cf4b31d705
Update crates 2025-08-09 03:25:47 +00:00
hurl-bot 2f04773bdc
Update crates 2025-08-08 03:31:02 +00:00
Jean-Christophe Amiel afecae6c58
Move test_failed/* integration tests in subfolder. 2025-08-07 18:19:33 +02:00
hurl-bot 63b3824fed
Update crates 2025-08-07 03:31:09 +00:00
Mikhail 36ffa76ad4
Support --secrets-file for injecting secrets 2025-08-06 15:23:48 +00:00
Jean-Christophe Amiel 27b4c12c68
Move integration tests in subfolder. 2025-08-06 14:06:17 +02:00
Jean-Christophe Amiel 1086dc7dcb
Move integration tests in subfolders. 2025-08-06 09:45:49 +02:00
hurl-bot 4efd35d980
Update actions 2025-08-06 04:15:53 +00:00
hurl-bot 689a5e2a34
Update crates 2025-08-06 03:31:01 +00:00
Jean-Christophe Amiel 4d0e594fe9
Add `VariablesFile` struct to manage variables file. 2025-08-05 14:17:15 +02:00
hurl-bot 801f32a4cd
Update crates 2025-08-05 03:31:55 +00:00
Jean-Christophe Amiel 321edde504
Move integration tests in subfolders. 2025-08-04 09:01:34 +02:00
Jean-Christophe Amiel da4b1ea312
Move tests_failed/assert* integration test in subfolder. 2025-08-03 17:16:53 +02:00
hurl-bot 378f5034fd
Update crates 2025-08-03 03:34:11 +00:00
Ashish Reddy cdb58f2d2b
Add integration tests for --ntlm option 2025-08-02 15:04:04 +00:00
Filipe PINTO c68f4cc028
Use Hurl instead of curl for features detection on http_version_not_supported test 2025-08-02 14:11:52 +02:00
Jean-Christophe Amiel 695e806827
POC with waitress as WGSI server for integration tests_failed/*. 2025-08-02 06:10:00 +00:00
Jean-Christophe Amiel c6e38fe97b
POC with waitress as WGSI server for integration tests_ok/*. 2025-08-02 06:09:59 +00:00
hurl-bot 6d2e1b7750
Update crates 2025-08-02 03:28:56 +00:00
Jean-Christophe Amiel acd0e62ad5
Use Hurl instead of curl for features detection. 2025-08-02 00:24:17 +02:00
Filipe PINTO 950b8236ef
Use libclang-dev for contrib ppa 2025-08-01 23:47:20 +02:00
Filipe PINTO 9951912b92
Fix mounted gpg volume for contrib ppa 2025-08-01 22:18:50 +02:00
Filipe PINTO 2238e4888a
Fix libclang-dev version in debian/control for contrib ppa 2025-08-01 17:52:49 +02:00
Filipe PINTO be1f1c3887
Fix changelog.template version for contrib ppa 2025-08-01 17:48:38 +02:00
Filipe PINTO 7c97c453fa
Fix libclang version on README.md for contrib ppa 2025-08-01 17:45:42 +02:00
Filipe PINTO 2663d6a318
Fix typo for contrib ppa README.md 2025-08-01 17:15:11 +02:00
Filipe PINTO bc8af249df
Patch debian/control when olders Ubuntu for contrib ppa 2025-08-01 15:31:28 +02:00
Filipe PINTO e4c17013ac
Fix Windows build contrib 2025-08-01 15:08:06 +02:00
Filipe PINTO 19835abf4a
Reorder and fix README.md for contrib ppa 2025-08-01 14:56:43 +02:00
Filipe PINTO 70cdceca69
Fix debuild errs and warns for contrib ppa 2025-08-01 14:48:34 +02:00
Filipe PINTO f90a3c0416
Fix non native mode for contrib ppa 2025-08-01 11:55:06 +02:00
Filipe PINTO 6f0f7b2439
Fix copyright for contrib ppa 2025-08-01 11:32:36 +02:00
Filipe PINTO f7b97f3257
Fix override_dh_clean and version for contrib ppa 2025-08-01 11:17:45 +02:00
Jean-Christophe Amiel 9ef0c310a4
Update Hurl contrib sample. 2025-07-31 18:20:15 +00:00
Filipe PINTO bd3f64d087
Add libclang-dev to contrib ppa build prerequisites 2025-07-31 17:20:41 +02:00
Filipe PINTO fef0b7eefe
Add libclang-dev to control file for contrib ppa 2025-07-31 17:04:14 +02:00
Filipe PINTO 35154843a5
Add passphrase var to ppa contrib 2025-07-31 16:53:51 +02:00
Jean-Christophe Amiel 56f5bdbf0b
Update npm package for Hurl 7.0.0
Remove axios and rimraf dependencies and use Node API >= 18.
2025-07-31 12:58:07 +00:00
Filipe PINTO c68e503650
Update to alpine:3.22 for docker package 2025-07-31 14:30:36 +02:00
Filipe PINTO de21eda655
Fix workflow descriptions on update-branch-version.yml 2025-07-30 17:08:30 +02:00
Filipe PINTO 2a6a9af188
Fix token for push-to-winget job on extra-package.yml 2025-07-30 16:58:38 +02:00
hurl-bot 4220b4d25c
Update hurl version to 7.1.0-SNAPSHOT 2025-07-30 14:31:35 +00:00
hurl-bot 04d053ab4c
Create 7.0.0 release 2025-07-30 12:05:41 +00:00
Fabrice Reix 55c53559fe
Make the JSONPath index selector returns nothing rather than empty list 2025-07-30 11:20:04 +02:00
hurl-bot 41165ad59b
Update crates 2025-07-30 03:30:45 +00:00
Jean-Christophe Amiel 607ca0dac1
Fix regression in following redirection with query sections. 2025-07-29 22:38:09 +02:00
Jean-Christophe Amiel 9c3096eb6a
Update docs on Content-Encoding not affecting captures. 2025-07-29 08:50:23 +02:00
hurl-bot 568d8fbd00
Update crates 2025-07-29 03:33:24 +00:00
Jean-Christophe Amiel b0fa7010bb
Fix "Create null pull request" job. 2025-07-28 15:05:46 +02:00
Jean-Christophe Amiel 399bc2794f
Update standalone links. 2025-07-28 13:31:11 +02:00
Jean-Christophe Amiel 302dd7efd3
Update CHANGELOG. 2025-07-28 13:02:52 +02:00
hurl-bot 1c8eb5b9e1
Update crates 2025-07-27 08:28:36 +00:00
Tyler Brockmeyer 716ec572d9
add negotiate option 2025-07-26 15:38:21 -05:00
Jean-Christophe Amiel 6756a6c02f
Update README. 2025-07-26 11:29:31 +02:00
Tyler Brockmeyer fe48eda608
prevent duplicated response sections 2025-07-25 21:11:13 -05:00
Tyler Brockmeyer c361a4aa28
create test case for duplicate response section 2025-07-25 21:11:12 -05:00
Jean-Christophe Amiel 302b0b2457
Update Hurl npm package to 6.1.4 2025-07-23 21:53:39 +02:00
Jean-Christophe Amiel fcbeb8fe12
Restrict jsonpath filter to string input values. 2025-07-23 18:40:40 +02:00
Jean-Christophe Amiel b76ee7b33c
Update CHANGELOG 2025-07-23 17:13:15 +02:00
Ashish Reddy 4bb05dad42
Add ntlm cli option 2025-07-23 16:32:24 +05:30
hurl-bot 6521c42ad1
Update crates 2025-07-22 03:29:38 +00:00
Jean-Christophe Amiel 3b0ab5403f
Update Hurl npm package to 6.1.3. 2025-07-21 23:22:30 +02:00
Jean-Christophe Amiel 433f43bab0
Update vim simple syntax coloring. 2025-07-21 17:01:08 +00:00
TheoForger e5e51cae12
Implement predicate `isUuid` 2025-07-21 12:25:15 -04:00
Jean-Christophe Amiel 4e9ef9a523
Update IntelliJ simple syntax coloring. 2025-07-21 17:21:33 +02:00
Jacob Adam 7b88461066
Fix build on Rust nightly by excluding `pre_entry` and `post_entry` from the `PartialEq` derivation of `RunnerOptions`. 2025-07-21 14:35:08 +01:00
Jean-Christophe Amiel c45b85759a
Hide deprecated interactive option from help and manual. 2025-07-21 13:43:49 +02:00
Jean-Christophe Amiel 8b3b797992
Add token for check latest Rust version. 2025-07-21 13:00:59 +02:00
Jean-Christophe Amiel 29f4f8d05e
Display errors when trying to get the latest Rust version. 2025-07-21 11:26:07 +02:00
Jean-Christophe Amiel d0903ada37
Add precision in the CONTRIBUTING guide. 2025-07-21 08:29:46 +02:00
hurl-bot 0810ed92d2
Update crates 2025-07-21 03:31:11 +00:00
Jean-Christophe Amiel cfbcbe676e
Remove unnecessary println. 2025-07-20 11:26:11 +02:00
hurl-bot 6a8c98554c
Update crates 2025-07-20 03:31:44 +00:00
Jean-Christophe Amiel 1e105fd0dd
Update integration test on toFloat filter. 2025-07-19 15:15:51 +00:00
Jean-Christophe Amiel c070c739e6
Minor change to status line parsing. 2025-07-19 16:46:53 +02:00
hurl-bot 4371ac9118
Update crates 2025-07-19 03:27:25 +00:00
Jean-Christophe Amiel 5bc4a0d114
Move method to test code. 2025-07-18 19:04:02 +02:00
Jean-Christophe Amiel 27bc9a7eb7
Make momentarly package-anatomy continues on errors. 2025-07-18 16:13:37 +00:00
Jean-Christophe Amiel d79e60848d
Small tweaks on error messages. 2025-07-18 09:22:24 +02:00
Jean-Christophe Amiel 9503559bc3
Update filters errors integration test. 2025-07-17 18:12:57 +02:00
Jean-Christophe Amiel 898d8f496e
Remove ReadOnlySecret error (unused). 2025-07-17 13:39:01 +02:00
Jean-Christophe Amiel 92aa88f412
Remove dead code. 2025-07-16 21:22:41 +00:00
Jean-Christophe Amiel ddeac72e33
Add integration test for verbose capture. 2025-07-16 20:13:32 +00:00
Jean-Christophe Amiel 4057195e1c
Improve captures error messages when filter chain returned no value. 2025-07-16 21:06:18 +02:00
hurl-bot 2f09d4a1f8
Update crates 2025-07-16 03:29:17 +00:00
Jean-Christophe Amiel 372e6912c8
Using Arch Linux libxml2-legacy package for testing Linux generic package on Arch Linux. 2025-07-15 14:34:43 +02:00
hurl-bot 62eaac0fb8
Update crates 2025-07-15 03:29:30 +00:00
Jean-Christophe Amiel a1a2ae106b
Update location filter doc. 2025-07-14 21:43:55 +02:00
hurl-bot 521404eebb
Update crates 2025-07-14 03:30:08 +00:00
Jean-Christophe Amiel 4083288281
Improve report I/O error message with filename. 2025-07-13 23:47:00 +02:00
Jean-Christophe Amiel 60838fe184
Fix mini typo. 2025-07-13 22:33:21 +02:00
Jean-Christophe Amiel fa9ad5633a
Add deprecation integration test. 2025-07-12 16:23:18 +00:00
Jean-Christophe Amiel 0c3acf06a7
Delete unused function. 2025-07-12 16:38:33 +02:00
Jean-Christophe Amiel b2e12e0725
Support jsonpath filter input other than string. 2025-07-11 17:02:39 +02:00
hurl-bot 5f29389f75
Update actions 2025-07-11 04:11:55 +00:00
hurl-bot 89e2bb1e09
Update crates 2025-07-11 03:29:26 +00:00
Jean-Christophe Amiel a5e1f3d87f
Fix doc typo. 2025-07-10 22:09:08 +02:00
Jean-Christophe Amiel 4435c3c233
Update CHANGELOG. 2025-07-10 17:47:51 +02:00
hurl-bot 658b8caad0
Update crates 2025-07-10 03:26:59 +00:00
Jean-Christophe Amiel a3cad69bfc
Remove dead-code error case in URL decode filter. 2025-07-09 11:41:51 +02:00
Jean-Christophe Amiel ce5f26886e
Tweak filter errors messages. 2025-07-09 07:32:06 +02:00
Jean-Christophe Amiel 0f75ff5db3
Use slice instead of Vec in function params. 2025-07-09 06:47:35 +02:00
hurl-bot 97a9423d72
Update crates 2025-07-07 03:28:31 +00:00
hurl-bot 234556f465
Update crates 2025-07-06 03:28:58 +00:00
Jean-Christophe Amiel a314f3085c
Update on somme error/help messages. 2025-07-04 15:09:47 +02:00
Fabrice Reix d28e05e99d
Fix clippy warnings for Rust 1.88.0 2025-07-04 09:39:46 +02:00
Fabrice Reix ae3cc1ec69
Update Rust to 1.88.0 2025-07-04 09:38:58 +02:00
Jean-Christophe Amiel f586986c0e
Update sample with redirects query. 2025-07-02 21:32:22 +02:00
hurl-bot c50d1a2018
Update crates 2025-07-02 03:24:39 +00:00
lepapareil b6a72f1006
Add robustness to zizmor.sh 2025-07-01 11:42:18 +02:00
Jean-Christophe Amiel a3d46629ae
Update follow redirection integration test with some request cookies. 2025-06-30 22:04:09 +02:00
Fabrice Reix 85aeff183c
Fix zsh completion 2025-06-30 19:21:16 +00:00
hurl-bot d4a1b103dc
Update crates 2025-06-30 15:37:16 +00:00
Jean-Christophe Amiel 89d720fa22
Update CHANGELOG 2025-06-30 14:48:08 +00:00
Filipe PINTO 33014ac3fa
Fix zizmor 2025-06-30 16:36:53 +02:00
Filipe PINTO 925d684189
Fix getting last crates versions in update_crates.sh 2025-06-30 14:26:48 +02:00
Jean-Christophe Amiel 8641a2e91e
Update READMEs. 2025-06-26 23:42:12 +02:00
Jean-Christophe Amiel 3e90acfc72
Update output option section with '-'. 2025-06-26 11:02:45 +00:00
Jean-Christophe Amiel 6fa28f2789
Update doc sample with "Debug Tips" sections 2025-06-25 21:18:09 +02:00
Dhruv Thakur 81be6a6c25
parse curl's --cookie flag
Only support inline data in the format "NAME1=VALUE1; NAME2=VALUE2" (as
opposed to also supporting reading cookie data from a file) in the first
iteration.
2025-06-23 22:19:42 +02:00
Jean-Christophe Amiel 0ecdf2f0b7
Rename DisplaySourceError::to_string method to DisplaySourceError::render 2025-06-23 18:03:30 +02:00
Jean-Christophe Amiel 598e8361b2
Delete error_runtime_rich<E: DisplaySourceError> on Logger. 2025-06-23 18:00:23 +02:00
Jean-Christophe Amiel 9af4d372dd
Delete error_parsing_rich<E: DisplaySourceError> on Logger. 2025-06-23 17:55:54 +02:00
Fabrice Reix 9e8a1cff54
Support negative index in jsonpath 2025-06-23 17:17:41 +02:00
Jean-Christophe Amiel 6116a622d7
Support template in nth filter parameter 2025-06-21 20:29:39 +02:00
Jean-Christophe Amiel 6e3cc2546d
Update grammar for nth filter. 2025-06-21 19:25:57 +02:00
Jean-Christophe Amiel 1b6d25abc5
Reorder "Source" nav item in HTML report. 2025-06-21 13:03:35 +02:00
Jean-Christophe Amiel 5f9f4bc8a4
Update sample on Home with a better POST form. 2025-06-21 12:50:37 +02:00
Jean-Christophe Amiel ad6ac8d8af
Fix typo in CHANGELOG. 2025-06-21 12:23:58 +02:00
Jean-Christophe Amiel 17b89cdb23
Update Python dev dependencies. 2025-06-20 12:17:59 +00:00
Jean-Christophe Amiel 7f60c5fe28
Update changelog 2025-06-20 13:21:10 +02:00
Jean-Christophe Amiel 14145f02dd
Introduces newtype CharPos on reader 2025-06-19 16:31:03 +02:00
hurl-bot 24618d0137
Update actions 2025-06-19 12:25:37 +00:00
Jean-Christophe Amiel d246c2366a
Rewrite lint algo to not recreate an AST. 2025-06-19 09:07:04 +02:00
Jean-Christophe Amiel c0473a34cb
Small tweaks to --test progress ouput 2025-06-18 14:06:55 +02:00
Jean-Christophe Amiel 877bf98320
Update docs/integration test with regex syntax / flags. 2025-06-18 09:23:34 +02:00
hurl-bot d568b13180
Update crates 2025-06-18 03:22:53 +00:00
Jean-Christophe Amiel 0eb5c6ab2d
Align parser on grammar for redacted captures. 2025-06-17 13:00:25 +02:00
hurl-bot 6364342643
Update actions 2025-06-17 04:05:29 +00:00
Jean-Christophe Amiel 61159d9d34
Update Python dependencies (for test/dev). 2025-06-16 16:28:59 +02:00
Ashish Reddy 6ad7e5f00a
Add timeline link on status label in source and run pages 2025-06-16 06:57:19 +00:00
hurl-bot 61847124cc
Update crates 2025-06-14 03:20:39 +00:00
Jean-Christophe Amiel b43beb3f0a
Change field redact to redacted. 2025-06-13 12:05:29 +00:00
Jean-Christophe Amiel cc83adddd3
Fix typo CloudFlare/Cloudflare. 2025-06-13 12:05:29 +00:00
Jean-Christophe Amiel e2b67864f3
Fix typo hurl/Hurl in man. 2025-06-13 12:05:28 +00:00
hurl-bot 41acdba54d
Update crates 2025-06-13 03:23:21 +00:00
Jean-Christophe Amiel 7b9d411a05
Small refacto on entry options. 2025-06-12 09:39:24 +02:00
hurl-bot 0d65694696
Update crates 2025-06-12 03:22:12 +00:00
Jean-Christophe Amiel aabf7d33f8
Implement text exporter with visitor. 2025-06-11 09:50:57 +00:00
Tim Weber 14895db571
Do spell checking in comments only
See `:h spell-syntax` for how this works.
2025-06-11 07:04:47 +00:00
Jean-Christophe Amiel da79c894dd
Update CHANGELOG. 2025-06-10 18:21:32 +02:00
Jean-Christophe Amiel 248ac41cfa
Add integration test for HTML injection through regex literal in HTML report. 2025-06-10 13:12:18 +02:00
Jean-Christophe Amiel 7dcdbd1796
Fix HTML injection in HTML report through regex literal.
The HTML report generation uses a new AST walker.
2025-06-10 13:12:17 +02:00
hurl-bot 3385d02289
Update crates 2025-06-10 03:24:02 +00:00
Jean-Christophe Amiel 7ec649e8dd
Add implementation. not on error rendering. 2025-06-09 17:32:55 +02:00
hurl-bot 7363536234
Update crates 2025-06-08 03:27:38 +00:00
Jean-Christophe Amiel bad34ff70e
Update CHANGELOG. 2025-06-06 14:40:43 +02:00
Jean-Christophe Amiel 5e1e65706f
Fix "variables" token in GraphQL HTML export 2025-06-06 13:45:54 +02:00
hurl-bot 88bc0dce51
Update crates 2025-06-06 03:22:47 +00:00
Ashish Reddy 2dfbab6208
Show curl command when error format option is set to long 2025-06-05 13:14:49 +00:00
hurl-bot 9f0980c789
Update crates 2025-06-05 03:22:20 +00:00
Jean-Christophe Amiel 502b6328c4
Use filename class for unix-socket option HTML class. 2025-06-04 13:30:43 +02:00
Jean-Christophe Amiel a0af1f2e13
Update filters doc. 2025-06-03 18:15:32 +02:00
Jean-Christophe Amiel 250fbbec8c
Add replaceRegex filter and fix replace filter to not take regex 2025-06-02 19:12:22 +02:00
Jean-Christophe Amiel 059cd4c894
Hightlight line errors in HTML export. 2025-06-02 09:13:28 +02:00
Jean-Christophe Amiel ca2628227b
Remove buggy HTML report "line" class. 2025-06-02 08:27:07 +02:00
hurl-bot f9796b7c03
Update crates 2025-05-31 03:19:25 +00:00
Jean-Christophe Amiel 325c7630e0
Fix integration tests file. 2025-05-29 19:43:17 +02:00
Jean-Christophe Amiel a23bbf5537
Update progress_bar integration test. 2025-05-29 16:34:40 +02:00
Jean-Christophe Amiel e1f9919bc7
Fix integration tests file. 2025-05-29 16:17:57 +02:00
Jean-Christophe Amiel 154dfa0cc5
Move very_verbose integration tests in subfolder. 2025-05-29 14:26:43 +02:00
Jean-Christophe Amiel 4ba8336a54
Move version integration tests in subfolder. 2025-05-29 14:26:43 +02:00
Jean-Christophe Amiel 06d92652a3
Move verbose integration tests in subfolder. 2025-05-29 14:26:42 +02:00
Jean-Christophe Amiel 6d9417ed63
Move variables integration tests in subfolder. 2025-05-29 14:26:42 +02:00
Jean-Christophe Amiel ed8db060b0
Move utf8 integration tests in subfolder. 2025-05-29 14:26:42 +02:00
Jean-Christophe Amiel 06756c524d
Move user_agent integration tests in subfolder. 2025-05-29 14:26:41 +02:00
Ashish Reddy 4501a99d37
Add docs for first and last filter 2025-05-29 11:10:55 +00:00
Jean-Christophe Amiel fd869455ae
Fix refacto integration tests. 2025-05-29 10:52:45 +02:00
Jean-Christophe Amiel 2c34116613
Move url integration tests in subfolder. 2025-05-29 10:04:28 +02:00
Jean-Christophe Amiel 3bb73c4255
Move stdout integration tests in subfolder. 2025-05-29 10:04:27 +02:00
Jean-Christophe Amiel a57637dd65
Move stdin integration tests in subfolder. 2025-05-29 10:04:27 +02:00
Jean-Christophe Amiel 7331ad7fe6
Move skip integration tests in subfolder. 2025-05-29 10:04:27 +02:00
Jean-Christophe Amiel 2f4d623f86
Move secret integration tests in subfolder. 2025-05-29 10:04:27 +02:00
Jean-Christophe Amiel bc78163159
Move retry integration tests in subfolder. 2025-05-29 10:04:27 +02:00
Jean-Christophe Amiel 3e43c751e6
Move resolve integration tests in subfolder. 2025-05-29 10:04:26 +02:00
Jean-Christophe Amiel 4c54eaabca
Move request_content_length integration tests in subfolder. 2025-05-29 10:04:26 +02:00
Jean-Christophe Amiel ea0f10c381
Move repeat integration tests in subfolder. 2025-05-29 10:04:26 +02:00
Jean-Christophe Amiel 933bdbf313
Move redirect integration tests in subfolder. 2025-05-29 10:04:25 +02:00
hurl-bot 2a910d12ff
Update crates 2025-05-29 03:20:50 +00:00
Ashish Reddy 943f9446cf
Add integration tests for first and last filter 2025-05-28 12:58:53 +00:00
Jean-Christophe Amiel 1e5cc7bf45
Move reason integration tests in subfolder. 2025-05-28 13:17:13 +02:00
Jean-Christophe Amiel a78cdd0811
Move querystring integration tests in subfolder. 2025-05-28 13:17:12 +02:00
Jean-Christophe Amiel 97c263a915
Update comments on redirection. 2025-05-28 12:01:46 +02:00
Jean-Christophe Amiel bb24c88516
Move output integration tests in subfolder. 2025-05-28 11:28:07 +02:00
Jean-Christophe Amiel e96f793e3a
Move put integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel b37355a8a9
Move proxy integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel 81e100366d
Move progress_bar integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel 305e9962ab
Move predicates integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel 1c68a7b4cb
Move post integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel e40cafbee6
Move path_as_is integration tests in subfolder. 2025-05-28 11:28:06 +02:00
Jean-Christophe Amiel fdda98783d
Move patch integration tests in subfolder. 2025-05-28 11:28:05 +02:00
Jean-Christophe Amiel 873a2618a3
Move parse_cache integration tests in subfolder. 2025-05-28 11:28:05 +02:00
Jean-Christophe Amiel 304e50ed28
Move override_header integration tests in subfolder. 2025-05-28 11:28:05 +02:00
Jean-Christophe Amiel 5f721f1ace
Move output integration tests in subfolder. 2025-05-28 11:28:05 +02:00
Ashish Reddy 876719f446
Add first and last filters 2025-05-28 08:25:40 +00:00
Jean-Christophe Amiel 4c0dbab8ad
Add integration test for request body during redirections. 2025-05-28 09:15:19 +02:00
Jean-Christophe Amiel 91a20aea51
Update CHANGELOG.md. 2025-05-28 08:06:32 +02:00
Ashish Reddy 53beeceed1
Add grammar and parsing for first and last filters 2025-05-28 05:17:18 +00:00
hurl-bot 09f0dc33ff
Update crates 2025-05-28 03:20:35 +00:00
Jean-Christophe Amiel 2903a3da6d
Move options_template integration tests in subfolder. 2025-05-27 18:42:18 +02:00
Jean-Christophe Amiel f6d130c648
Move non_utf8 integration tests in subfolder. 2025-05-27 18:42:18 +02:00
Jean-Christophe Amiel 8e4a7bad84
Move no_output integration tests in subfolder. 2025-05-27 18:42:17 +02:00
Jean-Christophe Amiel d1278d8725
Move no_entry integration tests in subfolder. 2025-05-27 18:42:17 +02:00
Jean-Christophe Amiel f5c1284480
Move netrc integration tests in subfolder. 2025-05-27 18:42:17 +02:00
Yannick Alexander b5c1361046
Fix to retain the request_spec after a redirect
Adjusted client to only use the original request body in case the method didn't change after redirection
2025-05-27 15:03:29 +00:00
Jean-Christophe Amiel de29db8af6
Update Authorization filter test with lower case header name and --location. 2025-05-27 10:07:16 +00:00
Ashish Reddy 29c80fc200
Add integrations tests for pinnedpubkey option 2025-05-27 09:34:09 +00:00
Jean-Christophe Amiel a85c880f0f
Move multiple integration tests in subfolder. 2025-05-27 07:19:29 +00:00
Jean-Christophe Amiel 204e81a844
Move multipart integration tests in subfolder. 2025-05-27 07:19:28 +00:00
Jean-Christophe Amiel 46c379a2a2
Move multilines integration tests in subfolder. 2025-05-27 07:19:28 +00:00
Jean-Christophe Amiel 8359cea0a5
Move method integration tests in subfolder. 2025-05-27 07:19:27 +00:00
hurl-bot df5979df67
Update crates 2025-05-27 03:19:36 +00:00
Ashish Reddy df44118115
Add option to configure pinnedpubkey per request 2025-05-26 20:50:29 +00:00
Jean-Christophe Amiel 073d48812d
Update CHANGELOG. 2025-05-26 16:53:39 +00:00
Fabrice Reix c4293f03d2
Use optional color in options 2025-05-26 15:54:23 +00:00
Jean-Christophe Amiel eef7454709
Fix contrib sample (should use the last release version) 2025-05-26 15:25:51 +02:00
Fabrice Reix bc3bc2f4d0
Handle option defaults explictly 2025-05-26 13:36:29 +02:00
Jean-Christophe Amiel 034cf77c3b
Move max_redirect integration tests in subfolder. 2025-05-26 09:15:57 +02:00
Ashish Reddy 2c109824f5
Add integration tests for pinnedpubkey 2025-05-26 06:35:13 +00:00
hurl-bot ede22dd610
Update crates 2025-05-26 03:22:28 +00:00
Jean-Christophe Amiel c8afb25c8a
Move limit_rate integration tests in subfolder. 2025-05-23 18:42:43 +02:00
Jean-Christophe Amiel 2feded093a
Move key_template integration tests in subfolder. 2025-05-23 18:40:28 +02:00
hurl-bot 668f888fc2
Update crates 2025-05-23 11:11:52 +00:00
Ashish Reddy 5926653248
Add pinnedpubkey cli option 2025-05-23 10:26:48 +00:00
Jean-Christophe Amiel fa97ac47d0
Update to Rust 1.87 2025-05-23 08:49:29 +02:00
Jean-Christophe Amiel efe2c6c3d2
Move test integration tests in subfolder. 2025-05-22 07:16:18 +02:00
Jean-Christophe Amiel a86b4e4ec8
Move tap integration tests in subfolder. 2025-05-22 07:16:18 +02:00
Jean-Christophe Amiel 35023dbf03
Move report_json integration tests in subfolder. 2025-05-22 07:16:18 +02:00
Jean-Christophe Amiel 2bcffb5388
Move junit integration tests in subfolder. 2025-05-22 07:16:18 +02:00
Jean-Christophe Amiel b3d68984be
Move jsonpath integration tests in subfolder. 2025-05-22 07:16:17 +02:00
Jean-Christophe Amiel 019ea24391
Move json_output integration tests in subfolder. 2025-05-22 07:16:17 +02:00
Jean-Christophe Amiel 7e470905f8
Move interactive integration tests in subfolder. 2025-05-22 07:16:17 +02:00
Jean-Christophe Amiel 54ac9beff0
Move ip_query in subfolder. 2025-05-22 07:16:17 +02:00
Jean-Christophe Amiel 282d629acd
Move html include, insecure tests in subfolder. 2025-05-22 07:16:17 +02:00
hurl-bot 6d8de7e92f
Update crates 2025-05-22 03:19:41 +00:00
Ashish Reddy e7e1ce0342
Update docs for max-time 2025-05-20 17:51:07 +05:30
Jean-Christophe Amiel ef26155c33
Update README for docs and add script for updating all docs. 2025-05-20 11:09:23 +02:00
Jean-Christophe Amiel 037b23ad4d
Move ignore_asserts integration tests in subfolder. 2025-05-20 09:40:22 +02:00
Jean-Christophe Amiel 56ae85b4ff
Move html integration tests in subfolder. 2025-05-20 09:40:21 +02:00
Jean-Christophe Amiel af8856c852
Move help integration tests in subfolder. 2025-05-20 09:40:20 +02:00
hurl-bot 7339fc0bab
Update crates 2025-05-20 03:19:42 +00:00
Jean-Christophe Amiel 7f64f58ebc
Move hello integration tests in subfolder. 2025-05-19 16:43:57 +02:00
Jean-Christophe Amiel dbb7eb6696
Move header integration tests in subfolder. 2025-05-19 16:43:57 +02:00
Jean-Christophe Amiel 25a6cd28d5
Move head integration tests in subfolder. 2025-05-19 16:43:57 +02:00
Ashish Reddy 9892a9e288
Add support for negative values for nth filter 2025-05-19 19:51:52 +05:30
Jean-Christophe Amiel 4946166f84
Move graphql integration tests in subfolder. 2025-05-19 14:21:30 +02:00
Jean-Christophe Amiel 40faa677b7
Move get_large integration tests in subfolder. 2025-05-19 14:20:41 +02:00
Jean-Christophe Amiel 9cdfdf8f96
Move gb2312 integration tests in subfolder. 2025-05-19 14:20:41 +02:00
Jean-Christophe Amiel ec202be326
Move function_params integration tests in subfolder. 2025-05-19 14:20:41 +02:00
Jean-Christophe Amiel 69fd5015e3
Move form_params integration tests in subfolder. 2025-05-19 14:20:40 +02:00
Jean-Christophe Amiel 42417ff600
Minor method name modification. 2025-05-19 09:17:05 +02:00
Jean-Christophe Amiel 543b8ab82a
Move follow_redirect integration tests in subfolder. 2025-05-19 08:21:03 +02:00
Jean-Christophe Amiel 5cb96bfbc2
Move float integration tests in subfolder. 2025-05-18 19:42:36 +02:00
Jean-Christophe Amiel 116620a093
Move filter integration tests in subfolder. 2025-05-18 19:42:36 +02:00
Jean-Christophe Amiel 72f6d48663
Move filter integration tests in subfolder. 2025-05-18 19:42:36 +02:00
Jean-Christophe Amiel 4441f1a0aa
Move fileroot integration tests in subfolder. 2025-05-18 19:42:36 +02:00
Jean-Christophe Amiel 8fac41d808
Move expect integration tests in subfolder. 2025-05-18 19:42:36 +02:00
Jean-Christophe Amiel bad437ea4b
Move env_var integration tests in subfolder. 2025-05-18 19:42:35 +02:00
Jean-Christophe Amiel 979de7fda2
Move entry integration tests in subfolder. 2025-05-18 19:42:35 +02:00
Jean-Christophe Amiel 67e956eda9
Rework some errors name for cli module and parallel module. 2025-05-18 19:04:40 +02:00
Ashish Reddy fe1e2e0894
Add option to configure max-time per request 2025-05-18 15:01:19 +00:00
Ashish Reddy 324d2a2ad7
Fix wrong curl option being shown in debug when run with max-time 2025-05-17 16:15:55 +00:00
Jean-Christophe Amiel 1cfdf18a58
Move encoding integration tests in subfolder. 2025-05-17 14:09:29 +00:00
alanb 4528ed4410
Fix hurlfmt to disallow invalid header argument in curl command
This commit requires each header parameter in curl commands to either include
a colon or end with a semicolon (for cases with empty header values).
2025-05-17 11:21:20 +00:00
hurl-bot d031c3c3f5
Update crates 2025-05-17 03:18:02 +00:00
Jean-Christophe Amiel b85e025dd8
Move empty integration tests in subfolder. 2025-05-16 11:01:21 +02:00
Jean-Christophe Amiel 9a9a995bd3
Move delay integration tests in subfolder. 2025-05-16 11:01:21 +02:00
Jean-Christophe Amiel b94a486e4c
Move content_type integration tests in subfolder. 2025-05-16 11:01:21 +02:00
Jean-Christophe Amiel 430caa941c
Move completion integration tests in subfolder. 2025-05-16 11:01:21 +02:00
Jean-Christophe Amiel b7cb210653
Move color integration tests in subfolder. 2025-05-16 11:01:20 +02:00
Jean-Christophe Amiel ef62f92ffa
Move charset integration tests in subfolder. 2025-05-16 11:01:20 +02:00
Jean-Christophe Amiel e6a473cb21
Move bench integration tests in subfolder. 2025-05-16 11:01:20 +02:00
Jean-Christophe Amiel 092c1c9dec
Update to latest grcov 2025-05-16 08:36:59 +02:00
hurl-bot 794ac38109
Update crates 2025-05-16 03:19:59 +00:00
hurl-bot 30c85e8acd
Update crates 2025-05-15 19:03:30 +00:00
Jean-Christophe Amiel feaa22734c
Rollback grcov version for coverage.
See <https://github.com/mozilla/grcov/issues/1351>.
2025-05-15 10:16:53 +02:00
Jean-Christophe Amiel 942b7d1937
Move parallel integration tests in subfolder. 2025-05-14 14:16:12 +02:00
Jean-Christophe Amiel f92b3345d9
Move cookie integration tests in subfolder. 2025-05-14 11:58:38 +02:00
Jean-Christophe Amiel dafc5ccdef
Move HTTP version integration tests in subfolder. 2025-05-14 11:58:38 +02:00
Jean-Christophe Amiel a25d4c117d
Fix integration tests. 2025-05-14 09:47:37 +02:00
Jean-Christophe Amiel ae83960769
Move compressed integration test in subfolder. 2025-05-14 09:30:32 +02:00
Jean-Christophe Amiel f2c760d27c
Move captures integration test in subfolder. 2025-05-14 09:30:31 +02:00
Jean-Christophe Amiel 38461fb037
Move connect_to integration test in subfolder. 2025-05-14 08:55:30 +02:00
Jean-Christophe Amiel b387bc1980
Move aws_sigv4 integration test in subfolder. 2025-05-14 08:51:54 +02:00
Jean-Christophe Amiel b23ac6ec3d
Move basic bytes integration test in subfolder. 2025-05-14 08:51:54 +02:00
Jean-Christophe Amiel 7c7540817a
Move basic add_header integration test in subfolder. 2025-05-14 08:35:21 +02:00
Jean-Christophe Amiel ef6e92637c
Move basic authentification integration test in subfolder. 2025-05-14 03:15:21 +00:00
TheoForger 5c615c7e07
Add `location` filter to value variant `HttpResponse` 2025-05-13 19:24:28 +00:00
Jean-Christophe Amiel ec53ca4488
Move inputdir integration test in subfolder. 2025-05-13 13:45:25 +02:00
Jean-Christophe Amiel fa91ba51c8
Move tests_ok/assert* integration tests in subfolder. 2025-05-12 18:17:29 +02:00
Jean-Christophe Amiel eb048a9261
Update CHANGELOG. 2025-05-12 13:01:14 +00:00
Jean-Christophe Amiel 1adb18313c
Add --progress-bar option to force test progress bar to be displayed.
In non interactive TTys, the test progress bar is not displayed. This option for its display.
2025-05-12 13:39:39 +02:00
Ashish Reddy d76bdb196c
Fix incorrect curl command for POST redirect 2025-05-12 04:43:03 +00:00
hurl-bot 137244daf2
Update crates 2025-05-12 03:20:43 +00:00
hurl-bot 667da38de5
Update crates 2025-05-11 03:20:47 +00:00
Jean-Christophe Amiel 6ad3711b8c
Fix HTML closing tag for line with trailing comment. 2025-05-10 12:45:17 +02:00
Jean-Christophe Amiel cfd0a3a5c2
Update build instructions because of libxml crate update. 2025-05-10 12:05:09 +02:00
Jean-Christophe Amiel 4114c83f6b
Fix libxml build (requires bindgen for rust-libxml >= 0.3.4). 2025-05-09 13:38:16 +02:00
hurl-bot 99c4025006
Update crates 2025-05-09 11:16:37 +00:00
Jean-Christophe Amiel 7340d5d7b2
Update cratew without libxml.
libxml crate 0.3.5 has build issues => see <https://github.com/KWARC/rust-libxml/issues/168>
2025-05-09 11:06:33 +02:00
Ashish Reddy 566c454035
Remove hex crate dependency 2025-05-06 22:09:17 +05:30
Ashish Reddy e1e4e17180
Add integration tests and documentation for toHex filter 2025-05-06 11:25:02 +00:00
hurl-bot 44321a68e6
Update actions 2025-05-06 04:00:29 +00:00
Ashish Reddy 8e50da0a3f
Add toHex filter 2025-05-05 12:05:38 +05:30
Jean-Christophe Amiel afb6199383
HTML report: fix span for lines in comment. 2025-05-04 20:44:53 +02:00
Ashish Reddy 1403160a72
Add parsing support for toHex filter 2025-05-04 14:25:55 +00:00
Ashish Reddy 72be53e56f
Update predicate docs to include date 2025-05-04 14:03:55 +00:00
Jean-Christophe Amiel 63bc8f92e4
Downgrade Archlinux CI test to libxml 2.13.8 (2.14 can not be used with Hurl Linux build) 2025-05-04 15:25:12 +02:00
Jean-Christophe Amiel f1fa81b079
Remove lxml dev dependencies. 2025-05-04 14:33:30 +02:00
Jean-Christophe Amiel ba3e29b419
Update changelog. 2025-04-30 18:21:54 +02:00
Jean-Christophe Amiel cfa3068a73
Add function docs. 2025-04-28 17:52:29 +02:00
Jean-Christophe Amiel b93bc46944
Rename multipart ast FileParam to FilenameParam.
We keep File vs Filename for semantic File vs Path.
2025-04-28 16:44:21 +02:00
hurl-bot ff3076a091
Update actions 2025-04-28 04:00:47 +00:00
Jean-Christophe Amiel 39aeddf0a0
Delete std::env from test code. 2025-04-27 18:04:11 +02:00
Jean-Christophe Amiel 6705c92ece
Accept depencies with ISC license <https://www.isc.org/download/> 2025-04-24 14:00:48 +00:00
hurl-bot f76e2476e5
Update hurl version to 7.0.0-SNAPSHOT 2025-04-24 13:47:43 +00:00
Filipe PINTO aa40d01fdc
Cargo lock update for hurl packages when updating branch version 2025-04-24 15:36:46 +02:00
Filipe PINTO 200741e55d
Disable cargo update on updating branch version 2025-04-24 13:23:45 +00:00
Filipe PINTO 42aeeeb6ea
Update zizmor conf 2025-04-24 14:46:55 +02:00
Jean-Christophe Amiel 59d419dea3
Rename some enum/struc/functions to be more explicit.
There were two `AssertResult` struct/enum, I've changed the not public to be `PredicateResult
2025-04-20 22:13:56 +00:00
Jean-Christophe Amiel 7c7b410c30
Replace deprecated libxml2 initGenericErrorDefaultFunc with xmlSetGenericErrorFunc. 2025-04-20 23:31:16 +02:00
Jean-Christophe Amiel 11849eadbf
Update CHANGELOG. 2025-04-20 20:54:43 +02:00
Fabrice Reix d5c681df51
Add jsonpath test on a field that does not exist 2025-04-14 13:41:45 +02:00
Fabrice Reix a1484bf1d3
Update clap help formatting 2025-04-13 10:56:54 +02:00
Fabrice Reix 1ef5e684d2
Parse cookie Expires date attrbute with '-' 2025-04-12 18:48:29 +02:00
Fabrice Reix dc72b07738
Add Cookie Expires attribute value parsing error 2025-04-10 14:36:00 +00:00
Fabrice Reix e7e268bac6
Upgrade to Ubuntu 24.04 for checks 2025-04-10 16:08:00 +02:00
Fabrice Reix 5034e510f1
Display version for valgrind/cargo-valgrind 2025-04-10 15:15:54 +02:00
Fabrice Reix 3c0fba54d3
Fix clippy warning 2025-04-10 15:00:50 +02:00
Fabrice Reix 9fd76ea9e0
Update Rust to 1.86.0 2025-04-10 15:00:47 +02:00
hurl-bot 4cc19fe5b1
Update crates 2025-04-10 03:14:44 +00:00
Ashish Reddy 87425aebac
Add date comparison predicate and update grammar 2025-04-09 09:38:06 +00:00
hurl-bot 441489b509
Update crates 2025-04-09 03:14:37 +00:00
Falk Woldmann bfa08cfdea
Use std::sync::LazyLock instead of lazy_static 2025-04-08 05:40:11 +00:00
Falk Woldmann 4cc46abedf
Fix clippy lint 2025-04-06 17:44:10 +00:00
hurl-bot e4007f65d8
Update crates 2025-04-06 03:15:15 +00:00
hurl-bot 68fc09a1db
Update crates 2025-04-05 03:12:06 +00:00
TheoForger 9866cab7d4
Add http redirects query and integration tests 2025-04-04 08:53:44 +00:00
Jean-Christophe Amiel 6497604a5e
Relax test on proxy error message regression with curl 8.13.0
See <https://github.com/curl/curl/issues/16958>
2025-04-04 10:15:05 +02:00
Jean-Christophe Amiel e33c01e8fd
Implement ToSource on Regex ast node. 2025-04-02 14:54:08 +02:00
Filipe PINTO 535649b2fa
Fix PPA contributing 2025-04-02 11:51:27 +00:00
Filipe PINTO 0bd0253925
Fix PPA contributing 2025-04-02 11:51:26 +00:00
Ashish Reddy 1dded94a31
Update docs for base64 filters 2025-04-02 10:59:44 +00:00
Jean-Christophe Amiel b18c16cb6e
Fix new clap help rendering (see <https://github.com/clap-rs/clap/pull/5963>). 2025-04-02 09:11:09 +02:00
hurl-bot 8880ea2a28
Update crates 2025-04-02 03:13:50 +00:00
hurl-bot cb62edfa7b
Update crates 2025-04-01 11:40:10 +00:00
Ashish Reddy 37b03782b6
Update unit tests for base 64 filters 2025-04-01 14:00:01 +05:30
Ashish Reddy 9cc2aa92ca
Add integration tests for base64 url safe filters 2025-04-01 13:04:28 +05:30
Ashish Reddy a049476ee8
Add base64 url safe encode and decode filters 2025-03-31 11:12:24 +00:00
Fabrice Reix 4ec67dbe23
Update spec JSON Body Asserts 2025-03-31 09:13:08 +00:00
hurl-bot 1c143ed3cd
Update actions 2025-03-31 06:59:44 +00:00
hurl-bot 903f6cb13f
Update crates 2025-03-31 03:16:23 +00:00
Ashish Reddy 31f43d1e6e
Add grammar and parsing support for base64 url safe encode and decode filters 2025-03-30 18:30:50 +05:30
Jean-Christophe Amiel b0a65cd710
Update to Rust 1.85.1. 2025-03-30 13:11:04 +02:00
Ashish Reddy d35d28479e
Add documentation for urlQueryParam filter 2025-03-29 23:56:31 +05:30
Jean-Christophe Amiel 79d277a8ed
Make a specific error to the http::url module. 2025-03-28 10:22:59 +00:00
hurl-bot b28ddefb7a
Update crates 2025-03-28 03:13:50 +00:00
Ashish Reddy 11e409764b
Add integration tests for urlQueryParam 2025-03-27 17:25:16 +00:00
hurl-bot 0e14972e1a
Update crates 2025-03-27 16:56:45 +00:00
Ashish Reddy 5c43de7540
Add urlQueryParam filter 2025-03-27 16:05:56 +05:30
Jean-Christophe Amiel 73d2d07e5e
Update secret integration tests with ovveridden secrets. 2025-03-26 14:50:02 +01:00
Jean-Christophe Amiel a8fbbe3ce0
Keep secret value forever, even if a secret variable override an existing one. 2025-03-26 13:57:50 +01:00
Jean-Christophe Amiel 90f87161ea
Small doc typos. 2025-03-26 09:31:12 +01:00
Jean-Christophe Amiel d0038161de
Update asserting response doc. 2025-03-26 09:18:10 +01:00
Jean-Christophe Amiel 402421e6e9
Publish Hurl 6.1.1 npm package. 2025-03-25 12:55:35 +01:00
Ashish Reddy fa735e6bf0
Update grammar and add parsing support for urlQueryParam 2025-03-25 10:59:15 +00:00
hurl-bot 2298457741
Update actions 2025-03-25 08:34:25 +00:00
Jean-Christophe Amiel 5578c6d281
Fix ip sample and cargo install documentation. 2025-03-25 05:06:32 +00:00
Dhruv Thakur 602c96e3a4
Add integration tests 2025-03-24 17:16:52 +00:00
Dhruv Thakur 9b2475bd4b
Parse verbose flag in curl command 2025-03-24 17:16:51 +00:00
Jean-Christophe Amiel 0e8ed9e246
Show hurl --help with color 2025-03-24 16:28:58 +00:00
Filipe PINTO 670e0d8de4
Fix final pull request on releasing 2025-03-24 15:53:00 +00:00
TheoForger 9bab458b93
modify eval methods to take a list of responses 2025-03-24 10:31:18 -04:00
Jean-Christophe Amiel 8d480538ab
Fix cargo fmt error. 2025-03-24 14:44:58 +01:00
hurl-bot 054e8d9173
Update hurl version to 6.2.0-SNAPSHOT 2025-03-24 13:42:55 +00:00
hurl-bot 376b7e0e45
Create 6.1.1 release 2025-03-24 12:39:25 +00:00
hurl-bot 1c9c826701
Create 6.1.1 release 2025-03-21 07:02:56 +00:00
hurl-bot ae921ffbd8
Create 6.1.1 release 2025-03-21 07:53:00 +01:00
Fabrice Reix 35ae7ff019
Ignore live test 2025-03-21 07:52:53 +01:00
Fabrice Reix 6fb1fc2f35
Fix error message 2025-03-20 16:57:11 +01:00
Fabrice Reix 0ee62ae125
Update CHANGELOG 2025-03-19 15:14:41 +01:00
Fabrice Reix 6b5ef21bdb
Support any value for contains predicate 2025-03-19 15:14:40 +01:00
Fabrice Reix 03f26c71c4
Fix jsonpath array filter with missing attribute in array element 2025-03-19 15:14:40 +01:00
Fabrice Reix 9f7bae9f75
Do not include CR in filename 2025-03-19 15:14:40 +01:00
Fabrice Reix 3ce7843c3d
Fix hurlfmt spacing 2025-03-19 15:13:59 +01:00
Fabrice Reix 569cde1e34
Update hurl version to 6.1.1 2025-03-19 15:13:59 +01:00
Jean-Christophe Amiel 95a2cc55dd
Update toDate filter grammar 2025-03-19 13:56:46 +01:00
Jean-Christophe Amiel ca560a4d40
Publish npm package 6.1.0 2025-03-19 13:21:54 +01:00
lepapareil de91a5c198
Reorg assert doc 2025-03-19 10:25:01 +01:00
lepapareil 39ca8041b2
Clarify generic and deb packages installation 2025-03-18 15:36:51 +01:00
lepapareil 0e5f8ec6a0
Add CRLF tests (non-blocking) 2025-03-18 12:47:31 +00:00
Fabrice Reix ff6128def3
Update Test SSL keys/certificates 2025-03-18 11:42:21 +01:00
Filipe PINTO 37d81acb90
Fix RELEASING.md 2025-03-14 13:59:22 +01:00
hurl-bot 1099557bc1
Update hurl version to 6.2.0-SNAPSHOT 2025-03-14 09:13:46 +00:00
hurl-bot bb51574f83
Create 6.1.0 release 2025-03-12 13:54:55 +00:00
Filipe PINTO de47716b5a
Fix GITHUB_BRANCH_NAME on release.yml 2025-03-12 14:47:11 +01:00
Fabrice Reix d2546f11ab
Update CHANGELOG 2025-03-12 14:26:51 +01:00
lepapareil 31d736242b
Add aarch64 deb package 2025-03-12 13:37:37 +01:00
Jean-Christophe Amiel f19778825d
Update docs for 6.1.0 2025-03-12 09:39:08 +01:00
hurl-bot fa07a2fea8
Update crates 2025-03-12 03:09:22 +00:00
Rajiv Aaron Manglani bfe3b2489a
Fix page anchor in Capturing Response documentation. 2025-03-10 19:57:59 +00:00
TheoForger 2ae36e3963
Add integration test and docs for ip query
* Add integration test for ip query
* update grammar spec for ip
* update docs to include ip query
* disable ipv6-specific test for ip query
2025-03-10 13:03:12 -04:00
Jean-Christophe Amiel a16ed4a8f3
Update Hurl npm package with axios 1.8.2 2025-03-10 08:55:51 +01:00
hurl-bot cdfe7549db
Update crates 2025-03-10 03:01:52 +00:00
Fabrice Reix 0ad7ff1d66
Add spec for JSON Diff 2025-03-09 10:53:19 +00:00
hurl-bot 778bd3828d
Update crates 2025-03-09 03:01:48 +00:00
Fabrice Reix 62109a41b9
Add Deprecations category in CHANGELOG 2025-03-07 20:28:10 +00:00
Jean-Christophe Amiel 92a92ad28f
Update doc for 6.1.0 2025-03-07 17:59:46 +01:00
Jean-Christophe Amiel 7f8052a352
Update dev dependency Jinja 3.1.6 2025-03-07 14:01:23 +01:00
Jean-Christophe Amiel 8fec13529b
Warn for deprecated multilines string attributes 2025-03-07 10:45:19 +01:00
hurl-bot f5da03edbf
Update crates 2025-03-07 03:10:12 +00:00
hurl-bot 697e07a608
Update crates 2025-03-06 03:09:25 +00:00
Jean-Christophe Amiel 61296efb17
Minor refacto on Method, Status, Version AST elems. 2025-03-05 16:47:21 +00:00
Jean-Christophe Amiel 29c1b9ab6a
Update changelog. 2025-03-05 17:08:41 +01:00
Jean-Christophe Amiel 41fd77a02a
Warn for --interactive deprecation 2025-03-04 20:12:48 +00:00
lepapareil 9b77d8d3c8
Fix package-anatomy.sh to work with ubuntu 22.04 deb packages 2025-03-04 20:04:07 +01:00
Filipe PINTO 936fc904f1
Disable package-anatomy.sh waiting for create_deb.sh fix 2025-03-04 19:22:59 +01:00
Filipe PINTO 4157172864
Use ubuntu-22.04 runners as it is the new requirement for Github workflows 2025-03-04 17:46:25 +01:00
Filipe PINTO efc160efb1
Fix get_active_toolchain.sh 2025-03-04 17:11:26 +01:00
hurl-bot 8dce163818
Update crates 2025-03-04 03:10:03 +00:00
Fabrice Reix bd063eeb0b
Update CHANGELOG 2025-03-03 14:16:06 +01:00
Jean-Christophe Amiel 41530fa754
Update changelog. 2025-03-03 13:32:54 +01:00
Fabrice Reix f320207573
Add toString filter 2025-03-03 12:08:20 +01:00
Jean-Christophe Amiel 763443b302
Update integration test for multipart content type parsing. 2025-03-03 09:11:41 +00:00
Jean-Christophe Amiel 0154af5f1a
Change file content type to value string in multipart form data 2025-03-03 09:11:40 +00:00
Jean-Christophe Amiel 72b26aa13c
Update grammar; file-contentype can be templatized now. 2025-03-03 09:11:39 +00:00
Jean-Christophe Amiel 319f5072d2
Refacto on HTML mutlilines export. 2025-03-02 14:24:52 +01:00
hurl-bot e072031ed0
Update crates 2025-03-02 03:10:00 +00:00
Fabrice Reix 2557157eb7
Update HTML report 2025-03-01 12:37:12 +00:00
hurl-bot 0f6aefb41c
Update crates 2025-03-01 03:11:40 +00:00
Jean-Christophe Amiel b48967ac9f
Add new associated function on Template. 2025-02-28 13:47:52 +00:00
hurl-bot 0b99e9f22b
Update actions 2025-02-28 12:35:39 +00:00
hurl-bot 2ea63a5491
Update crates 2025-02-28 09:29:58 +00:00
Jean-Christophe Amiel 5d318aabe1
Update to Rust 1.85.0 2025-02-28 08:43:26 +01:00
hurl-bot 5188b915aa
Update actions 2025-02-27 08:33:55 +00:00
Jean-Christophe Amiel 2628171e0d
Implements to_string on Whitespace. 2025-02-26 18:38:42 +01:00
Jean-Christophe Amiel 4d0241da65
Delete to_string methods. 2025-02-26 09:25:42 +01:00
hurl-bot 3b6efef1b9
Update actions 2025-02-26 04:00:44 +00:00
Fabrice Reix dece792fb3
Add bash file completion for hurl/hurlfmt 2025-02-25 15:48:55 +00:00
lepapareil 152460428d
Optimize hurl command diffs check 2025-02-25 15:48:54 +00:00
Jean-Christophe Amiel 1de58b023e
Delete to_encoded_string method 2025-02-25 15:32:50 +01:00
Jean-Christophe Amiel d5856bae8c
Delete TemplateElement::to_encoded_string 2025-02-25 15:32:50 +01:00
Fabrice Reix 4a61d5e04a
Add Bash completion test 2025-02-25 07:37:47 +00:00
lepapareil 1fc5a6568f
Optimize hurl command diffs check 2025-02-25 07:37:46 +00:00
hurl-bot 9fd48757a3
Update crates 2025-02-25 03:07:44 +00:00
Lily 0b04b5290b
Removed limitation for --cookie-jar to use only one hurl file
Fix formatting
Changed documentation back and add comments to indicate file
Revert doc
Update unit test
2025-02-24 16:23:10 +00:00
Jean-Christophe Amiel 08b91207a0
Remove Text AST structure. 2025-02-24 15:45:47 +01:00
hurl-bot 5beee6364b
Update actions 2025-02-24 09:04:21 +00:00
hurl-bot 4dbc636b2f
Update crates 2025-02-24 03:08:32 +00:00
hurl-bot 140c3205fd
Update crates 2025-02-23 03:07:53 +00:00
Fabrice Reix 27100e3ea3
Remove dependency to _init_completion
examples from https://devmanual.gentoo.org/tasks-reference/completion/index.html
2025-02-22 17:20:29 +00:00
hurl-bot acb47274c2
Update actions 2025-02-22 16:12:16 +00:00
hurl-bot d7ce2f881d
Update crates 2025-02-22 11:54:25 +00:00
Jean-Christophe Amiel 250874c181
Change JsonValue::encoded for JsonValue::to_source. 2025-02-22 11:56:27 +01:00
Jean-Christophe Amiel 76da4993dc
Change JsonListElement::encoded for JsonListElement::to_source. 2025-02-22 11:43:18 +01:00
Jean-Christophe Amiel e3be293e40
Change JsonObjectElement::encoded for JsonObjectElement::to_source. 2025-02-22 11:38:39 +01:00
Jean-Christophe Amiel 5444f1ac93
Rename Value, ListElement, ObjectElement en JsonValue, JsonListElement, JsonObjectElement 2025-02-21 16:03:32 +01:00
Jean-Christophe Amiel 404876cbc3
Implement ToSource for Template and TemplateElement. 2025-02-21 14:37:13 +01:00
Jean-Christophe Amiel 068d062f0b
Reorganize ast core module. 2025-02-21 09:59:02 +00:00
hurl-bot f714fcbcad
Update crates 2025-02-21 08:31:39 +00:00
Jean-Christophe Amiel 07481b1589
Update changelog. 2025-02-20 22:28:36 +01:00
Jean-Christophe Amiel 15a9d979b4
Implement ToSource on Number. 2025-02-20 21:37:11 +01:00
Jean-Christophe Amiel 3574486ac4
Add link to 'open-to-contribution" issues. 2025-02-20 17:01:17 +00:00
TheoForger f79afa3724
allow asserts on ip versions
Add predicates for ip versions to integration test

Revert error variant `RunnerErrorKind::InvalidIpAddr`

improve error handling
2025-02-20 11:48:05 +00:00
hurl-bot 0356fc1c57
Update crates 2025-02-20 03:05:29 +00:00
Jean-Christophe Amiel bd5a204e80
Implement to_string for OptionKind. 2025-02-19 09:04:03 +01:00
hurl-bot 119d3b619d
Update actions 2025-02-19 04:00:36 +00:00
hurl-bot d80e0b7181
Update crates 2025-02-18 03:04:15 +00:00
Jean-Christophe Amiel 51c39f291b
Implement ToSource for U64. 2025-02-17 14:03:32 +00:00
hurl-bot dc1a32189c
Update crates 2025-02-17 12:17:28 +00:00
Fabrice Reix 7370316386
Uniformize IO errors in hurlfmt 2025-02-17 10:51:47 +00:00
Jean-Christophe Amiel e87fa0522a
Desactivate HTTP/3 test on Arch Linux. 2025-02-17 11:09:56 +01:00
Jean-Christophe Amiel 460eae8ffe
Réactivate HTTP/3 integration test on Arch Linux 2025-02-17 08:53:30 +01:00
Jean-Christophe Amiel 62059ae29e
Sort import. 2025-02-16 17:42:10 +01:00
Jean-Christophe Amiel fc582f1f41
Update CHANGELOG. 2025-02-16 16:44:40 +01:00
Jean-Christophe Amiel 68a2b2d2f1
Update integration tests with version query. 2025-02-16 14:24:49 +01:00
Jean-Christophe Amiel cbdfdc697d
Add allow_reuse field on RunnerOptions. 2025-02-16 14:07:49 +01:00
Jean-Christophe Amiel ac2f8fa3c8
Add doc to RunnerOptions. 2025-02-16 14:07:17 +01:00
Jean-Christophe Amiel 85325a643e
Add allow_reuse field on ClientOptions. 2025-02-16 14:07:16 +01:00
hurl-bot 708cc5aeb6
Update crates 2025-02-16 10:15:27 +00:00
Fabrice Reix 74809f6196
Refacto hurlfmt export using command 2025-02-16 08:03:47 +00:00
hurl-bot 825a8a6dde
Update crates 2025-02-15 03:03:41 +00:00
Fabrice Reix dce5e1d242
Refacto hurlfmt --in-place with a command 2025-02-13 17:23:40 +01:00
Jean-Christophe Amiel 82119c2110
Simplify ToSource impl for String and &str. 2025-02-12 17:11:39 +00:00
hurl-bot 3db2367ef3
Update crates 2025-02-12 15:49:05 +00:00
Fabrice Reix 6b70b495b3
Support multiple input file for hurlfmt --check 2025-02-12 14:38:28 +00:00
Jean-Christophe Amiel 32640a9d32
Fix prerequisites Windows for libxml.
See <https://github.com/microsoft/vcpkg-tool/pull/1582>
2025-02-12 14:12:10 +01:00
Filipe PINTO cd84970fc6
Use millisecond for ci tests duration 2025-02-10 10:19:55 +01:00
Fabrice Reix 311881d4d1
Remove lint-specific test script 2025-02-10 09:15:29 +01:00
Fabrice Reix 3d3097dc47
Add hurlfmt --check tests 2025-02-10 08:38:55 +01:00
hurl-bot 2a26a78f3d
Update crates 2025-02-10 03:06:04 +00:00
Ashish Reddy ede7df4ef1
Add version query to docs 2025-02-09 16:45:12 +00:00
Jean-Christophe Amiel 86d0e42fa4
Update changelog. 2025-02-09 17:04:52 +01:00
Ashish Reddy 2f107ddc74
Add version query and integration tests 2025-02-09 20:10:41 +05:30
hurl-bot 310083a11e
Update crates 2025-02-09 03:05:42 +00:00
Fabrice Reix 6c75cb3d00
Remove lint errors 2025-02-08 17:47:08 +00:00
Fabrice Reix 7e97ed412c
Remove lint errors 2025-02-08 17:47:07 +00:00
Hieu Nghia 6c34178b5c
Remove deprecated keyword HTTP/* for HTTP 2025-02-07 23:18:05 +00:00
ikorason 844c23d572
Fix hurlfmt panicking when pipe is broken, instead should exist with formatted error message and status code != 0 2025-02-07 21:21:14 +00:00
ikorason 195abfc18a
fix invalid escape in hurlfmt parse func 2025-02-07 19:32:37 +00:00
TheoForger 0fb503015f
add ip to asserts 2025-02-07 18:55:36 +00:00
TheoForger e41abb02aa
rename ip module 2025-02-07 18:55:35 +00:00
hurl-bot c4bdea4b25
Update actions 2025-02-07 14:26:22 +00:00
Jean-Christophe Amiel 37550ea85d
Fix cookie expire computation change with curl 8.12.0.
Starting with curl 8.12.0, curl caps cookies expires to 400 days from the current time.
See <https://github.com/curl/curl/pull/15937>
2025-02-07 12:31:26 +00:00
Jean-Christophe Amiel 8dd8451506
Update to Rust 1.84.1 2025-02-07 09:39:22 +01:00
hurl-bot 0f1703a2ca
Update crates 2025-02-06 03:04:16 +00:00
TheoForger a84dda3ed4
add ip address to response 2025-02-05 18:03:26 +00:00
Jean-Christophe Amiel 30d03cfa17
Use logger for warning instead of eprintln! 2025-02-05 17:04:38 +00:00
Filipe PINTO 62275934dc
Beautify tests duration logs 2025-02-05 15:41:50 +01:00
Filipe PINTO fd955e3db5
Use Github linux arm runners instead of Circleci and Qemu 2025-02-05 13:57:14 +01:00
hurl-bot e6b4e167a8
Update crates 2025-02-05 12:13:48 +00:00
Uday R ea1a7b76ae
Use util function for creating parent folders for curl export 2025-02-04 17:26:02 +00:00
Uday R 6e1f421ac2
Use util function for creating parent folders for TAP report 2025-02-04 17:26:02 +00:00
Uday R c2da541d6e
Use util function for creating parent folders for JUnit reports 2025-02-04 17:26:02 +00:00
Uday R f0bf4cdd9f
Extract parent folder creation logic to util function 2025-02-04 17:26:01 +00:00
Uday R 501aadfc60
Create parent folders if missing when using --cookie-jar FILE 2025-02-04 17:26:00 +00:00
hurl-bot bbf6a4a80c
Update crates 2025-02-04 03:02:56 +00:00
Jean-Christophe Amiel c0e12b81dd
Use SourceString in I64. 2025-02-03 17:47:51 +01:00
Jean-Christophe Amiel bf003df42e
Use SourceString in U64 AST. 2025-02-03 17:36:27 +01:00
Jean-Christophe Amiel 13fc5b7ca0
Use SourceString in Float AST. 2025-02-03 17:18:47 +01:00
Ashish Reddy a7ca363b2d
Add parsing support for version query 2025-02-03 13:17:01 +00:00
hurl-bot f657a90997
Update crates 2025-02-03 03:03:38 +00:00
hurl-bot 870e09552f
Update crates 2025-02-02 03:03:12 +00:00
Fabrice Reix 3620334c41
Deprecate includes in favor of contains predicate 2025-02-01 09:18:01 +00:00
hurl-bot a84f288e24
Update crates 2025-02-01 03:04:55 +00:00
Jean-Christophe Amiel 04c9ccb5cd
Use SourceString in Hex. 2025-01-31 23:46:19 +01:00
Jean-Christophe Amiel ece330703d
Rename variable. 2025-01-31 23:26:59 +01:00
Jean-Christophe Amiel c632346ab9
Use SourceString in Base64. 2025-01-31 23:21:44 +01:00
Jean-Christophe Amiel 4d71bba50e
Rename section name to identifier. 2025-01-31 23:15:29 +01:00
Jean-Christophe Amiel 3f3f9e9c0f
Change `TemplateElement`'s `source` field type from `String` to `SourceString`. 2025-01-31 17:12:14 +00:00
Fabrice Reix bcbdbd65a4
Support BigInteger in variable 2025-01-31 15:55:44 +00:00
Jean-Christophe Amiel a5fae9180d
Remove cloning on AST request helpers. 2025-01-31 14:47:11 +00:00
Ashish Reddy 07745d3584
Update documentation for base64Encode filter 2025-01-31 19:22:57 +05:30
Ashish Reddy 7c42440a9d
Update documentation for base64 filter 2025-01-31 19:02:46 +05:30
Jean-Christophe Amiel 0887fcb590
Make Float field provate (like I64 et U64). 2025-01-31 12:39:43 +00:00
Fabrice Reix 583cf901bc
Implement functions with Value 2025-01-31 09:56:42 +00:00
Jean-Christophe Amiel 7265f3007f
Rename I64 `encoded` field to `source`. 2025-01-30 18:00:56 +01:00
Jean-Christophe Amiel e1908c90f9
Rename U64 `encoded` field to `source`. 2025-01-30 17:59:00 +01:00
Jean-Christophe Amiel c6b264ee36
Rename Hex `encoded` field to `source`. 2025-01-30 17:59:00 +01:00
Jean-Christophe Amiel 2e75a53327
Delete unused `EncodedString` struct. 2025-01-30 17:59:00 +01:00
Jean-Christophe Amiel d71d873053
Rename Float `encoded` field to `source. 2025-01-30 17:59:00 +01:00
Jean-Christophe Amiel 104feddd96
Rename Base64 `encoded` field to `source. 2025-01-30 17:59:00 +01:00
Jean-Christophe Amiel db9b241f22
Rename TemplateElement `encoded` field to `source`. 2025-01-30 17:58:59 +01:00
Jean-Christophe Amiel 3d39ff0d5d
Run clippy on all targets. 2025-01-30 17:08:52 +01:00
Ashish Reddy bc96085f39
Add integration tests for base64 encode filter 2025-01-30 17:05:31 +05:30
TheoForger d7afe5d029
hurlfmt: handle empty headers from curl input 2025-01-29 12:23:03 -05:00
Jean-Christophe Amiel 815135ed5a
Update changelog. 2025-01-29 13:41:13 +01:00
Jean-Christophe Amiel ab8f7373de
Use Hurl predicates identifiers for Hurl to JSON file export 2025-01-29 13:10:51 +01:00
hurl-bot 6870a6d588
Update crates 2025-01-29 09:07:19 +00:00
Jean-Christophe Amiel 8732f726fe
Improve doc comments. 2025-01-29 09:26:57 +01:00
Jean-Christophe Amiel 07805fae28
Rename OptionKind::name to OptionKind::identifier. 2025-01-29 09:26:57 +01:00
Jean-Christophe Amiel b8e09474da
Rename PredicateFuncValue::name to PredicateFuncValue::identifier. 2025-01-29 09:26:57 +01:00
Jean-Christophe Amiel 0e280b40fd
Add identifier method on CertificateAttributeName. 2025-01-29 09:26:56 +01:00
Jean-Christophe Amiel cb427e3143
Sort display methods.. 2025-01-29 09:26:56 +01:00
Fabrice Reix 4e2f2d166b
Use Value compare in predicates 2025-01-28 22:22:00 +00:00
Jean-Christophe Amiel eda3bd7ffa
Mutualize `QueryValue` name, used in Hurl to HTML, Hurl to JSON, Hurl to text. 2025-01-28 21:38:23 +01:00
Jean-Christophe Amiel 2206a5b0e7
Mutualize `FilterValue` name, used in Hurl to HTML, Hurl to JSON, Hurl to text. 2025-01-28 18:06:33 +01:00
Jean-Christophe Amiel 24a2d4e75c
Display leaking files in integration test files. 2025-01-28 17:26:36 +01:00
Ashish Reddy 7594d043ec
Add integration tests for base64 decode filter 2025-01-28 21:11:39 +05:30
Fabrice Reix b8ef07d3cf
Use Value equality in == and != predicates 2025-01-28 13:20:46 +00:00
Filipe PINTO 62f8c101b6
Use Ubuntu-22.04 runner for package-generic-linux-aarch64 to fix cc link issue 2025-01-28 09:59:35 +01:00
hurl-bot d1f3a045dd
Update actions 2025-01-28 04:00:32 +00:00
Jean-Christophe Amiel 15e7100ef9
Update copyrights 2025 2025-01-27 14:06:31 +01:00
Ashish Reddy 8f603e90ca
Add base64 encode filter 2025-01-27 01:46:16 +05:30
Ashish Reddy 4c78c9918c
Update base64 decoder to use STANDARD 2025-01-26 19:32:04 +00:00
Ashish Reddy b815b8ed95
Add base64 decode filter 2025-01-26 19:32:03 +00:00
Jean-Christophe Amiel 039697d10e
Update doc with --secret and redact. 2025-01-26 16:04:00 +01:00
Fabrice Reix 0268b081c0
Eval template in JSON object key 2025-01-26 15:12:16 +01:00
hurl-bot 2d14abee6f
Update crates 2025-01-25 03:01:48 +00:00
Jean-Christophe Amiel d078d285ac
Update changelog. 2025-01-24 18:54:27 +01:00
Jean-Christophe Amiel 56317e4606
Redact secrets from cookies export. 2025-01-24 17:32:04 +01:00
Jean-Christophe Amiel deaddbf293
Redact secrets from curl export 2025-01-24 15:44:22 +01:00
hurl-bot 85b85ca513
Update crates 2025-01-24 03:02:51 +00:00
Ashish Reddy 7b0c84ac84
Update hurlfmt filter export test 2025-01-23 16:57:06 +05:30
Ashish Reddy af53237363
Add parsing for base64 filters 2025-01-23 16:10:21 +05:30
Filipe PINTO 0853e6937c
Speedify tests on Windows ci 2025-01-22 23:15:19 +01:00
Jean-Christophe Amiel 974b724bab
Redacts secrets from JUnit reports. 2025-01-22 16:43:35 +01:00
Jean-Christophe Amiel f7732deb23
Redacts secrets from JSON report 2025-01-22 15:29:12 +01:00
Jean-Christophe Amiel 8449c1afeb
Update CHANGELOG 2025-01-22 09:52:35 +00:00
Ashish Reddy dd36549216
Add base64 encode decode filters to grammar 2025-01-22 09:06:54 +00:00
hurl-bot 3d9948c188
Update crates 2025-01-22 03:04:09 +00:00
TheoForger 66fe26eeb8
Add integration test `header_curl` 2025-01-21 21:25:53 +00:00
TheoForger 819085b3dd
Handle empty headers in `CurlCmd` 2025-01-21 21:25:53 +00:00
TheoForger 1f14a73323
Refactor code and add unit test 2025-01-21 21:25:53 +00:00
TheoForger f9f81ce904
Allow empty http header 2025-01-21 21:25:52 +00:00
Filipe PINTO 617a7c5b7d
Add duration to test_script.py 2025-01-21 15:54:51 +00:00
Jean-Christophe Amiel 0cf921dd32
Remove dead method on `json::Value`. 2025-01-21 14:12:45 +01:00
Filipe PINTO 2472aa90e9
Fix Zizmor 2025-01-21 08:45:25 +00:00
Ashish Reddy fee90a8dfd
Add error handling for invalid format 2025-01-21 11:21:31 +05:30
hurl-bot 7d7357b5c2
Update crates 2025-01-21 03:02:34 +00:00
Jean-Christophe Amiel dc8cf59061
Raise an error if a secret is redacted while log is in verbose. 2025-01-20 20:41:37 +00:00
Jean-Christophe Amiel 42444f6856
Implement redact on captured variable. 2025-01-20 20:41:36 +00:00
Ashish Reddy 9328eca0ae
Update sourceinfo while creating filter 2025-01-20 19:59:16 +00:00
Ashish Reddy 5dcc03540b
Added unit tests for xpath 2025-01-20 19:59:15 +00:00
Ashish Reddy 96b80afe86
Fixed incorrect panic unit test 2025-01-20 17:03:34 +00:00
Ashish Reddy baddf607d9
Added panic unit test for format 2025-01-20 17:03:34 +00:00
Ashish Reddy a9de5f60e0
Added unit tests for format 2025-01-20 17:03:33 +00:00
Suhodolets Ilya be6fbf9db4
Remove hex-literal crate dependency 2025-01-20 15:02:30 +00:00
Ashish Reddy 0a6ee2f917
Added unit tests for decode 2025-01-20 12:42:30 +00:00
hurl-bot cc3085169a
Update crates 2025-01-20 11:47:45 +00:00
TheoForger 198f72cac1
Add variables to header_option integration test 2025-01-20 09:16:44 +00:00
Filipe PINTO 07e2fc7edd
Disable Zizmor 2025-01-20 10:08:50 +01:00
Fabrice Reix 7513cb7f4d
Add redact in Capture AST 2025-01-18 09:36:56 +00:00
hurl-bot 75f8dea685
Update crates 2025-01-18 03:01:51 +00:00
Jean-Christophe Amiel 10285be765
Update compatibility check sample. 2025-01-17 21:23:19 +00:00
Jean-Christophe Amiel 30b9a1bb5a
Update to Rust 1.84.0 2025-01-17 18:08:22 +01:00
Filipe PINTO fe968563de
Update coverage when push on master 2025-01-16 14:09:07 +01:00
Jean-Christophe Amiel 95227508ba
Modify the model representing secrets. 2025-01-15 14:17:53 +00:00
lepapareil f40e815d2f
Fix Zizmor alerts on release.yml 2025-01-15 14:02:34 +01:00
lepapareil f9796ff5ff
Fix Zizmor alerts on update-branch-version.yml 2025-01-15 14:02:34 +01:00
lepapareil 6c49c9f74a
Add Zizmor to checks 2025-01-15 14:02:29 +01:00
hurl-bot 31c19ccd10
Update crates 2025-01-15 03:02:48 +00:00
Jean-Christophe Amiel 32417157cd
Small fixes on secret variables. 2025-01-14 14:48:58 +01:00
Jean-Christophe Amiel f0ec07340e
Mutualize some common strings. 2025-01-14 14:48:58 +01:00
Jean-Christophe Amiel bed8d116ee
Expose end-of-run variables state in `HurlResult`. 2025-01-14 13:52:21 +01:00
hurl-bot b774284deb
Update crates 2025-01-14 03:01:58 +00:00
hurl-bot 3fa9d37686
Update crates 2025-01-13 03:09:23 +00:00
hurl-bot d268153d9d
Update crates 2025-01-12 03:10:14 +00:00
Jean-Christophe Amiel e0d13290c5
Add function doc on filters functions. 2025-01-11 23:11:47 +01:00
hurl-bot 50e086056a
Update actions 2025-01-11 20:35:46 +00:00
Jean-Christophe Amiel 34d21df6f7
Remove Variable struct, VariableSet is a map of String / Value and secrets are Value::Secret variant. 2025-01-11 17:24:10 +01:00
Jean-Christophe Amiel b6463d2300
Add new value type `Secret`. 2025-01-11 17:24:10 +01:00
theoforger 17d8dc577e
Add header option per request
* Remove `cli-only`
* Add `header` in the `options` field
* Add integration test for header option
2025-01-11 08:54:45 +00:00
hurl-bot c829d28e19
Update crates 2025-01-11 03:06:17 +00:00
Jean-Christophe Amiel e7f9708e46
Update Hurl snippet in doc. 2025-01-10 16:02:22 +01:00
Jean-Christophe Amiel 34f5899886
Update docs on content encoding, especially regarding body asserts.
We also add a new test to check that the response outputed on standard ouput respect 'Content-Encoding'.
2025-01-10 13:11:08 +00:00
lepapareil 293fa2bd47
Revert "Set persist-credentials to false on checkout action" 2025-01-10 14:09:34 +01:00
lepapareil 2be16ae5cc
Set persist-credentials to false on checkout action 2025-01-09 14:12:49 +01:00
hurl-bot 7a3da13c75
Update actions 2025-01-09 04:00:46 +00:00
hurl-bot 31f514acb5
Update crates 2025-01-08 03:05:33 +00:00
Fabrice Reix 44ea0eabe6
Create common printable representation of the value 2025-01-07 13:26:27 +01:00
hurl-bot f869ba53b2
Update crates 2025-01-07 03:07:26 +00:00
Fabrice Reix 647dd2fdc2
Create enum for Value Kind 2025-01-06 20:59:31 +01:00
Jean-Christophe Amiel 291f92aec2
Remove clap's 'cargo' feature.
See <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>, `CARGO_PKG_VERSION` contains the full version of the package, `env!` get this value at compile time and panics if it's not defined.
2025-01-06 13:35:24 +00:00
hurl-bot ff8bb64ceb
Update crates 2025-01-06 03:08:28 +00:00
hurl-bot 93aaba960e
Update actions 2025-01-05 04:00:39 +00:00
hurl-bot 4c8d59f581
Update crates 2025-01-04 03:04:05 +00:00
hurl-bot 5d1a6f9e67
Update crates 2025-01-03 03:05:34 +00:00
Jean-Christophe Amiel 0051116908
Remove "python-pip" packages. 2025-01-02 15:33:17 +01:00
hurl-bot 8b3ff229f0
Update crates 2025-01-02 03:04:32 +00:00
Jean-Christophe Amiel 92a6cd5eb6
Bump Python dev dependencies to fix Jinja CVE
Fix CVE-2024-56326, CVE-2024-56201
2024-12-30 17:57:03 +01:00
Jean-Christophe Amiel 14a14637a8
Minor optimizations to HTML reports. 2024-12-29 21:57:43 +00:00
Jean-Christophe Amiel fe43b0cd14
Replace RedactedString by trait Redact. 2024-12-29 20:31:21 +00:00
hurl-bot 1aa80d7d57
Update crates 2024-12-29 17:50:55 +00:00
Jean-Christophe Amiel 4ef4f4f73f
Install python-lxml package on ArchLinux. 2024-12-27 22:31:32 +01:00
hurl-bot 4b2552b198
Update crates 2024-12-22 03:08:28 +00:00
Jean-Christophe Amiel c25d04cda8
Improve HTML entities lookup tables creation perfs. 2024-12-20 14:30:46 +00:00
hurl-bot bf65e1c08f
Update crates 2024-12-20 03:05:56 +00:00
theoforger ab29198641
Add integration tests for the `--header` option 2024-12-19 15:28:14 -05:00
Jean-Christophe Amiel 08ef7274ba
Update changelog. 2024-12-19 16:19:04 +00:00
Jean-Christophe Amiel bc414f836f
Update secret integration test with HTML report. 2024-12-19 15:16:12 +01:00
Jean-Christophe Amiel 4816724076
Redacts secrets from HTML report 2024-12-19 12:17:00 +01:00
Jean-Christophe Amiel e254a39b3b
Add TODO comments on empty headers. 2024-12-19 11:25:00 +01:00
Jean-Christophe Amiel d98d7cc3d5
Fix missing request line errors in HTML report 2024-12-18 16:26:54 +01:00
Jean-Christophe Amiel 89e0088aaf
Remove deprecated predicates in favor of operators. 2024-12-18 14:15:30 +01:00
Jean-Christophe Amiel cacec561b6
Add overridden secret integration test. 2024-12-18 12:26:02 +01:00
Jean-Christophe Amiel 61aa70c320
Replace eprintln calls that bypass the logger. 2024-12-18 11:34:13 +01:00
hurl-bot 3c1dd9d200
Update actions 2024-12-18 04:00:35 +00:00
hurl-bot 67bd84b077
Update actions 2024-12-17 04:00:40 +00:00
Jean-Christophe Amiel bd56f94ee0
Add --secret integration test (secret are only redacted in logs for the moment) 2024-12-16 16:42:36 +01:00
Jean-Christophe Amiel 8525f2d752
Redacts secret from logs. 2024-12-16 16:41:47 +01:00
Fabrice Reix caaaa33958
Generalizing expressions in Hurl 2024-12-16 14:12:43 +00:00
Jean-Christophe Amiel 946c27ad20
Change error to warning as the error doesn't trigger a runtime error. 2024-12-16 11:08:05 +01:00
hurl-bot 07a042f732
Update crates 2024-12-16 03:16:38 +00:00
Jean-Christophe Amiel 6737edd513
Use PUT instead of POST as --data implies making a POST request. 2024-12-15 19:55:32 +00:00
Jean-Christophe Amiel 5b61be2af5
Remove unused attribute + add some docs. 2024-12-15 20:05:08 +01:00
Fabrice Reix e9e025dd3b
Wrap primitives within struct
in order to preserve user input
2024-12-14 22:43:19 +01:00
hurl-bot 04cd8f506d
Update crates 2024-12-14 03:12:07 +00:00
hurl-bot b61062becd
Update crates 2024-12-12 03:15:17 +00:00
hurl-bot 8975542371
Update crates 2024-12-11 15:32:29 +00:00
Filipe PINTO 46a6494a67
Clarify doc for delay option 2024-12-11 10:09:49 +01:00
Jean-Christophe Amiel f81fa71ab8
Add experimental --secret option (no implementation). 2024-12-10 16:46:18 +00:00
Filipe PINTO 64a171727e
Fix python prerequisites for coverage 2024-12-10 13:44:29 +01:00
Fabrice Reix cb91bb623b
Align parser implem to grammar
Do not re-use other primitive parsers such as natural
2024-12-10 09:26:49 +01:00
hurl-bot 77dec42e60
Update crates 2024-12-10 03:16:15 +00:00
Jean-Christophe Amiel 260a990f9c
Remove expected validation. 2024-12-09 13:53:16 +00:00
Jean-Christophe Amiel a97c60b501
Fix README with shell hint. 2024-12-09 09:36:16 +01:00
hurl-bot d36d7aa50f
Update crates 2024-12-09 03:16:50 +00:00
Fabrice Reix 751825a493
Refacto JSON number parser 2024-12-08 17:26:21 +01:00
Filipe PINTO 926bea4721
Update Dockerfile to alpine 3.21 2024-12-08 11:00:17 +01:00
theoforger 3971e918e9
Add a new option `--header` 2024-12-07 15:13:09 -05:00
Filipe PINTO 1a13135638
Use python 3.11 on Ubuntu/Debian ci 2024-12-07 19:09:43 +01:00
hurl-bot ca4b26f01a
Update crates 2024-12-07 03:14:14 +00:00
theoforger 397fb46732
Add 'Repeated-Header' to the original headers 2024-12-06 17:20:10 -05:00
theoforger 31a0bbfa6c
Add unit test of repeated headers for `aggregate_raw_headers` 2024-12-06 16:45:22 -05:00
Filipe PINTO 983779fc91
Use python 3.11 on windows ci 2024-12-06 11:10:14 +01:00
Filipe PINTO 5f91b14413
Recover commits infos when /accept 2024-12-06 09:50:35 +01:00
hurl-bot c6c8fcb270
Update actions 2024-12-06 07:33:05 +00:00
hurl-bot 35278d79ca
Update crates 2024-12-06 03:15:19 +00:00
Jean-Christophe Amiel e38d5c165c
Delete unnecessary close PR 2024-12-05 19:32:04 +00:00
Jean-Christophe Amiel 28d5717170
Update to Rust 1.83. 2024-12-05 17:30:26 +00:00
casdal 5f0153548f
Fix broken reference-style link in CONTRIBUTING.md 2024-12-05 10:55:24 -05:00
Filipe PINTO d66815e44d
Update installation doc with ppa for Ubuntu 2024-12-05 13:14:11 +00:00
Jean-Christophe Amiel 98663e797a
Publish Hurl 6.0.0 on npm 2024-12-05 13:43:42 +01:00
theoforger 2a89114402
fix typo 2024-12-05 11:39:41 +00:00
theoforger 67a9e23061
Implement method `aggregate_raw_headers` 2024-12-05 11:39:40 +00:00
Filipe PINTO a5b2931bbd
Add simple test to ppa contrib 2024-12-05 11:15:12 +01:00
Filipe PINTO 66bbc9c89d
Fix contrib/ppa/README.md 2024-12-05 11:04:43 +01:00
Filipe PINTO beb60fe902
Fix typo contrib/ppa/README.md 2024-12-05 10:45:36 +01:00
Filipe PINTO 8b58a2be0b
Use native wsl2 compatibility from Vampire/setup-wsl@v4.0.0 action 2024-12-05 08:03:45 +01:00
hurl-bot 74e63ee12c
Update actions 2024-12-05 04:00:41 +00:00
Filipe PINTO 337c0861b1
Add details about extra-packages workflow in RELEASING.md 2024-12-04 16:56:28 +01:00
hurl-bot 92e162f639
Update hurl version to 6.1.0-SNAPSHOT 2024-12-04 13:57:25 +00:00
hurl-bot b2530469dc
Create 6.0.0 release 2024-12-04 08:51:09 +00:00
Jean-Christophe Amiel a7eb25014a
Patch generating README. 2024-12-04 08:07:36 +00:00
hurl-bot 0f15b10198
Update crates 2024-12-04 03:15:29 +00:00
Jean-Christophe Amiel 1025eae405
Use release note script with GitHub token. 2024-12-03 14:31:10 +01:00
Jean-Christophe Amiel bad439942d
Fix typo 2024-12-03 13:43:04 +01:00
Fabrice Reix d5be6565b5
Set Release date 2024-12-03 11:45:39 +00:00
Jean-Christophe Amiel cf69cdfe05
Mark adding secret variable method as not yet ready to be used. 2024-12-03 11:21:05 +01:00
Jean-Christophe Amiel d2e0000076
Update 6.0.0 docs. 2024-12-02 18:33:51 +01:00
Jean-Christophe Amiel efa6b0cb8b
Fix typo. 2024-12-02 16:54:59 +01:00
Jean-Christophe Amiel 242cfa7adf
Favorise normal commit messages instead of "Conventionnal" or "Semantic" ones. 2024-12-02 10:25:05 +00:00
Jean-Christophe Amiel 9e6388f001
Update changelog 2024-12-02 10:32:49 +01:00
hurl-bot 3c9715f17d
Update crates 2024-12-02 03:16:08 +00:00
0xb-s e0da84a7f0
Update serialize_json.rs 2024-12-01 11:29:24 -08:00
hurl-bot 1f2ea65d95
Update crates 2024-12-01 03:20:40 +00:00
Bhuwan Pandit 836ecf6dd3
enhance/hurl: remove depreciated --fail-at-end option 2024-11-30 20:20:53 +00:00
hurl-bot 5649b4fde6
Update crates 2024-11-30 03:10:22 +00:00
hurl-bot 41fac8cbf2
Update crates 2024-11-29 23:18:01 +00:00
Bhuwan Pandit 4660d35473
enhance/hurlfmt: remove depreciated --format option 2024-11-29 22:36:07 +00:00
Fabrice Reix 59dbec80e7
Render date as UTC with microseconds by default 2024-11-28 15:33:09 +00:00
Jean-Christophe Amiel 6b386b5cf2
Rename feature flag from vendored-openssl to static-openssl.
Add comment on the feature.
2024-11-27 14:25:10 +01:00
hurl-bot 072a292a4b
Update crates 2024-11-27 03:26:41 +00:00
hurl-bot 5213bd30dd
Update crates 2024-11-26 03:24:49 +00:00
Fabrice Reix 494808babf
Update CHANGELOG 2024-11-25 18:29:01 +01:00
Jean-Christophe Amiel fda5b3fee4
Update changelog 2024-11-25 15:49:42 +00:00
Jean-Christophe Amiel c792710f50
Forbid wildcard import. 2024-11-25 16:16:34 +01:00
Jean-Christophe Amiel 04c31f3a71
Add public/secret variables (wip) 2024-11-25 09:27:36 +01:00
Jean-Christophe Amiel e3a67a34bf
Update changelog. 2024-11-24 16:47:41 +00:00
hurl-bot 58b281234b
Update crates 2024-11-24 15:59:37 +00:00
Jean-Christophe Amiel f351792c08
Fix help options order 2024-11-24 15:23:34 +00:00
Fabrice Reix ea23052e02
Add newDate generator 2024-11-23 10:50:26 +01:00
Fabrice Reix ce9d41c2c0
Render Date value 2024-11-23 08:37:07 +01:00
Jean-Christophe Amiel 474dcc672c
Update CHANGELOG 2024-11-22 16:39:22 +00:00
hurl-bot 078183a009
Update crates 2024-11-22 16:08:17 +00:00
Filipe PINTO def69bc5ab
Use system pkg-config in CI/CD for macOS (ARM & x86) 2024-11-22 14:50:09 +01:00
Fabrice Reix 184dad25dd
Implement function newUuid 2024-11-22 09:08:46 +01:00
Fabrice Reix d81b5254c3
Render expr rather than variable 2024-11-22 08:49:17 +01:00
Fabrice Reix 4ea2933c65
Add export integ test for function 2024-11-22 07:55:42 +01:00
Filipe PINTO 77731b6ed4
Use system curl in CI/CD for macOS (ARM & x86) 2024-11-21 13:24:04 +00:00
Fabrice Reix 6f28ab19f6
Add function in expression 2024-11-21 10:42:59 +00:00
hurl-bot aae693d698
Update crates 2024-11-21 03:10:29 +00:00
hurl-bot 8bc07977a9
Update crates 2024-11-20 03:10:18 +00:00
Jean-Christophe Amiel d9557522f2
Add source_info to VariableDefinition AST struct. 2024-11-19 17:27:15 +01:00
Jean-Christophe Amiel ac90de8a43
Update changelog. 2024-11-19 12:08:20 +01:00
Jean-Christophe Amiel ace0757204
Fix missing space in variable option HTML export 2024-11-19 11:24:10 +01:00
Fabrice Reix 5df1431d32
Add Placeholder in AST for inner spacing 2024-11-19 09:16:03 +00:00
hurl-bot 5487a59d5b
Update crates 2024-11-19 03:11:12 +00:00
Fabrice Reix eb16dde4c3
Treat Hurl string as template 2024-11-18 21:47:14 +01:00
Jean-Christophe Amiel fd3890fc87
Upgrade hurl crate sample to 5.0.1 2024-11-18 16:49:45 +00:00
Jean-Christophe Amiel 5adeaec74d
Fix cross-spawn dependencies. 2024-11-18 16:12:34 +00:00
Emanuele Panzeri 2ad1ec912e
Update asserting-response.md 2024-11-18 15:41:12 +00:00
Emanuele Panzeri eb648a5588
Fix typo in example.org examples 2024-11-18 15:08:39 +01:00
hurl-bot d0c7d02345
Update crates 2024-11-17 03:13:23 +00:00
hurl-bot f64a5322bf
Update crates 2024-11-15 03:11:04 +00:00
hurl-bot f2d60f2ed0
Update crates 2024-11-14 03:05:39 +00:00
Jean-Christophe Amiel 71d4756047
Introduce VariableSet struct instead of HashMap to hold variables. 2024-11-13 15:06:10 +00:00
hurl-bot 828917b79d
Update crates 2024-11-13 03:05:04 +00:00
Jean-Christophe Amiel 812a22b2ca
Begin spec on secret management. 2024-11-12 14:02:11 +01:00
hurl-bot 1d0b98440f
Update crates 2024-11-12 03:03:19 +00:00
hurl-bot b523244793
Update crates 2024-11-11 03:05:49 +00:00
hurl-bot f8eaf89656
Update crates 2024-11-10 03:06:09 +00:00
Filipe PINTO 64ef4e12c7
Cleanify ppa package source 2024-11-09 21:05:43 +00:00
Fabrice Reix 9f565f9227
Sort imports with ruff 2024-11-09 11:49:28 +01:00
Fabrice Reix 506c7b040d
Add ruff check / Fix ruff lints 2024-11-09 11:12:46 +01:00
Fabrice Reix eb24030e57
Replace black formatter by ruff 2024-11-09 09:22:23 +01:00
Jean-Christophe Amiel 9c91fe8dba
Add curl debug command to HTML report 2024-11-08 22:39:40 +01:00
Jean-Christophe Amiel fc1634d0f6
Update changelog 2024-11-08 22:09:52 +01:00
Fabrice Reix 1908c6c23e
Use eval and render from expr module 2024-11-08 18:32:14 +01:00
Jean-Christophe Amiel dd6519b82f
Allow any string in Location Header when not following redirection 2024-11-08 17:36:49 +01:00
Jean-Christophe Amiel 5aa7ad577b
Fix request log. 2024-11-08 16:47:14 +01:00
hurl-bot 4c96ef8b92
Update crates 2024-11-08 03:04:35 +00:00
Jean-Christophe Amiel 41ae24a848
Update changelog 2024-11-07 17:51:32 +01:00
Jean-Christophe Amiel 9ab2e17716
Add --curl option to export executed requests to curl commands 2024-11-07 17:01:21 +01:00
Jean-Christophe Amiel fb85f78137
Add curl debug command to --json and JSON report 2024-11-07 13:45:18 +01:00
hurl-bot 6bc76e6b84
Update crates 2024-11-07 13:09:18 +01:00
Jean-Christophe Amiel 7fc2d56aa7
Move curl command construction in its own struct. 2024-11-06 13:30:06 +00:00
hurl-bot 9774c8c450
Update crates 2024-11-06 03:03:46 +00:00
Jean-Christophe Amiel b9aa4e0d83
Update changlog. 2024-11-05 17:32:01 +01:00
Fabrice Reix f3eaf96ed0
Distinguish parsing template/expression 2024-11-04 16:50:50 +00:00
Filipe PINTO 2c48754ea9
Minimize rust sources for ppa 2024-11-04 15:29:22 +00:00
Fabrice Reix e341af50c2
Remove url-specific parser (align with grammar) 2024-11-04 12:49:33 +00:00
hurl-bot 9cfc5b90b0
Update crates 2024-11-03 03:09:46 +00:00
Filipe PINTO 7898e58af7
Minimize ppa package source 2024-11-02 23:18:31 +01:00
hurl-bot 6bbbafcaaa
Update actions 2024-11-02 04:00:30 +00:00
lepapareil 2a182f194b
Fix Fedora test prerequisites 2024-11-01 21:29:04 +01:00
Filipe PINTO 6a9645ed72
Add test-windows-wsl2-x64 2024-11-01 15:59:58 +01:00
Jean-Christophe Amiel 9b3defe208
Update changelog. 2024-11-01 10:37:28 +01:00
Fabrice Reix 64b93a505b
Refacto using our own Url struct 2024-10-31 14:03:50 +01:00
Jean-Christophe Amiel 36203a3c78
Fix reading standard input multiple times 2024-10-30 15:05:49 +01:00
Jean-Christophe Amiel 4c55eeaac7
Update changelog. 2024-10-30 11:31:58 +01:00
Jean-Christophe Amiel afcd47fd01
Support more JSON / XML "like" mimetypes with debug output 2024-10-30 10:42:02 +01:00
Fabrice Reix 86a7b6bf29
Add check valgrind 2024-10-29 14:58:12 +01:00
hurl-bot fa5068fb63
Update crates 2024-10-29 03:07:50 +00:00
Jean-Christophe Amiel fa7539b63d
Add limit-rate per request. 2024-10-28 17:58:10 +00:00
Jean-Christophe Amiel 22a879ca68
Update doc on --limit-rate. 2024-10-28 17:58:10 +00:00
Jean-Christophe Amiel 368f5b8a39
Update grammar. 2024-10-28 17:58:09 +00:00
Jean-Christophe Amiel 1a6eb881a5
Update Python dev dependencies. 2024-10-28 17:51:04 +01:00
Jean-Christophe Amiel f7ecbfd323
Update changelog. 2024-10-28 17:01:02 +01:00
Jean-Christophe Amiel fa34ee782b
Implement --limit-rate from curl 2024-10-28 15:31:11 +01:00
hurl-bot f1bd23656a
Update crates 2024-10-28 03:10:03 +00:00
hurl-bot a04f5d2cfd
Update actions 2024-10-27 09:29:37 +00:00
hurl-bot 0399382730
Update crates 2024-10-27 03:09:49 +00:00
Jean-Christophe Amiel 3b37755544
Update changelog. 2024-10-26 14:56:53 +02:00
Jean-Christophe Amiel f1a35a08ef
Remove unnessecary Shutdown message. 2024-10-25 17:44:51 +00:00
Jean-Christophe Amiel e8e5f2f92c
Fix graceful shutdown of workers threads in --test. 2024-10-25 17:44:50 +00:00
Jean-Christophe Amiel 6d7371bf6b
We use GitHub GraphQL API to get issues and PR referenced from issues.
Authors from issues and PR are gratified.
2024-10-25 12:29:07 +02:00
Jean-Christophe Amiel 244177d296
Categorise options in --help 2024-10-25 08:58:21 +00:00
hurl-bot 79eca83e71
Update actions 2024-10-25 08:21:26 +00:00
Jean-Christophe Amiel d5f1b3eb3f
Remove the crate float-cmp.
We can do a "classic" float comparison as clippy suggests https://rust-lang.github.io/rust-clippy/rust-1.72.0/index.html#/float_cmp and remove `float-cmp` from

```rust
let error_margin = f64::EPSILON; // Use an epsilon for comparison
// Or, if Rust <= 1.42, use `std::f64::EPSILON` constant instead.
// let error_margin = std::f64::EPSILON;
if (y - 1.23f64).abs() < error_margin { }
if (y - x).abs() > error_margin { }
```

Note: we compare `f64` for predicate value here 07512a9cbf/packages/hurl/src/runner/number.rs (L32-L40)
so there is no reason to use `float-cmp` in jsonpath module
2024-10-25 06:53:43 +00:00
hurl-bot 1a4c949e5d
Update crates 2024-10-25 05:57:22 +00:00
Jean-Christophe Amiel 1efd816035
Update to Rust 1.82. 2024-10-25 07:26:03 +02:00
Jean-Christophe Amiel 2eb7d02d4e
Add support for backtick strings in predicates values.
We are now able to support this code:

```
GET http://foo.com
HTTP 200
[Asserts]
xpath "string(//title)" == `Bob says: "Hi"`
```
2024-10-24 15:31:13 +02:00
Jean-Christophe Amiel 9fd010b30e
Update grammar with oneline string in predicate value.
Being able to support this code:

```
GET http://foo.com
HTTP 200
[Asserts]
xpath "string(//title)" == `Bob says: "Hi"`
```
2024-10-24 09:29:13 +02:00
Jean-Christophe Amiel 035d844f1d
Fix option connect-timeout help message and documentation. 2024-10-24 09:04:35 +02:00
hurl-bot 85fdf0f6a5
Update crates 2024-10-24 03:06:14 +00:00
hurl-bot f765b0d8f2
Update actions 2024-10-23 12:48:18 +00:00
hurl-bot ad06a45345
Update crates 2024-10-23 03:06:35 +00:00
Sven Schliesing c7704af0e7
Fix typo "ped" -> "pet" 2024-10-22 20:11:26 +02:00
Fabrice Reix c62fb43eea
Check protocol at runtime 2024-10-21 05:59:45 +00:00
hurl-bot 2491637b3d
Update crates 2024-10-21 03:09:15 +00:00
hurl-bot dc15773323
Update crates 2024-10-20 03:10:02 +00:00
hurl-bot 9283dff948
Update crates 2024-10-19 03:05:58 +00:00
hurl-bot 7224a5e0ae
Update crates 2024-10-18 14:05:10 +00:00
Zikani Nyirenda Mwase f3091d9cb3
fix: add connect-timeout to options.lint.hurl 2024-10-18 08:51:43 +00:00
Zikani Nyirenda Mwase ba9e5b5b46
chore: add connect-timeout to integration test file for hurlfmt and hurl.grammar 2024-10-18 08:51:43 +00:00
Zikani Nyirenda Mwase d7fe2318c9
feat: add connect-timeout option per request
Added a connect-timeout option to allow users to specify a
connect-timeout for each request in a hurl file.

Closes #3163
2024-10-18 08:51:42 +00:00
hurl-bot 9f74004026
Update crates 2024-10-17 03:06:28 +00:00
Fabrice Reix 77c94004e8
Add test with --test and --repeat 2024-10-16 14:18:08 +02:00
hurl-bot 7f18216d7e
Update crates 2024-10-16 03:08:11 +00:00
fpinto 5a52728c8c
Fix powershell install in checks ci 2024-10-15 21:02:06 +02:00
fpinto deeaf020c0
Fix python venv in checks ci 2024-10-15 20:40:18 +02:00
Filipe PINTO 12dc0cdaeb
Disable PAM for sudo in Fedora ci 2024-10-15 20:30:34 +02:00
hurl-bot 5dbce19ba4
Update crates 2024-10-11 03:05:13 +00:00
hurl-bot 893c2dc937
Update actions 2024-10-10 04:00:42 +00:00
hurl-bot 4cf44ffe0c
Update crates 2024-10-09 03:06:03 +00:00
hurl-bot cb4206bef2
Update crates 2024-10-08 18:01:51 +00:00
hurl-bot 7e68faa1fb
Update actions 2024-10-08 04:00:35 +00:00
hurl-bot a80a4645a9
Update crates 2024-10-07 03:08:15 +00:00
Fabrice Reix 069c533276
Add test for not-equal in jsonpath filter 2024-10-05 13:29:29 +02:00
sandeshbhusal 395c2bc7ec
chore: cargo fmt + clippy 2024-10-05 09:56:53 +00:00
sandeshbhusal 3b843238a2
feat: Added not equl operator in jsonpath predicate 2024-10-05 09:56:52 +00:00
hurl-bot 625a0a3aad
Update actions 2024-10-05 04:00:41 +00:00
fpinto 949963cfc8
Fix integration/README.md and CONTRIBUTING.md prerequisites 2024-10-04 18:35:35 +02:00
hurl-bot a854201606
Update actions 2024-10-04 07:47:27 +00:00
hurl-bot 629c133762
Update crates 2024-10-04 03:06:08 +00:00
fpinto edcb67734b
Reorg ssl tests certs 2024-10-03 15:25:25 +02:00
fpinto 3a0033cf51
Reorg unix_socket tests files 2024-10-02 17:56:03 +02:00
fpinto 250bd54157
Fix letsencrypt test 2024-10-02 17:56:02 +02:00
fpinto 545ef6eb40
Fix ssl tests diffs between sh and ps1 scripts 2024-10-02 17:55:57 +02:00
fpinto 9027540376
Reorg integration tests dirs 2024-10-01 17:27:55 +02:00
fpinto 13e1e5649c
Fix sh vs ps1 test files 2024-10-01 17:27:54 +02:00
fpinto dd1c2ed5e2
Fix kebab case check 2024-10-01 17:27:53 +02:00
Filipe PINTO 1988aa817a
Add hurl commands check to diff sh and ps1 tests files 2024-10-01 17:27:48 +02:00
hurl-bot 8007988979
Update crates 2024-09-30 03:10:02 +00:00
hurl-bot 9d94720551
Update crates 2024-09-29 03:09:21 +00:00
Fabrice Reix 6957b9fa38
Update CHANGELOG 2024-09-28 19:29:31 +02:00
Fabrice Reix b896ffb938
Fix filename parsing (used by cert option) 2024-09-28 18:09:15 +02:00
Fabrice Reix e1100acbaf
Support case-insensitive Cookie Attributes 2024-09-28 14:14:03 +02:00
hurl-bot d9535fba89
Update actions 2024-09-27 04:00:32 +00:00
hurl-bot 2a2e737a00
Update crates 2024-09-26 03:06:26 +00:00
Fabrice Reix 4c48d57c8b
Add test integ for jsonpath bool filter 2024-09-24 09:07:08 +02:00
Fabrice Reix bd9678fbba
Update CHANGELOG 2024-09-24 09:07:07 +02:00
Jesús Vargas cd7bb24c3b
feature(jsonpath): adding possibility to filter by boolean 2024-09-24 05:41:08 +00:00
hurl-bot f2e1dd6f4f
Update crates 2024-09-21 03:02:36 +00:00
Jean-Christophe Amiel 860fbf4aa5
Update CHANGELOG. 2024-09-20 17:54:12 +02:00
Jean-Christophe Amiel c92df5a3dc
Add additional check on maximum response size.
This insures that --max-filesize works even if libcurl < 8.4.0 (see https://curl.se/docs/manpage.html#--max-filesize)
2024-09-20 16:58:45 +02:00
Jean-Christophe Amiel b0169379ae
Add additional check for --max-filesize integration test. 2024-09-20 15:50:31 +02:00
hurl-bot 07512a9cbf
Update crates 2024-09-20 03:03:38 +00:00
Jean-Christophe Amiel 3c1fbe572d
Implements short syntax for [Form], [Query], [Multipart]. 2024-09-19 10:08:18 +00:00
Jean-Christophe Amiel 087a45f208
Update grammar with [Query], [Form], [Multipart] 2024-09-19 10:08:17 +00:00
Mohammed Al Sahaf 55452d09cb
add mTLS options to Request documentation page 2024-09-19 12:15:53 +03:00
hurl-bot 7aeff6dae9
Update crates 2024-09-19 03:03:37 +00:00
Jean-Christophe Amiel d8924d5b5c
Update READMEs 2024-09-18 16:17:56 +02:00
Jean-Christophe Amiel ce2e2e9095
Add script for standalone Markdown generation. 2024-09-18 15:39:58 +02:00
hurl-bot 50a5b7567f
Update crates 2024-09-18 03:02:33 +00:00
hurl-bot 49e55913f4
Update crates 2024-09-17 03:02:43 +00:00
Fabrice Reix 298d0eea0c
Check that variables do not conflict with existing functions 2024-09-15 08:44:38 +02:00
hurl-bot d8dd240acf
Update crates 2024-09-14 09:39:37 +00:00
Jean-Christophe Amiel e9c33bd716
Update to Rust version 1.81 2024-09-14 11:01:46 +02:00
hurl-bot bd9d26e599
Update crates 2024-09-12 03:02:08 +00:00
hurl-bot 3849c720ea
Update hurl version to 6.0.0-SNAPSHOT 2024-09-11 13:35:35 +00:00
hurl-bot 1db27c92c5
Update crates 2024-09-09 03:03:41 +00:00
Fabrice Reix 5af5889b7f
Add functions in expression 2024-09-08 08:27:06 +00:00
hurl-bot 64b7e4cd22
Update crates 2024-09-08 03:03:20 +00:00
hurl-bot 56492a2519
Update crates 2024-09-06 03:02:40 +00:00
hurl-bot 32f142a251
Update crates 2024-09-05 03:01:58 +00:00
hurl-bot d50eb5695e
Update crates 2024-09-04 03:01:50 +00:00
Filipe PINTO 68cd6f215b
Add package-generic-linux-aarch64 to package github workflow 2024-09-03 10:13:38 +02:00
hurl-bot 1084170731
Update actions 2024-09-01 00:06:12 +00:00
hurl-bot 86c7929132
Update crates 2024-08-31 03:01:59 +00:00
Jean-Christophe Amiel 6bf371a05b
Update npm Hurl 5.0.1 package. 2024-08-30 16:13:55 +02:00
hurl-bot 8a6e9626e7
Create 5.0.1 release 2024-08-30 12:33:04 +00:00
Filipe PINTO f7b90b96dd
Use github download url for sha256 csv 2024-08-30 13:52:21 +02:00
Fabrice Reix 74081db93b
Set Release Date 2024-08-30 11:49:49 +02:00
Fabrice Reix 0aa544e59c
Check date in CHANGELOG 2024-08-30 11:49:25 +02:00
Filipe PINTO af36905521
Fix non interactive mode on install_prerequisites_ubuntu.sh 2024-08-29 15:13:47 +00:00
Jean-Christophe Amiel 93218e35ee
Update change log. 2024-08-29 16:53:32 +02:00
Jean-Christophe Amiel 062e2ab0f8
Fix regression in --output when output file doesn't exist. 2024-08-29 15:44:03 +02:00
Fabrice Reix 16b1e6b72d
Update doc RELEASING 2024-08-29 15:12:10 +02:00
hurl-bot 7ffca41abb
Update hurl version to 5.0.1-SNAPSHOT 2024-08-29 11:30:22 +00:00
Filipe PINTO bfceed782b
Fix push-to-winget token 2024-08-29 11:01:19 +02:00
Filipe PINTO c9225a1c52
Fix non interactive mode for package-generic-linux-aarch64 2024-08-29 10:38:46 +02:00
Filipe PINTO 0f4ce03652
Fix release sha256 csv format 2024-08-29 10:13:39 +02:00
2453 changed files with 115657 additions and 24851 deletions

View File

@ -1,46 +0,0 @@
version: 2.1
jobs:
test-ubuntu-arm64:
machine:
image: ubuntu-2004:current
resource_class: arm.medium
steps:
- checkout
- run:
name: Environment
command: |
bin/environment.sh
- run:
name: Install prerequisites
command: |
bin/install_prerequisites_ubuntu.sh
sudo apt update -qq
sudo apt install -y -qq libxml2-dev libxslt-dev libxml2-utils libcurl4-openssl-dev
- run:
name: Install rust
command: |
bin/install_rust.sh
- run:
name: Tests units
command: |
bin/test/test_prerequisites.sh
bin/test/test_unit.sh
- run:
name: Build release
command: |
bin/release/release.sh
- run:
name: Integration tests
command: |
PATH="${PWD}/target/release:${PATH}"
export PATH
bin/test/test_prerequisites.sh
bin/test/test_integ.sh
- store_artifacts:
path: integration/build/*.log
workflows:
tests-arm64:
jobs:
- test-ubuntu-arm64

View File

@ -67,8 +67,9 @@ jobs:
echo "base_ref=$(jq -rc .base.ref ${pr_detail_file})" | tee -a "${GITHUB_OUTPUT}" echo "base_ref=$(jq -rc .base.ref ${pr_detail_file})" | tee -a "${GITHUB_OUTPUT}"
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: ${{ env.BASE_REF }} ref: ${{ env.BASE_REF }}
token: ${{ secrets.HURL_BOT_TOKEN }} token: ${{ secrets.HURL_BOT_TOKEN }}
fetch-depth: 0 fetch-depth: 0
@ -87,7 +88,7 @@ jobs:
echo "ORDER=${order}" | tee -a "${GITHUB_ENV}" echo "ORDER=${order}" | tee -a "${GITHUB_ENV}"
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}
@ -287,21 +288,12 @@ jobs:
gh pr comment "${PR_NUMBER}" --body "${comment}" gh pr comment "${PR_NUMBER}" --body "${comment}"
exit 1 exit 1
fi fi
- name: Final comment
- name: Close pull request
if: ${{ github.event.comment.body == '/accept' || github.event.comment.body == '/accept --force' }} if: ${{ github.event.comment.body == '/accept' || github.event.comment.body == '/accept --force' }}
run: | run: |
if [[ "${PR_COMMENT}" =~ "--force" ]] ; then if [[ "${PR_COMMENT}" =~ "--force" ]] ; then
comment="✅ Pull request merged without waiting for checks and closed by \`${COMMENT_USER_LOGIN}\` with fast forward merge." comment="✅ Pull request merged with fast forward by \`${COMMENT_USER_LOGIN}\` without waiting for checks."
else else
comment="✅ Pull request merged and closed by \`${COMMENT_USER_LOGIN}\` with fast forward merge." comment="✅ Pull request merged with fast forward by \`${COMMENT_USER_LOGIN}\`."
fi
gh pr close "${PR_NUMBER}" --delete-branch --comment "${comment}.<br><br>\# List of commits merged from \`${{ env.HEAD_REPO_FULL_NAME}}/${{ env.HEAD_REF }}\` branch into \`${{ env.BASE_REPO_FULL_NAME}}/${{ env.BASE_REF }}\` branch:<br>$(echo ; sed "s/+/-/g" ${{ env.NEW_COMMITS_FILE }})" && exit_code=0 || exit_code=1
if [ ${exit_code} -eq 0 ] ; then
echo " - ${comment}"
else
comment="❌ A problem occurred when closing pull request and/or deleting branch."
echo " - ${comment}"
#gh pr comment "${PR_NUMBER}" --body "${comment} Please refer to ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID} logs."
#exit 1
fi fi
gh pr comment "${PR_NUMBER}" --body "${comment}.<br><br>\# List of commits merged from \`${{ env.HEAD_REPO_FULL_NAME}}/${{ env.HEAD_REF }}\` branch into \`${{ env.BASE_REPO_FULL_NAME}}/${{ env.BASE_REF }}\` branch:<br>$(echo ; sed 's/+/-/g' ${{ env.NEW_COMMITS_FILE }})"

View File

@ -17,7 +17,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with:
persist-credentials: false
- name: Auto close inactive PR - name: Auto close inactive PR
run: .github/workflows/bin/auto-close-inactive-pr.sh --github-project-path "${REPO}" --github-token "${GITHUB_TOKEN}" --max-days-of-inactivity 15 run: .github/workflows/bin/auto-close-inactive-pr.sh --github-project-path "${REPO}" --github-token "${GITHUB_TOKEN}" --max-days-of-inactivity 15

View File

@ -10,18 +10,25 @@ on:
required: true required: true
type: string type: string
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
jobs: jobs:
checks: checks:
runs-on: ubuntu-latest runs-on: ubuntu-24.04
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Shellcheck - name: Shellcheck
@ -44,22 +51,37 @@ jobs:
if: always() if: always()
run: bin/check/hadolint.sh ./contrib/docker/Dockerfile run: bin/check/hadolint.sh ./contrib/docker/Dockerfile
- name: Install Python 3.12
uses: actions/setup-python@v6.1.0
with:
python-version: '3.12'
- name: Install prerequisites - name: Install prerequisites
if: always() if: always()
run: | run: |
bin/check/install_prerequisites.sh bin/activate_python3_venv.sh
bin/install_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
python3 --version python3 --version
pip --version pip --version
bin/check/install_prerequisites.sh
- name: Zizmor
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: always()
run: |
pip install zizmor
bin/check/zizmor.sh --github-token ${GITHUB_TOKEN} .github/workflows/*.yml
- name: Check Rust version - name: Check Rust version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: always() if: always()
run: | run: |
python3 -m pip install requests --quiet python3 -m pip install requests --quiet
bin/check/rust_version.py 7 bin/check/rust_version.py --token ${GITHUB_TOKEN} 7
- name: Generated - name: Generated
if: always() if: always()
@ -73,9 +95,9 @@ jobs:
if: always() if: always()
run: bin/check/clippy.sh run: bin/check/clippy.sh
- name: Black - name: Ruff
if: always() if: always()
run: bin/check/black.sh run: bin/check/ruff.sh
- name: Check XML/HTML files - name: Check XML/HTML files
if: always() if: always()
@ -100,6 +122,13 @@ jobs:
if: always() if: always()
run: bin/check/doc.sh run: bin/check/doc.sh
- name: Check Valgrind
if: always()
run: |
sudo apt-get install -y valgrind
cargo install cargo-valgrind
bin/check/valgrind.sh
- name: Check completion files - name: Check completion files
if: always() if: always()
run: | run: |

View File

@ -1,8 +1,9 @@
name: coverage name: coverage
on: on:
schedule: push:
- cron: "0 8 * * *" branches:
- master
workflow_dispatch: workflow_dispatch:
env: env:
@ -16,31 +17,38 @@ jobs:
rust: [stable] rust: [stable]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with:
- name: Environment persist-credentials: false
run: bin/environment.sh
- name: Install Prerequisites - name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh run: bin/install_prerequisites_ubuntu.sh
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Tests prerequisites
run: bin/test/test_prerequisites.sh
- name: Install Rust - name: Install Rust
run: bin/install_rust.sh run: bin/install_rust.sh
- name: Install Grcov - name: Install Grcov
run: bin/install_grcov.sh run: bin/install_grcov.sh
- name: Environment
run: bin/environment.sh
- name: Build - name: Build
run: cargo build run: cargo build
- name: Test Prerequisites
run: bin/test/test_prerequisites.sh
- name: Run Coverage - name: Run Coverage
run: bin/coverage_run.sh run: bin/coverage_run.sh
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}
@ -60,7 +68,7 @@ jobs:
destination_dir: coverage destination_dir: coverage
- name: Archive Artifacts - name: Archive Artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: coverage name: coverage

View File

@ -1,135 +1,81 @@
name: extra-package name: extra-package
on: on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
set-release-version: set-release-version:
description: 'Desired release version (x.y.z)' description: 'Desired release version (x.y.z)'
required: true required: true
type: string type: string
push-to-chocolatey: push-to-chocolatey:
description: 'Push to chocolatey' description: 'Push to chocolatey'
type: boolean type: boolean
default: false default: false
push-to-winget: push-to-winget:
description: 'Push to winget' description: 'Push to winget'
type: boolean type: boolean
default: false default: false
package-generic-linux-aarch64:
description: 'Create generic linux aarch64 package' concurrency: extra-package
type: boolean
default: false jobs:
check-release:
concurrency: extra-package env:
GH_TOKEN: ${{ github.token }}
jobs: RELEASE_VERSION: ${{ github.event.inputs.set-release-version }}
check-release: name: Check-release
env: runs-on: ubuntu-latest
GH_TOKEN: ${{ github.token }} steps:
RELEASE_VERSION: ${{ github.event.inputs.set-release-version }} - name: Checkout repository
name: Check-release uses: actions/checkout@v6.0.1
runs-on: ubuntu-latest with:
steps: persist-credentials: true
- name: Checkout repository fetch-depth: 1
uses: actions/checkout@v4.1.7 ref: ${{ github.event.inputs.set-release-version }}
with: - name: Check if branch is a published release
fetch-depth: 1 run: |
ref: ${{ github.event.inputs.set-release-version }} if gh release list --exclude-drafts --exclude-pre-releases | grep -E "^${RELEASE_VERSION}" ; then
- name: Check if branch is a published release echo "✅ Desired release ${RELEASE_VERSION} is a published release"
run: | else
if gh release list --exclude-drafts --exclude-pre-releases | grep -E "^${RELEASE_VERSION}" ; then echo "❌ You have to run this workflow for a published release (excluding draft and pre-release), but the desired one [${RELEASE_VERSION}] is not."
echo "✅ Desired release ${RELEASE_VERSION} is a published release" exit 1
else fi
echo "❌ You have to run this workflow for a published release (excluding draft and pre-release), but the desired one [${RELEASE_VERSION}] is not."
exit 1 push-to-chocolatey:
fi if: github.event.inputs.push-to-chocolatey == 'true'
needs: check-release
push-to-chocolatey: env:
if: github.event.inputs.push-to-chocolatey == 'true' RELEASE_VERSION: ${{ github.event.inputs.set-release-version }}
needs: check-release CHOCOLATEY_TOKEN: ${{ secrets.LEPAPAREIL_CHOCOLATEY_TOKEN }}
env: name: Push to chocolatey
RELEASE_VERSION: ${{ github.event.inputs.set-release-version }} runs-on: windows-latest
CHOCOLATEY_TOKEN: ${{ secrets.LEPAPAREIL_CHOCOLATEY_TOKEN }} steps:
name: Push to chocolatey - name: Checkout repository
runs-on: windows-latest uses: actions/checkout@v6.0.1
steps: with:
- name: Checkout repository persist-credentials: false
uses: actions/checkout@v4.1.7 fetch-depth: 1
with: ref: ${{ github.event.inputs.set-release-version }}
fetch-depth: 1 - name: Push to chocolatey
ref: ${{ github.event.inputs.set-release-version }} run: .\bin\release\push_package_to_chocolatey.ps1 $env:RELEASE_VERSION $env:CHOCOLATEY_TOKEN
- name: Push to chocolatey
run: .\bin\release\push_package_to_chocolatey.ps1 $env:RELEASE_VERSION $env:CHOCOLATEY_TOKEN push-to-winget:
if: github.event.inputs.push-to-winget == 'true'
push-to-winget: needs: check-release
if: github.event.inputs.push-to-winget == 'true' env:
needs: check-release RELEASE_VERSION: ${{ github.event.inputs.set-release-version }}
env: WINGET_TOKEN: ${{ secrets.LEPAPAREIL_WINGET_TOKEN }}
RELEASE_VERSION: ${{ github.event.inputs.set-release-version }} name: Push to winget
WINGET_TOKEN: ${{ secrets.LEPAPAREIL_WINGET_TOKEN }} runs-on: windows-latest
name: Push to winget steps:
runs-on: windows-latest - name: Checkout repository
steps: uses: actions/checkout@v6.0.1
- name: Checkout repository with:
uses: actions/checkout@v4.1.7 persist-credentials: true
with: fetch-depth: 1
fetch-depth: 1 ref: ${{ github.event.inputs.set-release-version }}
ref: ${{ github.event.inputs.set-release-version }} - name: Push to winget
- name: Push to winget run: |
run: | Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile .\wingetcreate.exe
Invoke-WebRequest https://aka.ms/wingetcreate/latest -OutFile .\wingetcreate.exe .\wingetcreate.exe version
.\wingetcreate.exe version .\bin\release\push_package_to_winget.ps1 "$env:RELEASE_VERSION" "$env:WINGET_TOKEN"
.\bin\release\push_package_to_winget.ps1 "$env:RELEASE_VERSION" "$env:WINGET_TOKEN"
package-generic-linux-aarch64:
if: github.event.inputs.package-generic-linux-aarch64 == 'true'
needs: check-release
name: Create generic linux aarch64 package
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.7
with:
fetch-depth: 1
ref: ${{ github.event.inputs.set-release-version }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3.2.0
- name: Create package
uses: addnab/docker-run-action@v3
with:
image: ubuntu:22.04
options: --platform linux/arm64/v8 --volume ${{ github.workspace }}:/work --workdir /work --privileged --env CARGO_TERM_COLOR=always --env CARGO_BUILD_TARGET=aarch64-unknown-linux-gnu
run: |
set -e
echo "::group::Install Prerequisites"
bin/install_prerequisites_ubuntu.sh
sudo apt-get install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross
./bin/export_cross_compile_env.sh
echo "::endgroup::"
echo "::group::Install Rust"
bin/install_rust.sh
. "$HOME/.cargo/env"
echo "::endgroup::"
echo "::group::Environment"
bin/environment.sh
echo "::endgroup::"
echo "::group::Build"
./bin/release/release.sh
cp -frp target/$CARGO_BUILD_TARGET/release/hurl ./target/release/
cp -frp target/$CARGO_BUILD_TARGET/release/hurlfmt ./target/release/
echo "::endgroup::"
echo "::group::Get version"
export VERSION=$(bin/release/get_version.sh)
echo "::endgroup::"
echo "::group::Create man"
bin/release/man.sh
echo "::endgroup::"
echo "::group::Create tarball"
bin/release/create_tarball.sh
bin/release/sha256sum.sh --write target/upload/hurl-$VERSION-aarch64-unknown-linux-gnu.tar.gz
echo "::endgroup::"
- name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6
with:
name: release-generic-linux-aarch64-artifacts
path: target/upload/*

View File

@ -11,33 +11,42 @@ on:
required: true required: true
type: string type: string
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
jobs: jobs:
package-generic-linux-x64: package-generic-linux-x64:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Python 3.10 - name: Install prerequisites
uses: actions/setup-python@v5.1.1 run: bin/install_prerequisites_ubuntu.sh
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with: with:
python-version: '3.10' python-version: '3.11'
- name: Install python3 venv - name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
python3 --version python3 --version
pip --version pip --version
- name: Install - name : Environment
run: | run: bin/environment.sh
bin/install_prerequisites_ubuntu.sh - name: Install rust
bin/install_rust.sh run: bin/install_rust.sh
- name: Build - name: Build
run: | run: |
bin/release/release.sh bin/release/release.sh
@ -51,7 +60,7 @@ jobs:
bin/release/man.sh bin/release/man.sh
bin/release/create_tarball.sh bin/release/create_tarball.sh
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-generic-linux-x64-artifacts name: release-generic-linux-x64-artifacts
path: target/upload/* path: target/upload/*
@ -61,46 +70,49 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Retrieve release-generic-linux-x64-artifacts - name: Retrieve release-generic-linux-x64-artifacts
uses: actions/download-artifact@v4.1.8 uses: actions/download-artifact@v7.0.0
with: with:
name: release-generic-linux-x64-artifacts name: release-generic-linux-x64-artifacts
path: target/upload path: target/upload
- name: Install package and tests integ - name: Install package and tests integ
uses: addnab/docker-run-action@v3 uses: addnab/docker-run-action@v3
with: with:
image: ubuntu image: ubuntu:22.04
options: --volume ${{ github.workspace }}:/work --workdir /work --privileged options: --volume ${{ github.workspace }}:/work --workdir /work --privileged
run: | run: |
set -e set -e
echo "::group::Install system prerequisites" echo "::group::Install Prerequisites"
bin/install_prerequisites_ubuntu.sh bin/install_prerequisites_ubuntu.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Install python 3.11"
bin/install_python3_venv.sh bin/install_pythonx_for_ubuntu.sh 11
bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 echo "::endgroup::"
python3 --version echo "::group::Install Rust"
pip --version bin/install_rust.sh
. "$HOME/.cargo/env"
echo "::endgroup::" echo "::endgroup::"
echo "::group::Environment" echo "::group::Environment"
bin/environment.sh bin/environment.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install generic linux package" echo "::group::Install generic linux package"
bin/release/install_generic_linux_package.sh bin/release/install_generic_linux_package.sh
export PATH="/tmp/hurl-generic-linux/bin:$PATH" export PATH="/tmp/hurl-generic-linux/bin:$PATH"
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install tests prerequisites" echo "::group::Install tests integ prerequisistes"
bin/test/test_prerequisites.sh bin/test/test_prerequisites.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Tests" echo "::group::Tests"
bin/test/test_integ.sh bin/test/test_integ.sh
echo "::endgroup::" echo "::endgroup::"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-generic-linux-package-docker-ubuntu-x64-artifacts name: test-generic-linux-package-docker-ubuntu-x64-artifacts
@ -112,11 +124,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Retrieve release-generic-linux-x64-artifacts - name: Retrieve release-generic-linux-x64-artifacts
uses: actions/download-artifact@v4.1.8 uses: actions/download-artifact@v7.0.0
with: with:
name: release-generic-linux-x64-artifacts name: release-generic-linux-x64-artifacts
path: target/upload path: target/upload
@ -128,10 +141,10 @@ jobs:
run: | run: |
set -e set -e
echo "::group::Install system prerequisites" echo "::group::Install system prerequisites"
bin/install_prerequisites_ubuntu.sh bin/install_prerequisites_debian.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Activate python3 venv"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -151,7 +164,7 @@ jobs:
bin/test/test_integ.sh bin/test/test_integ.sh
echo "::endgroup::" echo "::endgroup::"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-generic-linux-package-docker-debian-x64-artifacts name: test-generic-linux-package-docker-debian-x64-artifacts
@ -163,11 +176,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Retrieve release-generic-linux-x64-artifacts - name: Retrieve release-generic-linux-x64-artifacts
uses: actions/download-artifact@v4.1.8 uses: actions/download-artifact@v7.0.0
with: with:
name: release-generic-linux-x64-artifacts name: release-generic-linux-x64-artifacts
path: target/upload path: target/upload
@ -176,13 +190,24 @@ jobs:
with: with:
image: archlinux image: archlinux
options: --volume ${{ github.workspace }}:/work --workdir /work --privileged options: --volume ${{ github.workspace }}:/work --workdir /work --privileged
# Revert to libxml 2.13.8 that has a soname libxml2.so.2 required by our Ubuntu Hurl build (using `libxml2-legacy` package).
# Starting from libxml 2.14, <https://gitlab.gnome.org/GNOME/libxml2/-/releases/v2.14.0>:
#
# > Binary compatibility is restricted to versions 2.14 or newer. On ELF systems, the soname was bumped from
# > libxml2.so.2 to libxml2.so.16.
#
# We downgrade when testing the Hurl generic package, not when we're building the Hurl package on Arch Linux as the soname
# problem arise only with the generic package.
run: | run: |
set -e set -e
echo "::group::Install system prerequisites" echo "::group::Install system prerequisites"
bin/install_prerequisites_archlinux.sh bin/install_prerequisites_archlinux.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Downgrade libxml2"
bin/install_python3_venv.sh pacman --sync --noconfirm libxml2-legacy
echo "::endgroup::"
echo "::group::Activate python3 venv"
bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -202,7 +227,7 @@ jobs:
bin/test/test_integ.sh bin/test/test_integ.sh
echo "::endgroup::" echo "::endgroup::"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-generic-linux-package-docker-archlinux-x64-artifacts name: test-generic-linux-package-docker-archlinux-x64-artifacts
@ -214,11 +239,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Retrieve release-generic-linux-x64-artifacts - name: Retrieve release-generic-linux-x64-artifacts
uses: actions/download-artifact@v4.1.8 uses: actions/download-artifact@v7.0.0
with: with:
name: release-generic-linux-x64-artifacts name: release-generic-linux-x64-artifacts
path: target/upload path: target/upload
@ -229,11 +255,14 @@ jobs:
options: --volume ${{ github.workspace }}:/work --workdir /work --privileged options: --volume ${{ github.workspace }}:/work --workdir /work --privileged
run: | run: |
set -e set -e
echo "::group::Disable PAM for sudo with root and no tty"
bin/disable_pam_for_sudo.sh
echo "::endgroup::"
echo "::group::Install system prerequisites" echo "::group::Install system prerequisites"
bin/install_prerequisites_fedora.sh bin/install_prerequisites_fedora.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Activate python3 venv"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -253,22 +282,23 @@ jobs:
bin/test/test_integ.sh bin/test/test_integ.sh
echo "::endgroup::" echo "::endgroup::"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-generic-linux-package-docker-fedora-x64-artifacts name: test-generic-linux-package-docker-fedora-x64-artifacts
path: | path: |
./**/*.log ./**/*.log
test-docker-x64-packages: test-dockerfile-x64:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.6.1 uses: docker/setup-buildx-action@v3.11.1
- name: Build docker images - name: Build docker images
run: | run: |
echo "::group::Docker build prerequisites" echo "::group::Docker build prerequisites"
@ -306,7 +336,7 @@ jobs:
bash bin/install_prerequisites_alpine.sh bash bin/install_prerequisites_alpine.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install tests prerequisites" echo "::group::Install tests prerequisites"
bash bin/install_python3_venv.sh bash bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -319,34 +349,87 @@ jobs:
echo "::group::Integration tests" echo "::group::Integration tests"
bash bin/test/test_integ.sh bash bin/test/test_integ.sh
echo "::endgroup::" echo "::endgroup::"
- name: find artifacts - name: Find artifacts
run: | run: |
pwd pwd
find . -name "*.log" find . -name "*.log"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: test-docker-amd64-package-artifacts name: test-docker-amd64-package-artifacts
path: | path: |
./**/*.log ./**/*.log
package-deb-x64: package-generic-linux-aarch64:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04-arm
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Python 3.10 - name: Install prerequisites
uses: actions/setup-python@v5.1.1 run: bin/install_prerequisites_ubuntu.sh
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with: with:
python-version: '3.10' python-version: '3.11'
- name: Activate python3 venv
run: |
bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV
which python3
python3 --version
pip --version
- name : Environment
run: bin/environment.sh
- name: Install rust
run: bin/install_rust.sh
- name: Build
run: |
bin/release/release.sh
echo "PATH=:${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Get version
run: |
VERSION=$(bin/release/get_version.sh)
echo "VERSION=${VERSION}" | tee -a "${GITHUB_ENV}"
- name: Create generic linux package
run: |
bin/release/man.sh
bin/release/create_tarball.sh
- name: Install generic linux package
run: |
bin/release/install_generic_linux_package.sh
export PATH="/tmp/hurl-generic-linux/bin:$PATH"
- name: Test integ
run: |
bin/test/test_prerequisites.sh
bin/test/test_integ.sh
- name: Archive production artifacts
uses: actions/upload-artifact@v6.0.0
with:
name: release-generic-linux-aarch64-artifacts
path: target/upload/*
package-deb-x64:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.1
with:
persist-credentials: false
ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh run: bin/install_prerequisites_ubuntu.sh
- name: Install python3 venv - name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
@ -377,25 +460,78 @@ jobs:
bin/test/test_prerequisites.sh bin/test/test_prerequisites.sh
bin/test/test_integ.sh bin/test/test_integ.sh
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-deb-x64-artifacts name: release-deb-x64-artifacts
path: target/upload/* path: target/upload/*
package-macos-x64: package-deb-aarch64:
runs-on: macos-13 runs-on: ubuntu-22.04-arm
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }}
- name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Activate python3 venv
run: |
bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV
which python3
python3 --version
pip --version
- name: Install Rust
run: bin/install_rust.sh
- name: Environment
run: bin/environment.sh
- name: Build
run: |
bin/release/release.sh
echo "PATH=:${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Get version
run: |
VERSION=$(bin/release/get_version.sh)
echo "VERSION=${VERSION}" | tee -a "${GITHUB_ENV}"
- name: Create deb package
run: |
bin/release/man.sh
bin/release/create_deb_package.sh
- name: Install package
run: |
bin/release/install_deb_package.sh
echo "PATH=/tmp/hurl-deb-package/usr/bin:$PATH" >> "${GITHUB_ENV}"
- name: Test integ
run: |
bin/test/test_prerequisites.sh
bin/test/test_integ.sh
- name: Archive production artifacts
uses: actions/upload-artifact@v6.0.0
with:
name: release-deb-aarch64-artifacts
path: target/upload/*
package-macos-x64:
runs-on: macos-15-intel
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.1
with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: | run: |
bin/install_prerequisites_macos.sh bin/install_prerequisites_macos.sh
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
- name: Install python3 venv - name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
@ -426,25 +562,26 @@ jobs:
bin/test/test_prerequisites.sh bin/test/test_prerequisites.sh
bin/test/test_integ.sh bin/test/test_integ.sh
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-macos-x64-artifacts name: release-macos-x64-artifacts
path: target/upload/* path: target/upload/*
package-macos-aarch64: package-macos-aarch64:
runs-on: macos-14 runs-on: macos-15
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: | run: |
bin/install_prerequisites_macos.sh bin/install_prerequisites_macos.sh
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
- name: Install python3 venv - name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
@ -475,44 +612,49 @@ jobs:
bin/test/test_prerequisites.sh bin/test/test_prerequisites.sh
bin/test/test_integ.sh bin/test/test_integ.sh
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-macos-aarch64-artifacts name: release-macos-aarch64-artifacts
path: target/upload/* path: target/upload/*
package-windows-x64: package-windows-x64:
runs-on: windows-latest runs-on: windows-latest
env:
VCPKGRS_DYNAMIC: 1
steps: steps:
- name: Set git to use LF - name: Set git to use LF
run: | run: |
git config --global core.autocrlf false git config --global core.autocrlf false
git config --global core.eol lf git config --global core.eol lf
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Rust - name: Install Rust
run: | run: |
.\bin\install_rust.ps1 .\bin\install_rust.ps1
- name: Manage vcpkg cache - name: Manage vcpkg cache
uses: actions/cache@v4.0.2 uses: actions/cache@v5.0.1
with: with:
path: C:\vcpkg path: C:\vcpkg
key: ${{ runner.os }}-release-windows-x64 key: ${{ runner.os }}-release-windows-x64
- name: Environment
run: .\bin\environment.ps1
- name: Install prerequisites - name: Install prerequisites
run: .\bin\install_prerequisites_windows.ps1 run: .\bin\install_prerequisites_windows.ps1
- name: Build - name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Environment
run: | run: |
.\bin\release\release.ps1 .\bin\activate_python3_venv.ps1
.\bin\environment.ps1
- name: Build
run: .\bin\release\release.ps1
- name: Create windows64 Zip package - name: Create windows64 Zip package
run: .\bin\release\create_windows64_zip_package.ps1 run: .\bin\release\create_windows64_zip_package.ps1
- name: Install win64 zip and test integ - name: Install win64 zip and test integ
run: | run: |
.\bin\release\install_windows64_zip_package.ps1 .\bin\release\install_windows64_zip_package.ps1
.\bin\activate_python3_venv.ps1
.\bin\test\test_prerequisites.ps1 .\bin\test\test_prerequisites.ps1
.\bin\test\test_integ.ps1 .\bin\test\test_integ.ps1
- name: Create windows64 installer - name: Create windows64 installer
@ -520,10 +662,11 @@ jobs:
- name: Install win64 installer and test integ - name: Install win64 installer and test integ
run: | run: |
.\bin\release\install_windows64_installer.ps1 .\bin\release\install_windows64_installer.ps1
.\bin\activate_python3_venv.ps1
.\bin\test\test_prerequisites.ps1 .\bin\test\test_prerequisites.ps1
.\bin\test\test_integ.ps1 .\bin\test\test_integ.ps1
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-windows-x64-artifacts name: release-windows-x64-artifacts
path: | path: |
@ -533,7 +676,9 @@ jobs:
package-anatomy: package-anatomy:
needs: needs:
- package-generic-linux-x64 - package-generic-linux-x64
- package-generic-linux-aarch64
- package-deb-x64 - package-deb-x64
- package-deb-aarch64
- package-macos-x64 - package-macos-x64
- package-macos-aarch64 - package-macos-aarch64
- package-windows-x64 - package-windows-x64
@ -541,10 +686,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- uses: actions/download-artifact@v4.1.8 - uses: actions/download-artifact@v7.0.0
with: with:
path: artifacts path: artifacts
- name: Prerequisites - name: Prerequisites
@ -553,9 +699,15 @@ jobs:
- name: Package generic linux x64 anatomy - name: Package generic linux x64 anatomy
if: ${{ always() }} if: ${{ always() }}
run: bin/release/package-anatomy.sh artifacts/release-generic-linux-x64-artifacts/hurl-*-x86_64-unknown-linux-gnu.tar.gz --compare-with-dir docs/spec/packages run: bin/release/package-anatomy.sh artifacts/release-generic-linux-x64-artifacts/hurl-*-x86_64-unknown-linux-gnu.tar.gz --compare-with-dir docs/spec/packages
- name: Package generic linux aarch64 anatomy
if: ${{ always() }}
run: bin/release/package-anatomy.sh artifacts/release-generic-linux-aarch64-artifacts/hurl-*-aarch64-unknown-linux-gnu.tar.gz --compare-with-dir docs/spec/packages
- name: Package deb x64 anatomy - name: Package deb x64 anatomy
if: ${{ always() }} if: ${{ always() }}
run: bin/release/package-anatomy.sh artifacts/release-deb-x64-artifacts/hurl_*_amd64.deb --compare-with-dir docs/spec/packages run: bin/release/package-anatomy.sh artifacts/release-deb-x64-artifacts/hurl_*_amd64.deb --compare-with-dir docs/spec/packages
- name: Package deb aarch64 anatomy
if: ${{ always() }}
run: bin/release/package-anatomy.sh artifacts/release-deb-aarch64-artifacts/hurl_*_arm64.deb --compare-with-dir docs/spec/packages
- name: Package macos x64 anatomy - name: Package macos x64 anatomy
if: ${{ always() }} if: ${{ always() }}
run: bin/release/package-anatomy.sh artifacts/release-macos-x64-artifacts/hurl-*-x86_64-apple-darwin.tar.gz --compare-with-dir docs/spec/packages run: bin/release/package-anatomy.sh artifacts/release-macos-x64-artifacts/hurl-*-x86_64-apple-darwin.tar.gz --compare-with-dir docs/spec/packages

View File

@ -13,8 +13,10 @@ concurrency: release
jobs: jobs:
set-context: set-context:
env: env:
GITHUB_BRANCH_NAME: ${{ github.ref_name }}
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }}
SET_RELEASE_VERSION: ${{ github.event.inputs.set-release-version }}
outputs: outputs:
release_version: ${{ steps.set-release-version.outputs.release_version }} release_version: ${{ steps.set-release-version.outputs.release_version }}
release_branch: ${{ steps.set-release-branch.outputs.release_branch }} release_branch: ${{ steps.set-release-branch.outputs.release_branch }}
@ -23,25 +25,25 @@ jobs:
steps: steps:
- name: Check trigger branch - name: Check trigger branch
run: | run: |
if [ $(echo "${{ github.ref_name }}" | grep -Ec "^master$|^release/") -eq 1 ] ; then if [ $(echo "${GITHUB_BRANCH_NAME}" | grep -Ec "^master$|^release/") -eq 1 ] ; then
echo " - ✅ The branch triggering this workflow is ${{ github.ref_name }}." echo " - ✅ The branch triggering this workflow is ${GITHUB_BRANCH_NAME}."
else else
echo " - ❌ The branch triggering this workflow is ${{ github.ref_name }} instead of master or release/[0-9].[0-9].[0-9]." echo " - ❌ The branch triggering this workflow is ${GITHUB_BRANCH_NAME} instead of master or release/[0-9].[0-9].[0-9]."
exit 1 exit 1
fi fi
- name: Set release version - name: Set release version
id: set-release-version id: set-release-version
run: | run: |
echo "release_version=${{ github.event.inputs.set-release-version }}" | tee -a $GITHUB_OUTPUT echo "release_version=${SET_RELEASE_VERSION}" | tee -a $GITHUB_OUTPUT
- name: Set release branch - name: Set release branch
id: set-release-branch id: set-release-branch
run: | run: |
if [ $(echo "${{ github.ref_name }}" | grep -c "^release/") -eq 1 ] ; then if [ $(echo "${GITHUB_BRANCH_NAME}" | grep -c "^release/") -eq 1 ] ; then
echo "release_branch=${{ github.ref_name }}" | tee -a $GITHUB_OUTPUT echo "release_branch=${GITHUB_BRANCH_NAME}" | tee -a $GITHUB_OUTPUT
else else
echo "release_branch=release/${{ github.event.inputs.set-release-version }}" | tee -a $GITHUB_OUTPUT echo "release_branch=release/${SET_RELEASE_VERSION}" | tee -a $GITHUB_OUTPUT
fi fi
clean-release: clean-release:
@ -53,7 +55,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with:
persist-credentials: true
- name: Check release pull request existence - name: Check release pull request existence
id: check-release-pull-request-existence id: check-release-pull-request-existence
@ -169,7 +173,9 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
if: github.ref_name == 'master' if: github.ref_name == 'master'
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with:
persist-credentials: true
- name: Create release branch - name: Create release branch
if: github.ref_name == 'master' if: github.ref_name == 'master'
@ -185,8 +191,9 @@ jobs:
fi fi
- name: Checkout new release branch - name: Checkout new release branch
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: ${{ needs.set-context.outputs.release_branch }} ref: ${{ needs.set-context.outputs.release_branch }}
- name: Check CHANGELOG - name: Check CHANGELOG
@ -234,7 +241,7 @@ jobs:
python3 bin/docs/build_readme.py crates > packages/hurl/README.md python3 bin/docs/build_readme.py crates > packages/hurl/README.md
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}
@ -260,7 +267,7 @@ jobs:
fi fi
- name: Archive artifacts - name: Archive artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: release-changelog name: release-changelog
@ -279,9 +286,12 @@ jobs:
deliver-github-release: deliver-github-release:
env: env:
GITHUB_BRANCH_NAME: ${{ github.ref_name }}
GITHUB_OWNER: ${{ github.repository_owner }}
GITHUB_REPO_NAME: ${{ github.event.repository.name }}
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }}
REPO: ${{ github.repository }} RELEASE_VERSION: ${{ needs.set-context.outputs.release_version }}
needs: needs:
- set-context - set-context
- clean-release - clean-release
@ -291,12 +301,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout new release branch - name: Checkout new release branch
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: ${{ needs.set-context.outputs.release_branch }} ref: ${{ needs.set-context.outputs.release_branch }}
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}
@ -305,40 +316,42 @@ jobs:
git_user_signingkey: true git_user_signingkey: true
git_commit_gpgsign: true git_commit_gpgsign: true
- uses: actions/download-artifact@v4.1.8 - uses: actions/download-artifact@v7.0.0
with: with:
path: artifacts path: artifacts
- name: Push tag - name: Push tag
run: | run: |
git tag -a ${{ needs.set-context.outputs.release_version }} -m "Release ${{ needs.set-context.outputs.release_version }}" git tag -a "${RELEASE_VERSION}" -m "Release ${RELEASE_VERSION}"
git tag -n git tag -n
git push --tags && git_exit_code=0 || git_exit_code=$? git push --tags && git_exit_code=0 || git_exit_code=$?
if [ ${git_exit_code} -eq 0 ] ; then if [ ${git_exit_code} -eq 0 ] ; then
echo " - ✅ ${{ needs.set-context.outputs.release_version }} tag created." echo " - ✅ ${RELEASE_VERSION} tag created."
git fetch git fetch
else else
echo " - ❌ A problem occurs when attempting to create ${{ needs.set-context.outputs.release_version }} tag." echo " - ❌ A problem occurs when attempting to create ${RELEASE_VERSION} tag."
exit 1 exit 1
fi fi
- name: Create sha256sums - name: Create sha256sums
run: | run: |
bin/release/sha256sum.sh --write \ bin/release/sha256sum.sh --write \
artifacts/release-deb-x64-artifacts/hurl_"${{ needs.set-context.outputs.release_version }}"_amd64.deb \ artifacts/release-deb-x64-artifacts/hurl_"${RELEASE_VERSION}"_amd64.deb \
artifacts/release-generic-linux-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-unknown-linux-gnu.tar.gz \ artifacts/release-deb-aarch64-artifacts/hurl_"${RELEASE_VERSION}"_arm64.deb \
artifacts/release-macos-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-apple-darwin.tar.gz \ artifacts/release-generic-linux-x64-artifacts/hurl-"${RELEASE_VERSION}"-x86_64-unknown-linux-gnu.tar.gz \
artifacts/release-macos-aarch64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-aarch64-apple-darwin.tar.gz \ artifacts/release-generic-linux-aarch64-artifacts/hurl-"${RELEASE_VERSION}"-aarch64-unknown-linux-gnu.tar.gz \
artifacts/release-windows-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-pc-windows-msvc-installer.exe \ artifacts/release-macos-x64-artifacts/hurl-"${RELEASE_VERSION}"-x86_64-apple-darwin.tar.gz \
artifacts/release-windows-x64-artifacts/hurl-"${{ needs.set-context.outputs.release_version }}"-x86_64-pc-windows-msvc.zip artifacts/release-macos-aarch64-artifacts/hurl-"${RELEASE_VERSION}"-aarch64-apple-darwin.tar.gz \
echo "file sha256" > ${{ needs.set-context.outputs.release_version }}.sha256.csv artifacts/release-windows-x64-artifacts/hurl-"${RELEASE_VERSION}"-x86_64-pc-windows-msvc-installer.exe \
find ./artifacts -name "*sha256" | xargs -I FILE sh -c 'echo "$(basename FILE) $(cat FILE)"' >> ${{ needs.set-context.outputs.release_version }}.sha256.csv artifacts/release-windows-x64-artifacts/hurl-"${RELEASE_VERSION}"-x86_64-pc-windows-msvc.zip
echo "file,sha256" > release-"${RELEASE_VERSION}".sha256.csv
find ./artifacts -name "*sha256" | xargs -I FILE sh -c 'echo "https://github.com/${GITHUB_OWNER}/${GITHUB_REPO_NAME}/releases/download/${RELEASE_VERSION}/$(basename FILE),$(cat FILE)"' >> release-"${RELEASE_VERSION}".sha256.csv
- name: Archive sha256 artifacts - name: Archive sha256 artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
with: with:
name: release-sha256-csv name: release-sha256-csv
path: ${{ needs.set-context.outputs.release_version }}.sha256.csv path: release-${{ needs.set-context.outputs.release_version }}.sha256.csv
- name: Deliver release - name: Deliver release
@ -352,7 +365,9 @@ jobs:
echo "::group::List artifacts" echo "::group::List artifacts"
ls -l \ ls -l \
artifacts/release-deb-x64-artifacts/* \ artifacts/release-deb-x64-artifacts/* \
artifacts/release-deb-aarch64-artifacts/* \
artifacts/release-generic-linux-x64-artifacts/* \ artifacts/release-generic-linux-x64-artifacts/* \
artifacts/release-generic-linux-aarch64-artifacts/* \
artifacts/release-macos-x64-artifacts/* \ artifacts/release-macos-x64-artifacts/* \
artifacts/release-macos-aarch64-artifacts/* \ artifacts/release-macos-aarch64-artifacts/* \
artifacts/release-windows-x64-artifacts/* artifacts/release-windows-x64-artifacts/*
@ -365,8 +380,12 @@ jobs:
--draft \ --draft \
artifacts/release-deb-x64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_amd64.deb \ artifacts/release-deb-x64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_amd64.deb \
artifacts/release-deb-x64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_amd64.deb.sha256 \ artifacts/release-deb-x64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_amd64.deb.sha256 \
artifacts/release-deb-aarch64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_arm64.deb \
artifacts/release-deb-aarch64-artifacts/hurl_${{ needs.set-context.outputs.release_version }}_arm64.deb.sha256 \
artifacts/release-generic-linux-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-unknown-linux-gnu.tar.gz \ artifacts/release-generic-linux-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-unknown-linux-gnu.tar.gz \
artifacts/release-generic-linux-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-unknown-linux-gnu.tar.gz.sha256 \ artifacts/release-generic-linux-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-unknown-linux-gnu.tar.gz.sha256 \
artifacts/release-generic-linux-aarch64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-aarch64-unknown-linux-gnu.tar.gz \
artifacts/release-generic-linux-aarch64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-aarch64-unknown-linux-gnu.tar.gz.sha256 \
artifacts/release-macos-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-apple-darwin.tar.gz \ artifacts/release-macos-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-apple-darwin.tar.gz \
artifacts/release-macos-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-apple-darwin.tar.gz.sha256 \ artifacts/release-macos-x64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-x86_64-apple-darwin.tar.gz.sha256 \
artifacts/release-macos-aarch64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-aarch64-apple-darwin.tar.gz \ artifacts/release-macos-aarch64-artifacts/hurl-${{ needs.set-context.outputs.release_version }}-aarch64-apple-darwin.tar.gz \
@ -392,13 +411,12 @@ jobs:
- name: Create new pull request - name: Create new pull request
run: | run: |
GITHUB_TOKEN=${{ secrets.HURL_BOT_TOKEN }}
{ {
echo "⚠ This is a GitHub releasing PR." echo "⚠ This is a GitHub releasing PR."
echo "- Please use \`/accept\` as usual then run the \`update-branch-version\` github workflow if you want to automatically update master branch to next SNAPSHOT version" echo "- Please use \`/accept\` as usual then run the \`update-branch-version\` github workflow if you want to automatically update master branch to next SNAPSHOT version"
} > file-body.txt } > file-body.txt
gh pr create \ gh pr create \
--title "Merge GitHub ${{ needs.set-context.outputs.release_branch }} into ${{ github.ref_name }}" \ --title "Merge GitHub ${{ needs.set-context.outputs.release_branch }} into master" \
--body-file file-body.txt \ --body-file file-body.txt \
--base master \ --base master \
--label bot && gh_exit_code=0 || gh_exit_code=$? --label bot && gh_exit_code=0 || gh_exit_code=$?

View File

@ -11,6 +11,12 @@ on:
required: true required: true
type: string type: string
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@ -19,19 +25,20 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh run: bin/install_prerequisites_ubuntu.sh
- name: Install python3 venv - name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV
which python3
python3 --version
pip --version
- name: Install Rust - name: Install Rust
run: bin/install_rust.sh run: bin/install_rust.sh
- name: Environment - name: Environment
@ -41,13 +48,32 @@ jobs:
bin/release/release.sh bin/release/release.sh
echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}" echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Archive artifacts - name: Archive artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-bench-artifacts name: tests-bench-artifacts
path: | path: |
bench/server.log bench/server.log
coverage:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.1
with:
persist-credentials: false
ref: ${{ inputs.branch }}
- name: Install Rust
run: bin/install_rust.sh
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Environment
run: bin/environment.sh
- name: Coverage
run: bin/check/coverage.sh
test-ubuntu-x64-latest: test-ubuntu-x64-latest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@ -55,23 +81,21 @@ jobs:
rust: [stable] rust: [stable]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Python 3.10
uses: actions/setup-python@v5.1.1
with:
python-version: '3.10'
- name: Install Prerequisites - name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh run: bin/install_prerequisites_ubuntu.sh
- name: Install python3 venv - name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3
python3 --version
pip --version
- name: Install Rust - name: Install Rust
run: bin/install_rust.sh run: bin/install_rust.sh
- name: Environment - name: Environment
@ -85,10 +109,18 @@ jobs:
echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}" echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Integration Tests - name: Integration Tests
run: bin/test/test_integ.sh run: bin/test/test_integ.sh
- name: Coverage - name: Integration Tests (Hurl files using CRLF)
run: bin/check/coverage.sh run: |
sudo apt update
sudo apt install -y dos2unix
current_dir="${PWD}"
tmp_dir=/tmp/hurl-tmp
bin/test/convert_hurl_to_crlf.sh --dest-dir "${tmp_dir}"
cd "${tmp_dir}"
bin/test/test_integ.sh || true
cd "${current_dir}"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-ubuntu-latest-${{ matrix.rust }}-artifacts name: tests-ubuntu-latest-${{ matrix.rust }}-artifacts
@ -97,30 +129,28 @@ jobs:
./**/report/*.json ./**/report/*.json
./**/report/*.xml ./**/report/*.xml
test-ubuntu-x64-20-04: test-ubuntu-x64-22-04:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
rust: [stable] rust: [stable]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Python 3.10
uses: actions/setup-python@v5.1.1
with:
python-version: '3.10'
- name: Install Prerequisites - name: Install Prerequisites
run: bin/install_prerequisites_ubuntu.sh run: bin/install_prerequisites_ubuntu.sh
- name: Install python3 venv - name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3
python3 --version
pip --version
- name: Install Rust - name: Install Rust
run: bin/install_rust.sh run: bin/install_rust.sh
- name: Environment - name: Environment
@ -135,10 +165,10 @@ jobs:
- name: Integration Tests - name: Integration Tests
run: bin/test/test_integ.sh run: bin/test/test_integ.sh
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-ubuntu-20.04-${{ matrix.rust }}-artifacts name: tests-ubuntu-22.04-${{ matrix.rust }}-artifacts
path: | path: |
./**/*.log ./**/*.log
./**/report/*.json ./**/report/*.json
@ -148,8 +178,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Build, Test units and Integration tests - name: Build, Test units and Integration tests
uses: addnab/docker-run-action@v3 uses: addnab/docker-run-action@v3
@ -161,8 +192,8 @@ jobs:
echo "::group::Install Prerequisites" echo "::group::Install Prerequisites"
bin/install_prerequisites_archlinux.sh bin/install_prerequisites_archlinux.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Activate python3 venv"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -178,7 +209,7 @@ jobs:
bin/test/test.sh bin/test/test.sh
echo "::endgroup::" echo "::endgroup::"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-archlinux-x64-artifacts name: tests-archlinux-x64-artifacts
@ -189,8 +220,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Build, Test units and Integration tests - name: Build, Test units and Integration tests
uses: addnab/docker-run-action@v3 uses: addnab/docker-run-action@v3
@ -199,11 +231,14 @@ jobs:
options: --volume ${{ github.workspace }}:/work --workdir /work --privileged --env CARGO_TERM_COLOR=always options: --volume ${{ github.workspace }}:/work --workdir /work --privileged --env CARGO_TERM_COLOR=always
run: | run: |
set -e set -e
echo "::group::Disable PAM for sudo with root and no tty"
bin/disable_pam_for_sudo.sh
echo "::endgroup::"
echo "::group::Install Prerequisites" echo "::group::Install Prerequisites"
bin/install_prerequisites_fedora.sh bin/install_prerequisites_fedora.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Activate python3 venv"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -218,12 +253,12 @@ jobs:
echo "::group::Tests" echo "::group::Tests"
bin/test/test.sh bin/test/test.sh
echo "::endgroup::" echo "::endgroup::"
- name: find artifacts - name: Find artifacts
run: | run: |
pwd pwd
find . -name "*.log" find . -name "*.log"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-fedora-x64-artifacts name: tests-fedora-x64-artifacts
@ -234,8 +269,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Build, Test units and Integration tests - name: Build, Test units and Integration tests
uses: addnab/docker-run-action@v3 uses: addnab/docker-run-action@v3
@ -249,8 +285,8 @@ jobs:
echo "::group::Install Prerequisites" echo "::group::Install Prerequisites"
bin/install_prerequisites_alpine.sh bin/install_prerequisites_alpine.sh
echo "::endgroup::" echo "::endgroup::"
echo "::group::Install python3 venv" echo "::group::Activate python3 venv"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
which python3 which python3
python3 --version python3 --version
@ -265,12 +301,12 @@ jobs:
echo "::group::Tests" echo "::group::Tests"
bin/test/test.sh bin/test/test.sh
echo "::endgroup::" echo "::endgroup::"
- name: find artifacts - name: Find artifacts
run: | run: |
pwd pwd
find . -name "*.log" find . -name "*.log"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-alpine-x64-artifacts name: tests-alpine-x64-artifacts
@ -278,22 +314,23 @@ jobs:
./**/*.log ./**/*.log
test-macos-x64: test-macos-x64:
runs-on: macos-13 runs-on: macos-15-intel
strategy: strategy:
matrix: matrix:
rust: [stable] rust: [stable]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: | run: |
bin/install_prerequisites_macos.sh bin/install_prerequisites_macos.sh
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
- name: Install python3 venv - name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
@ -311,14 +348,12 @@ jobs:
bin/test/test_unit.sh bin/test/test_unit.sh
bin/release/release.sh bin/release/release.sh
echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}" echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Integration Tests - name: Find artifacts
run: bin/test/test_integ.sh
- name: find artifacts
run: | run: |
pwd pwd
find . -name "*.log" find . -name "*.log"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-macos-x64-${{ matrix.rust }}-artifacts name: tests-macos-x64-${{ matrix.rust }}-artifacts
@ -326,22 +361,23 @@ jobs:
./**/*.log ./**/*.log
test-macos-aarch64: test-macos-aarch64:
runs-on: macos-14 runs-on: macos-15
strategy: strategy:
matrix: matrix:
rust: [stable] rust: [stable]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Prerequisites - name: Install Prerequisites
run: | run: |
bin/install_prerequisites_macos.sh bin/install_prerequisites_macos.sh
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
- name: Install python3 venv - name: Activate python3 venv
run: | run: |
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH="/tmp/hurl-python3-venv/bin:$PATH" export PATH="/tmp/hurl-python3-venv/bin:$PATH"
echo "PATH=$PATH" >> $GITHUB_ENV echo "PATH=$PATH" >> $GITHUB_ENV
which python3 which python3
@ -359,14 +395,12 @@ jobs:
bin/test/test_unit.sh bin/test/test_unit.sh
bin/release/release.sh bin/release/release.sh
echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}" echo "PATH=${PWD}/target/release:$PATH" >> "${GITHUB_ENV}"
- name: Integration Tests - name: Find artifacts
run: bin/test/test_integ.sh
- name: find artifacts
run: | run: |
pwd pwd
find . -name "*.log" find . -name "*.log"
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-macos-aarch64-${{ matrix.rust }}-artifacts name: tests-macos-aarch64-${{ matrix.rust }}-artifacts
@ -375,39 +409,112 @@ jobs:
test-windows-x64: test-windows-x64:
runs-on: windows-latest runs-on: windows-latest
strategy:
matrix:
rust: [stable]
env:
VCPKGRS_DYNAMIC: 1
steps: steps:
- name: Set git to use LF - name: Set git to use LF
run: | run: |
git config --global core.autocrlf false git config --global core.autocrlf false
git config --global core.eol lf git config --global core.eol lf
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: false
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Install Rust - name: Install Rust
run: | run: |
.\bin\install_rust.ps1 .\bin\install_rust.ps1
- name: Manage vcpkg cache - name: Manage vcpkg cache
uses: actions/cache@v4.0.2 uses: actions/cache@v5.0.1
with: with:
path: C:\vcpkg path: C:\vcpkg
key: ${{ runner.os }}-test-windows-x64 key: ${{ runner.os }}-test-windows-x64
- name: Environment - name: Install prerequisites
run: .\bin\environment.ps1
- name: Install Prerequisites
run: .\bin\install_prerequisites_windows.ps1 run: .\bin\install_prerequisites_windows.ps1
- name: Install Python 3.11
uses: actions/setup-python@v6.1.0
with:
python-version: '3.11'
- name: Environment
run: |
.\bin\activate_python3_venv.ps1
- name: Build and test - name: Build and test
run: .\bin\test\test.ps1 run: |
.\bin\activate_python3_venv.ps1
.\bin\test\test_prerequisites.ps1
.\bin\test\test_unit.ps1
- name: Archive production artifacts - name: Archive production artifacts
uses: actions/upload-artifact@v4.3.6 uses: actions/upload-artifact@v6.0.0
if: ${{ always() }} if: ${{ always() }}
with: with:
name: tests-win64-${{ matrix.rust }}-artifacts name: tests-win64-${{ matrix.rust }}-artifacts
path: | path: |
./**/*.log ./**/*.log
test-windows-wsl2-x64:
runs-on: windows-latest
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout repository
uses: actions/checkout@v6.0.1
with:
persist-credentials: false
ref: ${{ inputs.branch }}
- name: Setup wsl Ubuntu
uses: Vampire/setup-wsl@v6.0.0
with:
distribution: Ubuntu-22.04
wsl-version: 2
wsl-conf: |
[interop]
appendWindowsPath=false
- name: List wsl distribution
run: |
wsl --list --verbose --all
- shell: wsl-bash {0}
run: |
# Build, Test units and Integration tests
set -e
echo "::group::Move to linux compatible workspace"
win_workspace="${{ github.workspace }}"
wsl_workspace="/mnt/$(echo "${win_workspace}" | tr -d ':' | tr '\\' '/' | tr '[:upper:]' '[:lower:]')"
linux_workspace="/tmp/hurl"
cp -frp "${wsl_workspace}" "${linux_workspace}"
cd "${linux_workspace}"
pwd
ls
echo "::endgroup::"
echo "::group::Install Prerequisites"
bin/install_prerequisites_ubuntu.sh
echo "::endgroup::"
echo "::group::Install python 3.11"
bin/install_pythonx_for_ubuntu.sh 11
bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH
echo "::endgroup::"
echo "::group::Install tests integ prerequisistes"
bin/test/test_prerequisites.sh
echo "::endgroup::"
echo "::group::Install Rust"
bin/install_rust.sh
echo "::endgroup::"
echo "::group::Environment"
bin/environment.sh
echo "::endgroup::"
echo "::group::Tests units"
bin/test/test_unit.sh
echo "::endgroup::"
echo "::group::Build"
bin/release/release.sh
export PATH="${PWD}/target/release:$PATH"
echo "::group::Tests integ"
bin/test/test_integ.sh
echo "::endgroup::"
- name: Archive production artifacts
uses: actions/upload-artifact@v6.0.0
if: ${{ always() }}
with:
name: tests-win64-wsl2-artifacts
path: |
./**/*.log

View File

@ -2,7 +2,7 @@ name: update-actions
on: on:
schedule: schedule:
- cron: "0 4 * * *" - cron: "0 4 * * 1"
workflow_dispatch: workflow_dispatch:
concurrency: update-actions-${{ github.ref }} concurrency: update-actions-${{ github.ref }}
@ -18,8 +18,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: master ref: master
token: ${{ secrets.HURL_BOT_TOKEN }} token: ${{ secrets.HURL_BOT_TOKEN }}
@ -68,7 +69,7 @@ jobs:
fi fi
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}

View File

@ -4,7 +4,7 @@ on:
workflow_dispatch: workflow_dispatch:
inputs: inputs:
new_version: new_version:
description: 'Version (x.y.z-SNASPHOT)' description: 'Version (x.y.z-SNAPSHOT)'
required: true required: true
type: string type: string
workflow_call: workflow_call:
@ -20,7 +20,7 @@ on:
required: true required: true
inputs: inputs:
new_version: new_version:
description: "Version (x.y.z-SNASPHOT)" description: "Version (x.y.z-SNAPSHOT)"
required: true required: true
type: string type: string
branch: branch:
@ -38,22 +38,25 @@ concurrency: update-branch-version
jobs: jobs:
update-branch-version: update-branch-version:
env: env:
GITHUB_REF: ${{ github.ref }}
GITHUB_CONTEXT: ${{ toJson(github) }} GITHUB_CONTEXT: ${{ toJson(github) }}
GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }} GITHUB_TOKEN: ${{ secrets.HURL_BOT_TOKEN }}
REPO: ${{ github.repository }} REPO: ${{ github.repository }}
NEW_VERSION: ${{ inputs.new_version }}
outputs: outputs:
pr_number: ${{ steps.create-new-version-pr.outputs.pr_number }} pr_number: ${{ steps.create-new-version-pr.outputs.pr_number }}
name: update-branch-version name: update-branch-version
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Init bot branch name - name: Init bot branch name
run: | run: |
base=$(echo "${{ github.ref }}" | sed "s#refs/heads/##g" | tr '/' '-') base=$(echo "${GITHUB_REF}" | sed "s#refs/heads/##g" | tr '/' '-')
echo "BOT_UPDATE_VERSION_BRANCH_NAME=bot/update-branch-version-${base}" | tee -a $GITHUB_ENV echo "BOT_UPDATE_VERSION_BRANCH_NAME=bot/update-branch-version-${base}" | tee -a $GITHUB_ENV
- name: Update version - name: Update version
@ -61,22 +64,21 @@ jobs:
hurl_packages="hurl_core hurl hurlfmt" hurl_packages="hurl_core hurl hurlfmt"
for package in ${hurl_packages} ; do for package in ${hurl_packages} ; do
cargo_toml="packages/${package}/Cargo.toml" cargo_toml="packages/${package}/Cargo.toml"
sed -i "s/^version.*/version = \"${{ inputs.new_version }}\"/" "${cargo_toml}" sed -i "s/^version.*/version = \"${NEW_VERSION}\"/" "${cargo_toml}"
echo "----------------------------" echo "----------------------------"
echo " > package version for ${cargo_toml}" echo " > package version for ${cargo_toml}"
echo " $(grep "^version =" "${cargo_toml}")" echo " $(grep "^version =" "${cargo_toml}")"
for dep_package in ${hurl_packages} ; do for dep_package in ${hurl_packages} ; do
if [ $(grep -c "^${dep_package} =" "${cargo_toml}") -gt 0 ] ; then if [ $(grep -c "^${dep_package} =" "${cargo_toml}") -gt 0 ] ; then
sed -i "s/^${dep_package} = { version .*/${dep_package} = { version = \"${{ inputs.new_version }}\", path = \"..\/${dep_package}\" }/" "${cargo_toml}" sed -i "s/^${dep_package} = { version .*/${dep_package} = { version = \"${NEW_VERSION}\", path = \"..\/${dep_package}\" }/" "${cargo_toml}"
echo " > ${dep_package} dep package version for ${cargo_toml}" echo " > ${dep_package} dep package version for ${cargo_toml}"
echo " $(grep "^${dep_package} =" "${cargo_toml}")" echo " $(grep "^${dep_package} =" "${cargo_toml}")"
fi fi
done done
done done
- name: Cargo update - name: Cargo lock update
run: | run: cargo update hurl hurlfmt hurl_core
./bin/update_crates.sh
- name: Update man - name: Update man
run: | run: |
@ -91,7 +93,7 @@ jobs:
python3 bin/docs/build_readme.py crates > packages/hurl/README.md python3 bin/docs/build_readme.py crates > packages/hurl/README.md
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}
@ -103,7 +105,7 @@ jobs:
- name: Push commits - name: Push commits
run: | run: |
git checkout -b "${BOT_UPDATE_VERSION_BRANCH_NAME}" git checkout -b "${BOT_UPDATE_VERSION_BRANCH_NAME}"
git commit -am "Update hurl version to ${{ inputs.new_version }}" git commit -am "Update hurl version to ${NEW_VERSION}"
git push --set-upstream origin "${BOT_UPDATE_VERSION_BRANCH_NAME}" && git_exit_code=0 || git_exit_code=$? git push --set-upstream origin "${BOT_UPDATE_VERSION_BRANCH_NAME}" && git_exit_code=0 || git_exit_code=$?
if [ ${git_exit_code} -eq 0 ] ; then if [ ${git_exit_code} -eq 0 ] ; then
echo " - ✅ commits pushed to ${BOT_UPDATE_VERSION_BRANCH_NAME} branch." echo " - ✅ commits pushed to ${BOT_UPDATE_VERSION_BRANCH_NAME} branch."
@ -115,9 +117,8 @@ jobs:
- name: Create new version PR - name: Create new version PR
id: create-new-version-pr id: create-new-version-pr
run: | run: |
GITHUB_TOKEN=${{ secrets.HURL_BOT_TOKEN }}
git fetch git fetch
base=$(echo "${{ github.ref }}" | sed "s#refs/heads/##g") base=$(echo "${GITHUB_REF}" | sed "s#refs/heads/##g")
gh pr create --fill --label bot --base "${base}" --head "${BOT_UPDATE_VERSION_BRANCH_NAME}" && gh_exit_code=0 || gh_exit_code=$? gh pr create --fill --label bot --base "${base}" --head "${BOT_UPDATE_VERSION_BRANCH_NAME}" && gh_exit_code=0 || gh_exit_code=$?
if [ ${gh_exit_code} -eq 0 ] ; then if [ ${gh_exit_code} -eq 0 ] ; then
NEW_PR_NUMBER=$(gh pr list --repo "${REPO}" --head "${BOT_UPDATE_VERSION_BRANCH_NAME}" --state "open" --json number --jq .[].number) NEW_PR_NUMBER=$(gh pr list --repo "${REPO}" --head "${BOT_UPDATE_VERSION_BRANCH_NAME}" --state "open" --json number --jq .[].number)
@ -127,3 +128,4 @@ jobs:
echo " - ❌ A problem occurs when attempting to create new pull request." echo " - ❌ A problem occurs when attempting to create new pull request."
exit 1 exit 1
fi fi

View File

@ -18,8 +18,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4.1.7 uses: actions/checkout@v6.0.1
with: with:
persist-credentials: true
ref: master ref: master
- name: Crates update - name: Crates update
@ -67,7 +68,7 @@ jobs:
fi fi
- name: Init git bot context - name: Init git bot context
uses: crazy-max/ghaction-import-gpg@v6.1.0 uses: crazy-max/ghaction-import-gpg@v6.3.0
with: with:
gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }} passphrase: ${{ secrets.HURL_BOT_GPG_PRIVATE_KEY_PASSPHRASE }}

View File

@ -1,3 +1,291 @@
[7.2.0 (TBD)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#7.2.0)
========================================================================================================================
Thanks to
[@spiffytech](https://github.com/spiffytech),
[@rajiv](https://github.com/rajiv),
Enhancements:
* Add Subject Alt Name (SAN) attribute for certificate assertions [#4617](https://github.com/Orange-OpenSource/hurl/issues/4617)
Bugs Fixed:
* Fix truncating existing output file when response is tiny [#4576](https://github.com/Orange-OpenSource/hurl/issues/4576)
[7.1.0 (2025-11-18)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#7.1.0)
========================================================================================================================
Thanks to
[@Nezteb](https://github.com/Nezteb),
[@quantonganh](https://github.com/quantonganh),
[@lambrospetrou](https://github.com/lambrospetrou),
[@linkdd](https://github.com/linkdd),
[@gugahoa](https://github.com/gugahoa),
[@MikhailWahib](https://github.com/MikhailWahib),
[@ashishajr](https://github.com/ashishajr),
[@rcrisanti](https://github.com/rcrisanti),
Enhancements:
* Add CLI option to pretty print the response body [#1760](https://github.com/Orange-OpenSource/hurl/issues/1760)
* Add pretty print option [#1760](https://github.com/Orange-OpenSource/hurl/issues/1760)
* Support adding secret with HURL_SECRET_foo env variable [#3901](https://github.com/Orange-OpenSource/hurl/issues/3901)
* Use happy path with http/https scheme for URL parsing to improve stress test use-cases [#4144](https://github.com/Orange-OpenSource/hurl/issues/4144)
* Support `--secrets-file` for injecting secrets [#4309](https://github.com/Orange-OpenSource/hurl/issues/4309)
* Add `--ntlm` option per request [#4322](https://github.com/Orange-OpenSource/hurl/issues/4322)
* Add `--negotiate` option per request [#4323](https://github.com/Orange-OpenSource/hurl/issues/4323)
* Add utf8Decode/utf8Encode filters [#4382](https://github.com/Orange-OpenSource/hurl/issues/4382)
* Replace unmaintained encoding crate with encoding_rs crate [#4399](https://github.com/Orange-OpenSource/hurl/issues/4399)
* Enhance logging for retry [#4419](https://github.com/Orange-OpenSource/hurl/issues/4419)
* Add support for hour duration [#4422](https://github.com/Orange-OpenSource/hurl/issues/4422)
* Enhance `--test` duration logging [#4423](https://github.com/Orange-OpenSource/hurl/issues/4423)
* Add parsing support for more types of date time strings to toDate filter [#4439](https://github.com/Orange-OpenSource/hurl/issues/4439) [#4440](https://github.com/Orange-OpenSource/hurl/issues/4440) [#4441](https://github.com/Orange-OpenSource/hurl/issues/4441)
* HTML report enhancements [#4445](https://github.com/Orange-OpenSource/hurl/issues/4445) [#4446](https://github.com/Orange-OpenSource/hurl/issues/4446)
* Add retry count in the progress bar (only if retry >= 1) [#4511](https://github.com/Orange-OpenSource/hurl/issues/4511)
* Add isList predicate [#4520](https://github.com/Orange-OpenSource/hurl/issues/4520)
* Add isObject predicate [#4520](https://github.com/Orange-OpenSource/hurl/issues/4520)
Bugs Fixed:
* Parse `--user`, `--negotiate`, and `--ntlm` options in hurlfmt [#4213](https://github.com/Orange-OpenSource/hurl/issues/4213)
* Add parsing support for more types of date time strings to toDate filter [#4439](https://github.com/Orange-OpenSource/hurl/issues/4439) [#4440](https://github.com/Orange-OpenSource/hurl/issues/4440) [#4441](https://github.com/Orange-OpenSource/hurl/issues/4441)
* Accept more path names when appending HTML reports [#4459](https://github.com/Orange-OpenSource/hurl/issues/4459)
* Fix filtering of Authorization: and Cookie: headers when following redirections [#4460](https://github.com/Orange-OpenSource/hurl/issues/4460)
* Fix supporting space in cookie storage cookie values [#4461](https://github.com/Orange-OpenSource/hurl/issues/4461)
* Fix implicit "Content-Type" headers when following redirections [#4522](https://github.com/Orange-OpenSource/hurl/issues/4522)
* Fix curl debug command with dot-prefixed cookie domain [#4558](https://github.com/Orange-OpenSource/hurl/issues/4558)
[7.0.0 (2025-07-28)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#7.0.0)
========================================================================================================================
Thanks to
[@ecolinet](https://github.com/ecolinet),
[@theoforger](https://github.com/theoforger),
[@Muntaner](https://github.com/Muntaner),
[@ashishajr](https://github.com/ashishajr),
[@patkujawa-wf](https://github.com/patkujawa-wf),
[@niklasweimann](https://github.com/niklasweimann),
[@alanbondarun](https://github.com/alanbondarun),
[@benkio](https://github.com/benkio),
[@dhth](https://github.com/dhth),
[@verigak](https://github.com/verigak),
[@markphilpot](https://github.com/markphilpot),
[@lambrospetrou](https://github.com/lambrospetrou),
[@aresler](https://github.com/aresler),
[@nfj25](https://github.com/nfj25),
[@nwellnhof](https://github.com/nwellnhof),
[@YannickAlex07](https://github.com/YannickAlex07),
[@lu-zero](https://github.com/lu-zero),
[@RaghavSood](https://github.com/RaghavSood),
[@tjbrockmeyer](https://github.com/tjbrockmeyer),
Breaking Changes:
* Add replaceRegex filter and fix replace filter to not take regex [#4018](https://github.com/Orange-OpenSource/hurl/issues/4018)
Enhancements:
* Add query for HTTP redirects [#922](https://github.com/Orange-OpenSource/hurl/issues/922)
* Add urlQueryParam filter [#2199](https://github.com/Orange-OpenSource/hurl/issues/2199)
* Show curl command when error format option is set to long [#2226](https://github.com/Orange-OpenSource/hurl/issues/2226)
* Add option to configure max-time per request [#3162](https://github.com/Orange-OpenSource/hurl/issues/3162)
* Add date comparison predicates [#3480](https://github.com/Orange-OpenSource/hurl/issues/3480)
* Add pinnedpubkey cli option [#3563](https://github.com/Orange-OpenSource/hurl/issues/3563)
* Add base64 url safe encode and decode filters [#3840](https://github.com/Orange-OpenSource/hurl/issues/3840)
* parse curl's --cookie flag [#3877](https://github.com/Orange-OpenSource/hurl/issues/3877)
* Show hurl --help with color [#3882](https://github.com/Orange-OpenSource/hurl/issues/3882)
* Add toHex filter [#3963](https://github.com/Orange-OpenSource/hurl/issues/3963)
* Add first and last filters [#3998](https://github.com/Orange-OpenSource/hurl/issues/3998)
* Remove hex crate dependency [#4011](https://github.com/Orange-OpenSource/hurl/issues/4011)
* Small tweaks to --test progress output [#4028](https://github.com/Orange-OpenSource/hurl/issues/4028)
* Add support for negative values for nth filter [#4050](https://github.com/Orange-OpenSource/hurl/issues/4050)
* Add option to configure pinnedpubkey per request [#4084](https://github.com/Orange-OpenSource/hurl/issues/4084)
* Add timeline link on status label in source and run pages [#4128](https://github.com/Orange-OpenSource/hurl/issues/4128)
* Support template in nth filter parameter [#4152](https://github.com/Orange-OpenSource/hurl/issues/4152)
* Implement predicate `isUuid` [#4179](https://github.com/Orange-OpenSource/hurl/issues/4179)
* Improve captures error messages when filter chain returned no value [#4214](https://github.com/Orange-OpenSource/hurl/issues/4214)
* Add --ntlm cli option [#4216](https://github.com/Orange-OpenSource/hurl/issues/4216)
* Add --negotiate option [#4246](https://github.com/Orange-OpenSource/hurl/issues/4246)
Bugs Fixed:
* Fix incorrect curl command for POST redirect [#2797](https://github.com/Orange-OpenSource/hurl/issues/2797)
* Fix hurlfmt to disallow invalid header argument in curl command [#3668](https://github.com/Orange-OpenSource/hurl/issues/3668)
* Parse verbose flag in curl command [#3760](https://github.com/Orange-OpenSource/hurl/issues/3760)
* Keep secret value forever, even if a secret variable override an existing one [#3898](https://github.com/Orange-OpenSource/hurl/issues/3898)
* Fix zsh completion [#3938](https://github.com/Orange-OpenSource/hurl/issues/3938)
* Parse cookie Expires date attribute with '-' [#3956](https://github.com/Orange-OpenSource/hurl/issues/3956)
* Replace deprecated libxml2 initGenericErrorDefaultFunc with xmlSetGenericErrorFunc [#3975](https://github.com/Orange-OpenSource/hurl/issues/3975)
* HTML report: fix span for lines in comment. [#4002](https://github.com/Orange-OpenSource/hurl/issues/4002)
* Fix HTML closing tag for line with trailing comment [#4017](https://github.com/Orange-OpenSource/hurl/issues/4017)
* Add replaceRegex filter and fix replace filter to not take regex [#4018](https://github.com/Orange-OpenSource/hurl/issues/4018)
* Fix request body during redirections [#4073](https://github.com/Orange-OpenSource/hurl/issues/4073)
* Fix "variables" token in GraphQL HTML export [#4117](https://github.com/Orange-OpenSource/hurl/issues/4117)
* Support negative index in jsonpath [#4154](https://github.com/Orange-OpenSource/hurl/issues/4154)
Security Issues Fixed:
* Fix JavaScript injection in HTML report through regex literal [#4125](https://github.com/Orange-OpenSource/hurl/issues/4125)
[6.1.1 (2025-03-19)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#6.1.1)
========================================================================================================================
Thanks to
[@lu-zero](https://github.com/lu-zero),
[@andrejohansson](https://github.com/andrejohansson),
[@demostanis](https://github.com/demostanis),
[@techfg](https://github.com/techfg),
Bugs Fixed:
* Fix hurlfmt spacing [#3839](https://github.com/Orange-OpenSource/hurl/issues/3839)
* Fix filename parsing [#3848](https://github.com/Orange-OpenSource/hurl/issues/3848)
* Fix jsonpath array wildcard with missing attribute [#3859](https://github.com/Orange-OpenSource/hurl/issues/3859) [#3869](https://github.com/Orange-OpenSource/hurl/issues/3869)
* Fix predicate `contains` with none input [#3868](https://github.com/Orange-OpenSource/hurl/issues/3868)
[6.1.0 (2025-03-12)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#6.1.0)
========================================================================================================================
Thanks to
[@lilyhuang-github](https://github.com/lilyhuang-github),
[@ashishajr](https://github.com/ashishajr),
[@kidbrax](https://github.com/kidbrax),
[@theoforger](https://github.com/theoforger),
[@smokedlinq](https://github.com/smokedlinq),
[@docwhat](https://github.com/docwhat),
[@glb-cblin](https://github.com/glb-cblin),
[@Enoz](https://github.com/Enoz),
[@ikorason](https://github.com/ikorason),
[@uday-rana](https://github.com/uday-rana),
[@lu-zero](https://github.com/lu-zero),
[@nghiab1906724](https://github.com/nghiab1906724),
[@overbyte](https://github.com/overbyte),
Breaking Changes:
* Remove deprecated predicates (notEquals, greaterThan etc...) in favor of operators [#3532](https://github.com/Orange-OpenSource/hurl/issues/3532)
* Remove deprecated keyword HTTP/* for HTTP [#3697](https://github.com/Orange-OpenSource/hurl/issues/3697)
Enhancements:
* Removed limitation for --cookie-jar to use only one hurl file [#2537](https://github.com/Orange-OpenSource/hurl/issues/2537)
* Add HTTP version query [#1706](https://github.com/Orange-OpenSource/hurl/issues/1706)
* Add curl -H/--header option to globally add headers to all requests [#1905](https://github.com/Orange-OpenSource/hurl/issues/1905) [#2144](https://github.com/Orange-OpenSource/hurl/issues/2144)
* Add toString Filter [#2035](https://github.com/Orange-OpenSource/hurl/issues/2035) [#3798](https://github.com/Orange-OpenSource/hurl/issues/3798)
* Add base64 decode filter [#2145](https://github.com/Orange-OpenSource/hurl/issues/2145)
* Add base64 encode filter [#2145](https://github.com/Orange-OpenSource/hurl/issues/2145)
* Redacts secrets from JUnit reports [#2947](https://github.com/Orange-OpenSource/hurl/issues/2947) [#2972](https://github.com/Orange-OpenSource/hurl/issues/2972)
* Redacts secrets from JSON report [#2947](https://github.com/Orange-OpenSource/hurl/issues/2947) [#2972](https://github.com/Orange-OpenSource/hurl/issues/2972)
* Redact secret in HTML report [#2947](https://github.com/Orange-OpenSource/hurl/issues/2947) [#2972](https://github.com/Orange-OpenSource/hurl/issues/2972)
* Redact secrets from curl export [#2947](https://github.com/Orange-OpenSource/hurl/issues/2947) [#2972](https://github.com/Orange-OpenSource/hurl/issues/2972)
* Redact secrets from cookies export [#2947](https://github.com/Orange-OpenSource/hurl/issues/2947) [#2972](https://github.com/Orange-OpenSource/hurl/issues/2972)
* Add IP address query [#3106](https://github.com/Orange-OpenSource/hurl/issues/3106)
* Add isIpv4 / isIpv6 asserts on IP versions [#3106](https://github.com/Orange-OpenSource/hurl/issues/3106)
* Allow sending empty HTTP header [#3536](https://github.com/Orange-OpenSource/hurl/issues/3536)
* Redact dynamic values from logs [#3543](https://github.com/Orange-OpenSource/hurl/issues/3543)
* Add header option per request [#3575](https://github.com/Orange-OpenSource/hurl/issues/3575)
* Fix invalid escape in hurlfmt parse func [#3615](https://github.com/Orange-OpenSource/hurl/issues/3615)
* hurlfmt: Use Hurl predicates identifiers for Hurl to JSON file export [#3662](https://github.com/Orange-OpenSource/hurl/issues/3662)
* Add aarch64 deb package [#3829](https://github.com/Orange-OpenSource/hurl/issues/3829)
Bugs Fixed:
* Fix missing request line errors in HTML report [#3534](https://github.com/Orange-OpenSource/hurl/issues/3534)
* Eval template in JSON object key [#3593](https://github.com/Orange-OpenSource/hurl/issues/3593)
* Show error message if format is invalid in `format` filter [#3613](https://github.com/Orange-OpenSource/hurl/issues/3613)
* Create parent folders if missing when using --cookie-jar FILE [#3637](https://github.com/Orange-OpenSource/hurl/issues/3637)
* Remove lint errors and Fix non-zero exit code in case of error [#3648](https://github.com/Orange-OpenSource/hurl/issues/3648)
* Support BigInteger in variable [#3656](https://github.com/Orange-OpenSource/hurl/issues/3656)
* fix hurlfmt html export loosing some whitespaces [#3675](https://github.com/Orange-OpenSource/hurl/issues/3675)
* Fix template to source [#3675](https://github.com/Orange-OpenSource/hurl/issues/3675)
* Fix changing HTTP version per request sometimes not effective [#3719](https://github.com/Orange-OpenSource/hurl/issues/3719)
* Add bash file completion for hurl/hurlfmt [#3750](https://github.com/Orange-OpenSource/hurl/issues/3750)
* Fix multilines HTML export [#3768](https://github.com/Orange-OpenSource/hurl/issues/3768)
* Change parsing file content type in multipart form data [#3796](https://github.com/Orange-OpenSource/hurl/issues/3796)
Deprecations:
* Deprecate includes in favor of contains predicate [#1896](https://github.com/Orange-OpenSource/hurl/issues/1896)
* Warn for deprecated multilines string attributes [#3622](https://github.com/Orange-OpenSource/hurl/issues/3622)
* Warn for --interactive deprecation [#3763](https://github.com/Orange-OpenSource/hurl/issues/3763)
[6.0.0 (2024-12-03)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#6.0.0)
========================================================================================================================
Thanks to
[@cemoktra](https://github.com/cemoktra),
[@zikani03](https://github.com/zikani03),
[@lambrospetrou](https://github.com/lambrospetrou),
[@jmvargas](https://github.com/jmvargas),
[@quantonganh](https://github.com/quantonganh),
[@sandeshbhusal](https://github.com/sandeshbhusal),
[@thePanz](https://github.com/thePanz),
[@niklasweimann](https://github.com/niklasweimann),
[@infogulch](https://github.com/infogulch),
[@orlandow](https://github.com/orlandow),
[@bp7968h](https://github.com/bp7968h),
Breaking Changes:
* Check that variables do not conflict with existing functions [#3229](https://github.com/Orange-OpenSource/hurl/issues/3229)
* Remove deprecated --fail-at-end option [#3430](https://github.com/Orange-OpenSource/hurl/issues/3430)
* Change API for setting variable in hurl::runner::run [#3440](https://github.com/Orange-OpenSource/hurl/issues/3440)
* Remove hurlfmt deprecated --format option [#3445](https://github.com/Orange-OpenSource/hurl/issues/3445)
* Rename feature flag from vendored-openssl to static-openssl [#3460](https://github.com/Orange-OpenSource/hurl/issues/3460)
Enhancements:
* Implement function newUuid [#973](https://github.com/Orange-OpenSource/hurl/issues/973)
* Implement --limit-rate from curl [#1222](https://github.com/Orange-OpenSource/hurl/issues/1222)
* Add --curl option to export executed requests to curl commands [#2679](https://github.com/Orange-OpenSource/hurl/issues/2679)
* Configure --connect-timeout per request [#3163](https://github.com/Orange-OpenSource/hurl/issues/3163)
* Support short name for sections [QueryStringParams] => [Query], [FormParams] => [Form], [MultipartFormData] => [Multipart] [#3238](https://github.com/Orange-OpenSource/hurl/issues/3238)
* Remove url-specific parser (align with grammar) [#3244](https://github.com/Orange-OpenSource/hurl/issues/3244)
* Remove the crate float-cmp [#3247](https://github.com/Orange-OpenSource/hurl/issues/3247)
* Jsonpath / Add filter on boolean value [#3252](https://github.com/Orange-OpenSource/hurl/issues/3252)
* Jsonpath / Add non-equal filter on string and number value [#3261](https://github.com/Orange-OpenSource/hurl/issues/3261)
* Add support for backtick strings in predicates values [#3317](https://github.com/Orange-OpenSource/hurl/issues/3317)
* Categorise options in --help [#3339](https://github.com/Orange-OpenSource/hurl/issues/3339)
* Support more JSON / XML "like" mimetypes with debug output [#3343](https://github.com/Orange-OpenSource/hurl/issues/3343)
* Add curl debug command to --json and JSON report [#3374](https://github.com/Orange-OpenSource/hurl/issues/3374)
* Add curl debug command to HTML report [#3386](https://github.com/Orange-OpenSource/hurl/issues/3386)
* Render Date value [#3431](https://github.com/Orange-OpenSource/hurl/issues/3431)
* Add newDate generator [#3443](https://github.com/Orange-OpenSource/hurl/issues/3443)
Bugs Fixed:
* Fix reading standard input multiple times [#3216](https://github.com/Orange-OpenSource/hurl/issues/3216)
* Fix filename parsing (used by cert option) [#3242](https://github.com/Orange-OpenSource/hurl/issues/3242)
* Add additional check for --max-filesize option [#3245](https://github.com/Orange-OpenSource/hurl/issues/3245)
* Support case-insensitive Cookie Attributes [#3265](https://github.com/Orange-OpenSource/hurl/issues/3265)
* Allow any string in Location Header when not following redirection [#3293](https://github.com/Orange-OpenSource/hurl/issues/3293)
* Fix graceful shutdown of workers threads in --test [#3297](https://github.com/Orange-OpenSource/hurl/issues/3297)
* Fix missing space in variable option HTML export [#3412](https://github.com/Orange-OpenSource/hurl/issues/3412)
[5.0.1 (2024-08-30)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#5.0.1)
========================================================================================================================
Bugs Fixed:
* Fix regression in --output when output file doesn't exist [#3195](https://github.com/Orange-OpenSource/hurl/issues/3195)
[5.0.0 (2024-08-29)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#5.0.0) [5.0.0 (2024-08-29)](https://github.com/Orange-OpenSource/hurl/blob/master/CHANGELOG.md#5.0.0)
======================================================================================================================== ========================================================================================================================

View File

@ -24,6 +24,9 @@ relevant to you and we understand it; that's said, we try to reflect on every as
## How Can You Help ? ## How Can You Help ?
Issues opened to contributors are labelled ["open-to-contribution"](https://github.com/Orange-OpenSource/hurl/issues?q=is%3Aissue%20state%3Aopen%20label%3Aopen-to-contribution).
Apart for these issues, we're looking forward to contributors for:
- Installing / Packet managers: bundle Hurl for a particular packet manager is welcome. Currently, we built binaries for - Installing / Packet managers: bundle Hurl for a particular packet manager is welcome. Currently, we built binaries for
Linux, macOS, Windows and we support a narrow set of packet manager. [More would be better!]. Linux, macOS, Windows and we support a narrow set of packet manager. [More would be better!].
- IDE Support: everything from color syntax (in VSCode, Vim, IntelliJ, TextMate etc...) would be a good idea. An - IDE Support: everything from color syntax (in VSCode, Vim, IntelliJ, TextMate etc...) would be a good idea. An
@ -35,6 +38,9 @@ relevant to you and we understand it; that's said, we try to reflect on every as
- [Create a new Git branch], don't use `master` branch for PR. - [Create a new Git branch], don't use `master` branch for PR.
- All Git commits are [required to be signed] and marked as "Verified": signed with a GPG, SSH, or S/MIME that is successfully verified by GitHub. - All Git commits are [required to be signed] and marked as "Verified": signed with a GPG, SSH, or S/MIME that is successfully verified by GitHub.
- Commit messages are simple phrases, don't use [Semantic Commit Messages] nor [Conventional Commits]
- ❌ `fix: missing space in variable option HTML export`
- ✅ `Fix missing space in variable option HTML export`
- All tests must be green before merge. Our CI/CD will run [a test suite] to insure everything is OK. - All tests must be green before merge. Our CI/CD will run [a test suite] to insure everything is OK.
- Hurl Git history is linear, so we may rebase your PR on your fork before final merge. - Hurl Git history is linear, so we may rebase your PR on your fork before final merge.
@ -47,10 +53,10 @@ Once your setup is ready, just build the project:
```shell ```shell
$ cargo build $ cargo build
Compiling hurl_core v2.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurl_core) Compiling hurl_core v6.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurl_core)
... ...
Compiling hurlfmt v2.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurlfmt) Compiling hurlfmt v6.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurlfmt)
Compiling hurl v2.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurl) Compiling hurl v6.0.0-SNAPSHOT (/Users/jc/Documents/Dev/hurl/packages/hurl)
Finished dev [unoptimized + debuginfo] target(s) in 2.53s Finished dev [unoptimized + debuginfo] target(s) in 2.53s
``` ```
@ -61,7 +67,7 @@ $ cargo test --lib
``` ```
Hurl has a big suite of [integration tests]. To run the integration tests, you'll need Python 3.6+. You can use a [virtual environment] and install the dependencies needed Hurl has a big suite of [integration tests]. To run the integration tests, you'll need Python 3.9+. You can use a [virtual environment] and install the dependencies needed
by the tests suite: by the tests suite:
```shell ```shell
@ -73,15 +79,21 @@ $ pip install --requirement bin/requirements-frozen.txt
Then, you can launch our local server (used to test Hurl features): Then, you can launch our local server (used to test Hurl features):
```shell ```shell
$ cd integration $ cd integration/hurl
$ python3 server.py >server.log 2>&1 & $ python3 server.py > server.log 2>&1 &
$ python3 ssl/server.py >server-ssl.log 2>&1 & $ python3 tests_ssl/ssl_server.py 8001 tests_ssl/certs/server/cert.selfsigned.pem false > server-ssl-selfsigned.log 2>&1 &
$ squid_conf="http_access allow all\nhttp_port 3128\nrequest_header_add From-Proxy Hello\nreply_header_add From-Proxy Hello" $ python3 tests_ssl/ssl_server.py 8002 tests_ssl/certs/server/cert.pem false > server-ssl-signedbyca.log 2>&1 &
$ (echo "${squid_conf}" | squid -d 2 -N -f /dev/stdin > proxy.log 2>&1) & $ python3 tests_ssl/ssl_server.py 8003 tests_ssl/certs/server/cert.selfsigned.pem true > server-ssl-client-authent.log 2>&1 &
$ python3 tests_unix_socket/unix_socket_server.py > server-unix-socket.log 2>&1 &
$ squid_conf="cache deny all\ncache_log /dev/null\naccess_log /dev/null\nhttp_access allow all\nhttp_port 127.0.0.1:3128\nrequest_header_add From-Proxy Hello\nreply_header_add From-Proxy Hello"
$ (echo -e "${squid_conf}" | sudo squid -d 2 -N -f /dev/stdin | sudo tee proxy.log 2>&1) &
$ jobs $ jobs
[1] running python3 server.py > server.log 2>&1
[2] - running python3 ssl/server.py > server-ssl.log 2>&1 [1] Running ( echo -e "${squid_conf}" | sudo squid -d 2 -N -f /dev/stdin | sudo tee build/proxy.log 2>&1 ) &
[3] + running echo "${squid_conf}" | squid -d 2 -N -f /dev/stdin > proxy.log 2>&1 [2] Running python3 server.py > server.log 2>&1 &
[3] Running python3 tests_ssl/ssl_server.py 8001 tests_ssl/certs/server/cert.selfsigned.pem false > server-ssl-selfsigned.log 2>&1 &
[4]-Running python3 tests_ssl/ssl_server.py 8002 tests_ssl/certs/server/cert.pem false > server-ssl-signedbyca.log 2>&1 &
[5]+Running python3 tests_ssl/ssl_server.py 8003 tests_ssl/certs/server/cert.selfsigned.pem true > server-ssl-client-authent.log 2>&1 &
``` ```
You can check [the integration `README`] for more details You can check [the integration `README`] for more details
@ -92,7 +104,7 @@ Now, you can follow these steps when you make changes:
2. Run Clippy `cargo clippy` 2. Run Clippy `cargo clippy`
3. Format `cargo fmt` 3. Format `cargo fmt`
4. Run units tests `cargo test --lib` 4. Run units tests `cargo test --lib`
5. Run integration tests `cd integration && python3 integration.py` 5. Run integration tests `cd integration/hurl && python3 integration.py`
Et voilà 🎉! Et voilà 🎉!
@ -106,8 +118,10 @@ Et voilà 🎉!
[virtual environment]: https://docs.python.org/3/tutorial/venv.html [virtual environment]: https://docs.python.org/3/tutorial/venv.html
[Hurl core values]: #hurl-core-values [Hurl core values]: #hurl-core-values
[a test suite]: https://github.com/Orange-OpenSource/hurl/actions [a test suite]: https://github.com/Orange-OpenSource/hurl/actions
[an integration test]: https://github.com/Orange-OpenSource/hurl/tree/master/integration/tests_ok [an integration test]: https://github.com/Orange-OpenSource/hurl/tree/master/integration/hurl/tests_ok
[Create a new Git branch]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-and-deleting-branches-within-your-repository [Create a new Git branch]: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-and-deleting-branches-within-your-repository
[required to be signed]: https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification [required to be signed]: https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification
[integration tests]: https://github.com/Orange-OpenSource/hurl/tree/master/integration [integration tests]: https://github.com/Orange-OpenSource/hurl/tree/master/integration
[the integration `README`]: /integration/README.md [the integration `README`]: /integration/README.md
[Conventional Commits]: https://www.conventionalcommits.org
[Semantic Commit Messages]: https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716

1164
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -20,3 +20,4 @@ warnings = "deny"
empty_structs_with_brackets = "deny" empty_structs_with_brackets = "deny"
manual_string_new = "deny" manual_string_new = "deny"
semicolon_if_nothing_returned = "deny" semicolon_if_nothing_returned = "deny"
wildcard-imports = "deny"

597
README.md
View File

@ -19,7 +19,7 @@ versatile: it can be used for both <b>fetching data</b> and <b>testing HTTP</b>
Hurl makes it easy to work with <b>HTML</b> content, <b>REST / SOAP / GraphQL</b> APIs, or any other <b>XML / JSON</b> based APIs. Hurl makes it easy to work with <b>HTML</b> content, <b>REST / SOAP / GraphQL</b> APIs, or any other <b>XML / JSON</b> based APIs.
```hurl ```hurl
# Get home: # Go home and capture token
GET https://example.org GET https://example.org
HTTP 200 HTTP 200
[Captures] [Captures]
@ -27,8 +27,11 @@ csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
# Do login! # Do login!
POST https://example.org/login?user=toto&password=1234 POST https://example.org/login
X-CSRF-TOKEN: {{csrf_token}} X-CSRF-TOKEN: {{csrf_token}}
[Form]
user: toto
password: 1234
HTTP 302 HTTP 302
``` ```
@ -147,7 +150,7 @@ Finally, Hurl is easy to <b>integrate in CI/CD</b>, with text, JUnit, TAP and HT
Hurl is a lightweight binary written in [Rust]. Under the hood, Hurl HTTP engine is Hurl is a lightweight binary written in [Rust]. Under the hood, Hurl HTTP engine is
powered by [libcurl], one of the most powerful and reliable file transfer libraries. powered by [libcurl], one of the most powerful and reliable file transfer libraries.
With its text file format, Hurl adds syntactic sugar to run and test HTTP requests, With its text file format, Hurl adds syntactic sugar to run and test HTTP requests,
but it's still the [curl] that we love: __fast__, __efficient__ and __HTTP/3 ready__. but it's still the [curl] that we love: __fast__, __efficient__ and __IPv6 / HTTP/3 ready__.
# Feedbacks # Feedbacks
@ -172,93 +175,104 @@ HTTP 200
[Tutorial] [Tutorial]
[Documentation] [Documentation] (download [HTML], [PDF], [Markdown])
[GitHub] [GitHub]
Table of Contents # Table of Contents
=================
* [Samples](#samples) * [Samples](#samples)
* [Getting Data](#getting-data) * [Getting Data](#getting-data)
* [HTTP Headers](#http-headers) * [HTTP Headers](#http-headers)
* [Query Params](#query-params) * [Query Params](#query-params)
* [Basic Authentication](#basic-authentication) * [Basic Authentication](#basic-authentication)
* [Passing Data between Requests ](#passing-data-between-requests) * [Passing Data between Requests ](#passing-data-between-requests)
* [Sending Data](#sending-data) * [Sending Data](#sending-data)
* [Sending HTML Form Data](#sending-html-form-data) * [Sending HTML Form Data](#sending-html-form-data)
* [Sending Multipart Form Data](#sending-multipart-form-data) * [Sending Multipart Form Data](#sending-multipart-form-data)
* [Posting a JSON Body](#posting-a-json-body) * [Posting a JSON Body](#posting-a-json-body)
* [Templating a JSON Body](#templating-a-json-body) * [Templating a JSON Body](#templating-a-json-body)
* [Templating a XML Body](#templating-a-xml-body) * [Templating a XML Body](#templating-a-xml-body)
* [Using GraphQL Query](#using-graphql-query) * [Using GraphQL Query](#using-graphql-query)
* [Testing Response](#testing-response) * [Using Dynamic Datas](#using-dynamic-datas)
* [Testing Status Code](#testing-status-code) * [Testing Response](#testing-response)
* [Testing Response Headers](#testing-response-headers) * [Testing Status Code](#testing-status-code)
* [Testing REST APIs](#testing-rest-apis) * [Testing Response Headers](#testing-response-headers)
* [Testing HTML Response](#testing-html-response) * [Testing REST APIs](#testing-rest-apis)
* [Testing Set-Cookie Attributes](#testing-set-cookie-attributes) * [Testing HTML Response](#testing-html-response)
* [Testing Bytes Content](#testing-bytes-content) * [Testing Set-Cookie Attributes](#testing-set-cookie-attributes)
* [SSL Certificate](#ssl-certificate) * [Testing Bytes Content](#testing-bytes-content)
* [Checking Full Body](#checking-full-body) * [SSL Certificate](#ssl-certificate)
* [Reports](#reports) * [Checking Full Body](#checking-full-body)
* [HTML Report](#html-report) * [Testing Redirections](#testing-redirections)
* [JSON Report](#json-report) * [Debug Tips](#debug-tips)
* [JUnit Report](#junit-report) * [Verbose Mode](#verbose-mode)
* [TAP Report](#tap-report) * [Error Format](#error-format)
* [JSON Output](#json-output) * [Output Response Body](#output-response-body)
* [Others](#others) * [Export curl Commands](#export-curl-commands)
* [HTTP Version](#http-version) * [Using Proxy](#using-proxy)
* [Polling and Retry](#polling-and-retry) * [Reports](#reports)
* [Delaying Requests](#delaying-requests) * [HTML Report](#html-report)
* [Skipping Requests](#skipping-requests) * [JSON Report](#json-report)
* [Testing Endpoint Performance](#testing-endpoint-performance) * [JUnit Report](#junit-report)
* [Using SOAP APIs](#using-soap-apis) * [TAP Report](#tap-report)
* [Capturing and Using a CSRF Token](#capturing-and-using-a-csrf-token) * [JSON Output](#json-output)
* [Checking Byte Order Mark (BOM) in Response Body](#checking-byte-order-mark-bom-in-response-body) * [Others](#others)
* [AWS Signature Version 4 Requests](#aws-signature-version-4-requests) * [HTTP Version](#http-version)
* [Using curl Options](#using-curl-options) * [IP Address](#ip-address)
* [Manual](#manual) * [Polling and Retry](#polling-and-retry)
* [Name](#name) * [Delaying Requests](#delaying-requests)
* [Synopsis](#synopsis) * [Skipping Requests](#skipping-requests)
* [Description](#description) * [Testing Endpoint Performance](#testing-endpoint-performance)
* [Hurl File Format](#hurl-file-format) * [Using SOAP APIs](#using-soap-apis)
* [Capturing values](#capturing-values) * [Capturing and Using a CSRF Token](#capturing-and-using-a-csrf-token)
* [Asserts](#asserts) * [Redacting Secrets](#redacting-secrets)
* [Options](#options) * [Checking Byte Order Mark (BOM) in Response Body](#checking-byte-order-mark-bom-in-response-body)
* [Environment](#environment) * [AWS Signature Version 4 Requests](#aws-signature-version-4-requests)
* [Exit Codes](#exit-codes) * [Using curl Options](#using-curl-options)
* [WWW](#www) * [Manual](#manual)
* [See Also](#see-also) * [Name](#name)
* [Installation](#installation) * [Synopsis](#synopsis)
* [Binaries Installation](#binaries-installation) * [Description](#description)
* [Linux](#linux) * [Hurl File Format](#hurl-file-format)
* [Capturing values](#capturing-values)
* [Asserts](#asserts)
* [Options](#options)
* [Environment](#environment)
* [Exit Codes](#exit-codes)
* [WWW](#www)
* [See Also](#see-also)
* [Installation](#installation)
* [Binaries Installation](#binaries-installation)
* [Linux](#linux)
* [Debian / Ubuntu](#debian--ubuntu) * [Debian / Ubuntu](#debian--ubuntu)
* [Alpine](#alpine) * [Alpine](#alpine)
* [Arch Linux / Manjaro](#arch-linux--manjaro) * [Arch Linux / Manjaro](#arch-linux--manjaro)
* [NixOS / Nix](#nixos--nix) * [NixOS / Nix](#nixos--nix)
* [macOS](#macos) * [macOS](#macos)
* [Homebrew](#homebrew) * [Homebrew](#homebrew)
* [MacPorts](#macports) * [MacPorts](#macports)
* [FreeBSD](#freebsd) * [FreeBSD](#freebsd)
* [Windows](#windows) * [Windows](#windows)
* [Zip File](#zip-file) * [Zip File](#zip-file)
* [Installer](#installer) * [Installer](#installer)
* [Chocolatey](#chocolatey) * [Chocolatey](#chocolatey)
* [Scoop](#scoop) * [Scoop](#scoop)
* [Windows Package Manager](#windows-package-manager) * [Windows Package Manager](#windows-package-manager)
* [Cargo](#cargo) * [Cargo](#cargo)
* [conda-forge](#conda-forge) * [conda-forge](#conda-forge)
* [Docker](#docker) * [Docker](#docker)
* [npm](#npm) * [npm](#npm)
* [Building From Sources](#building-from-sources) * [Building From Sources](#building-from-sources)
* [Build on Linux](#build-on-linux) * [Build on Linux](#build-on-linux)
* [Debian based distributions](#debian-based-distributions) * [Debian based distributions](#debian-based-distributions)
* [Fedora based distributions](#fedora-based-distributions) * [Fedora based distributions](#fedora-based-distributions)
* [Red Hat based distributions](#red-hat-based-distributions) * [Red Hat based distributions](#red-hat-based-distributions)
* [Arch based distributions](#arch-based-distributions) * [Arch based distributions](#arch-based-distributions)
* [Alpine based distributions](#alpine-based-distributions) * [Alpine based distributions](#alpine-based-distributions)
* [Build on macOS](#build-on-macos) * [Build on macOS](#build-on-macos)
* [Build on Windows](#build-on-windows) * [Build on Windows](#build-on-windows)
# Samples # Samples
To run a sample, edit a file with the sample content, and run Hurl: To run a sample, edit a file with the sample content, and run Hurl:
@ -278,7 +292,7 @@ oriented output, you can use [`--test` option]:
$ hurl --test sample.hurl $ hurl --test sample.hurl
``` ```
A particular response can be saved with [`[Options] section`][option]: A particular response can be saved with [`[Options] section`](https://hurl.dev/docs/request.html#options):
```hurl ```hurl
GET https://example.ord/cats/123 GET https://example.ord/cats/123
@ -337,7 +351,7 @@ Connection: keep-alive
```hurl ```hurl
GET https://example.org/news GET https://example.org/news
[QueryStringParams] [Query]
order: newest order: newest
search: something to search search: something to search
count: 100 count: 100
@ -349,7 +363,7 @@ Or:
GET https://example.org/news?order=newest&search=something%20to%20search&count=100 GET https://example.org/news?order=newest&search=something%20to%20search&count=100
``` ```
> With `[QueryStringParams]` section, params don't need to be URL escaped. > With `[Query]` section, params don't need to be URL escaped.
[Doc](https://hurl.dev/docs/request.html#query-parameters) [Doc](https://hurl.dev/docs/request.html#query-parameters)
@ -414,7 +428,7 @@ HTTP 200
```hurl ```hurl
POST https://example.org/contact POST https://example.org/contact
[FormParams] [Form]
default: false default: false
token: {{token}} token: {{token}}
email: john.doe@rookie.org email: john.doe@rookie.org
@ -427,7 +441,7 @@ number: 33611223344
```hurl ```hurl
POST https://example.org/upload POST https://example.org/upload
[MultipartFormData] [Multipart]
field1: value1 field1: value1
field2: file,example.txt; field2: file,example.txt;
# One can specify the file content type: # One can specify the file content type:
@ -464,8 +478,6 @@ In that case, files have to be inlined in the Hurl file.
[Doc](https://hurl.dev/docs/request.html#multiline-string-body) [Doc](https://hurl.dev/docs/request.html#multiline-string-body)
### Posting a JSON Body ### Posting a JSON Body
With an inline JSON: With an inline JSON:
@ -585,6 +597,32 @@ GraphQL queries can also use [Hurl templates].
[Doc](https://hurl.dev/docs/request.html#graphql-body) [Doc](https://hurl.dev/docs/request.html#graphql-body)
### Using Dynamic Datas
[Functions] like `newUuid` and `newDate` can be used in templates to create dynamic datas:
A file that creates a dynamic email (i.e `0531f78f-7f87-44be-a7f2-969a1c4e6d97@test.com`):
```hurl
POST https://example.org/api/foo
{
"name": "foo",
"email": "{{newUuid}}@test.com"
}
```
A file that creates a dynamic query parameter (i.e `2024-12-02T10:35:44.461731Z`):
```hurl
GET https://example.org/api/foo
[Query]
date: {{newDate}}
HTTP 200
```
[Doc](https://hurl.dev/docs/templates.html#functions)
## Testing Response ## Testing Response
Responses are optional, everything after `HTTP` is part of the response asserts. Responses are optional, everything after `HTTP` is part of the response asserts.
@ -624,7 +662,6 @@ status < 300
[Doc](https://hurl.dev/docs/asserting-response.html#status-assert) [Doc](https://hurl.dev/docs/asserting-response.html#status-assert)
### Testing Response Headers ### Testing Response Headers
Use implicit response asserts to test header values: Use implicit response asserts to test header values:
@ -671,19 +708,20 @@ screencapability: low
HTTP 200 HTTP 200
[Asserts] [Asserts]
jsonpath "$.validated" == true jsonpath "$.validated" == true
jsonpath "$.userInfo" isObject
jsonpath "$.userInfo.firstName" == "Franck" jsonpath "$.userInfo.firstName" == "Franck"
jsonpath "$.userInfo.lastName" == "Herbert" jsonpath "$.userInfo.lastName" == "Herbert"
jsonpath "$.hasDevice" == false jsonpath "$.hasDevice" == false
jsonpath "$.links" count == 12 jsonpath "$.links" count == 12
jsonpath "$.state" != null jsonpath "$.state" != null
jsonpath "$.order" matches "^order-\\d{8}$" jsonpath "$.order" matches "^order-\\d{8}$"
jsonpath "$.order" matches /^order-\d{8}$/ # Alternative syntax with regex literal jsonpath "$.order" matches /^order-\d{8}$/ # Alternative syntax with regex literal
jsonpath "$.id" matches /(?i)[a-z]*/ # See syntax for flags <https://docs.rs/regex/latest/regex/#grouping-and-flags>
jsonpath "$.created" isIsoDate jsonpath "$.created" isIsoDate
``` ```
[Doc](https://hurl.dev/docs/asserting-response.html#jsonpath-assert) [Doc](https://hurl.dev/docs/asserting-response.html#jsonpath-assert)
### Testing HTML Response ### Testing HTML Response
```hurl ```hurl
@ -742,6 +780,8 @@ certificate "Subject" == "CN=example.org"
certificate "Issuer" == "C=US, O=Let's Encrypt, CN=R3" certificate "Issuer" == "C=US, O=Let's Encrypt, CN=R3"
certificate "Expire-Date" daysAfterNow > 15 certificate "Expire-Date" daysAfterNow > 15
certificate "Serial-Number" matches /[\da-f]+/ certificate "Serial-Number" matches /[\da-f]+/
certificate "Subject-Alt-Name" contains "DNS:example.org"
certificate "Subject-Alt-Name" split "," count == 2
``` ```
[Doc](https://hurl.dev/docs/asserting-response.html#ssl-certificate-assert) [Doc](https://hurl.dev/docs/asserting-response.html#ssl-certificate-assert)
@ -832,6 +872,123 @@ file,data.bin;
[Doc](https://hurl.dev/docs/asserting-response.html#file-body) [Doc](https://hurl.dev/docs/asserting-response.html#file-body)
### Testing Redirections
By default, Hurl doesn't follow redirection so each step of a redirect must be run manually and can be analysed:
```hurl
GET https://example.org/step1
HTTP 301
[Asserts]
header "Location" == "https://example.org/step2"
GET https://example.org/step2
HTTP 301
[Asserts]
header "Location" == "https://example.org/step3"
GET https://example.org/step3
HTTP 200
```
[Doc](https://hurl.dev/docs/asserting-response.html)
Using [`--location`] and [`--location-trusted`] (either with command line option or per request), Hurl follows
redirection and each step of the redirection can be checked.
```hurl
GET https://example.org/step1
[Options]
location: true
HTTP 200
[Asserts]
redirects count == 2
redirects nth 0 location == "https://example.org/step2"
redirects nth 1 location == "https://example.org/step3"
```
```hurl
GET https://example.org/step1
[Options]
location-trusted: true
HTTP 200
[Asserts]
redirects last location == "https://example.org/step2"
```
[Doc](https://hurl.dev/docs/asserting-response.html#redirects-assert)
## Debug Tips
### Verbose Mode
To get more info on a given request/response, use [`[Options]` section](https://hurl.dev/docs/request.html#options):
```hurl
GET https://example.org
HTTP 200
GET https://example.org/api/cats/123
[Options]
very-verbose: true
HTTP 200
```
`--verbose` and `--very-verbose` can be also used globally as command line options.
[Doc](https://hurl.dev/docs/manual.html#very-verbose)
### Error Format
```shell
$ hurl --test --error-format long *.hurl
```
[Doc](https://hurl.dev/docs/manual.html#error-format)
### Output Response Body
Use `--output` on a specific request to get the response body (`-` can be used as standard output):
```hurl
GET https://foo.com/failure
[Options]
# use - to output on standard output, foo.bin to save on disk
output: -
HTTP 200
GET https://foo.com/success
HTTP 200
```
[Doc](https://hurl.dev/docs/manual.html#output)
### Export curl Commands
```shell
$ hurl ---curl /tmp/curl.txt *.hurl
```
[Doc](https://hurl.dev/docs/manual.html#curl)
### Using Proxy
Use `--proxy` on a specific request or globally as command line option:
```hurl
GET https://foo.com/a
HTTP 200
GET https://foo.com/b
[Options]
proxy: localhost:8888
HTTP 200
GET https://foo.com/c
HTTP 200
```
## Reports ## Reports
@ -851,7 +1008,6 @@ $ hurl --test --report-json build/report/ *.hurl
[Doc](https://hurl.dev/docs/running-tests.html#generating-report) [Doc](https://hurl.dev/docs/running-tests.html#generating-report)
### JUnit Report ### JUnit Report
```shell ```shell
@ -877,12 +1033,11 @@ A structured output of running Hurl files can be obtained with [`--json` option]
$ hurl --json *.hurl $ hurl --json *.hurl
``` ```
## Others ## Others
### HTTP Version ### HTTP Version
Testing HTTP version (HTTP/1.0, HTTP/1.1, HTTP/2 or HTTP/3): Testing HTTP version (HTTP/1.0, HTTP/1.1, HTTP/2 or HTTP/3) can be done using implicit asserts:
```hurl ```hurl
GET https://foo.com GET https://foo.com
@ -894,6 +1049,36 @@ HTTP/2 200
[Doc](https://hurl.dev/docs/asserting-response.html#version-status) [Doc](https://hurl.dev/docs/asserting-response.html#version-status)
Or explicit:
```hurl
GET https://foo.com
HTTP 200
[Asserts]
version == "3"
GET https://bar.com
HTTP 200
[Asserts]
version == "2"
version toFloat > 1.1
```
[Doc](https://hurl.dev/docs/asserting-response.html#version-assert)
### IP Address
Testing the IP address of the response, as a string. This string may be IPv6 address:
```hurl
GET https://foo.com
HTTP 200
[Asserts]
ip == "2001:0db8:85a3:0000:0000:8a2e:0370:733"
ip startsWith "2001"
ip isIpv6
```
### Polling and Retry ### Polling and Retry
Retry request on any errors (asserts, captures, status code, runtime etc...): Retry request on any errors (asserts, captures, status code, runtime etc...):
@ -925,7 +1110,7 @@ jsonpath "$.state" == "COMPLETED"
Add delay for every request, or a particular request: Add delay for every request, or a particular request:
```hurl ```hurl
# Delaying this request by 5 seconds # Delaying this request by 5 seconds (aka sleep)
GET https://example.org/turtle GET https://example.org/turtle
[Options] [Options]
delay: 5s delay: 5s
@ -955,7 +1140,6 @@ GET https://example.org/d
[Doc](https://hurl.dev/docs/manual.html#skip) [Doc](https://hurl.dev/docs/manual.html#skip)
### Testing Endpoint Performance ### Testing Endpoint Performance
```hurl ```hurl
@ -1003,6 +1187,47 @@ HTTP 302
[Doc](https://hurl.dev/docs/capturing-response.html#xpath-capture) [Doc](https://hurl.dev/docs/capturing-response.html#xpath-capture)
### Redacting Secrets
Using command-line for known values:
```shell
$ hurl --secret token=1234 file.hurl
```
```hurl
POST https://example.org
X-Token: {{token}}
{
"name": "Alice",
"value": 100
}
HTTP 200
```
[Doc](https://hurl.dev/docs/templates.html#secrets)
Using `redact` for dynamic values:
```hurl
# Get an authorization token:
GET https://example.org/token
HTTP 200
[Captures]
token: header "X-Token" redact
# Send an authorized request:
POST https://example.org
X-Token: {{token}}
{
"name": "Alice",
"value": 100
}
HTTP 200
```
[Doc](https://hurl.dev/docs/capturing-response.html#redacting-secrets)
### Checking Byte Order Mark (BOM) in Response Body ### Checking Byte Order Mark (BOM) in Response Body
```hurl ```hurl
@ -1022,19 +1247,19 @@ Generate signed API requests with [AWS Signature Version 4], as used by several
POST https://sts.eu-central-1.amazonaws.com/ POST https://sts.eu-central-1.amazonaws.com/
[Options] [Options]
aws-sigv4: aws:amz:eu-central-1:sts aws-sigv4: aws:amz:eu-central-1:sts
[FormParams] [Form]
Action: GetCallerIdentity Action: GetCallerIdentity
Version: 2011-06-15 Version: 2011-06-15
``` ```
The Access Key is given per [`--user`], either with command line option or within the [`[Options]`][option] section: The Access Key is given per [`--user`], either with command line option or within the [`[Options]`](https://hurl.dev/docs/request.html#options) section:
```hurl ```hurl
POST https://sts.eu-central-1.amazonaws.com/ POST https://sts.eu-central-1.amazonaws.com/
[Options] [Options]
aws-sigv4: aws:amz:eu-central-1:sts aws-sigv4: aws:amz:eu-central-1:sts
user: bob=secret user: bob=secret
[FormParams] [Form]
Action: GetCallerIdentity Action: GetCallerIdentity
Version: 2011-06-15 Version: 2011-06-15
``` ```
@ -1050,7 +1275,7 @@ to each request of an Hurl file.
$ hurl --resolve foo.com:8000:127.0.0.1 foo.hurl $ hurl --resolve foo.com:8000:127.0.0.1 foo.hurl
``` ```
Use [`[Options]` section][option] to configure a specific request: Use [`[Options]` section](https://hurl.dev/docs/request.html#options) to configure a specific request:
```hurl ```hurl
GET http://bar.com GET http://bar.com
@ -1216,71 +1441,81 @@ HTTP 200
will follow a redirection only for the second entry. will follow a redirection only for the second entry.
| Option | Description | | Option | Description |
|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| <a href="#aws-sigv4" id="aws-sigv4"><code>--aws-sigv4 &lt;PROVIDER1[:PROVIDER2[:REGION[:SERVICE]]]&gt;</code></a> | Generate an `Authorization` header with an AWS SigV4 signature.<br><br>Use [`-u, --user`](#user) to specify Access Key Id (username) and Secret Key (password).<br><br>To use temporary session credentials (e.g. for an AWS IAM Role), add the `X-Amz-Security-Token` header containing the session token.<br> | | <a href="#aws-sigv4" id="aws-sigv4"><code>--aws-sigv4 &lt;PROVIDER1[:PROVIDER2[:REGION[:SERVICE]]]&gt;</code></a> | Generate an `Authorization` header with an AWS SigV4 signature.<br><br>Use [`-u, --user`](#user) to specify Access Key Id (username) and Secret Key (password).<br><br>To use temporary session credentials (e.g. for an AWS IAM Role), add the `X-Amz-Security-Token` header containing the session token.<br> |
| <a href="#cacert" id="cacert"><code>--cacert &lt;FILE&gt;</code></a> | Specifies the certificate file for peer verification. The file may contain multiple CA certificates and must be in PEM format.<br>Normally Hurl is built to use a default file for this, so this option is typically used to alter that default file.<br> | | <a href="#cacert" id="cacert"><code>--cacert &lt;FILE&gt;</code></a> | Specifies the certificate file for peer verification. The file may contain multiple CA certificates and must be in PEM format.<br>Normally Hurl is built to use a default file for this, so this option is typically used to alter that default file.<br> |
| <a href="#cert" id="cert"><code>-E, --cert &lt;CERTIFICATE[:PASSWORD]&gt;</code></a> | Client certificate file and password.<br><br>See also [`--key`](#key).<br> | | <a href="#cert" id="cert"><code>-E, --cert &lt;CERTIFICATE[:PASSWORD]&gt;</code></a> | Client certificate file and password.<br><br>See also [`--key`](#key).<br> |
| <a href="#color" id="color"><code>--color</code></a> | Colorize debug output (the HTTP response output is not colorized).<br><br>This is a cli-only option.<br> | | <a href="#color" id="color"><code>--color</code></a> | Colorize debug output (the HTTP response output is not colorized).<br><br>This is a cli-only option.<br> |
| <a href="#compressed" id="compressed"><code>--compressed</code></a> | Request a compressed response using one of the algorithms br, gzip, deflate and automatically decompress the content.<br> | | <a href="#compressed" id="compressed"><code>--compressed</code></a> | Request a compressed response using one of the algorithms br, gzip, deflate and automatically decompress the content.<br> |
| <a href="#connect-timeout" id="connect-timeout"><code>--connect-timeout &lt;SECONDS&gt;</code></a> | Maximum time in seconds that you allow Hurl's connection to take.<br><br>You can specify time units in the connect timeout expression. Set Hurl to use a connect timeout of 20 seconds with `--connect-timeout 20s` or set it to 35,000 milliseconds with `--connect-timeout 35000ms`. No spaces allowed.<br><br>See also [`-m, --max-time`](#max-time).<br><br>This is a cli-only option.<br> | | <a href="#connect-timeout" id="connect-timeout"><code>--connect-timeout &lt;SECONDS&gt;</code></a> | Maximum time in seconds that you allow Hurl's connection to take.<br><br>You can specify time units in the connect timeout expression. Set Hurl to use a connect timeout of 20 seconds with `--connect-timeout 20s` or set it to 35,000 milliseconds with `--connect-timeout 35000ms`. No spaces allowed.<br><br>See also [`-m, --max-time`](#max-time).<br> |
| <a href="#connect-to" id="connect-to"><code>--connect-to &lt;HOST1:PORT1:HOST2:PORT2&gt;</code></a> | For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead. This option can be used several times in a command line.<br><br>See also [`--resolve`](#resolve).<br> | | <a href="#connect-to" id="connect-to"><code>--connect-to &lt;HOST1:PORT1:HOST2:PORT2&gt;</code></a> | For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead. This option can be used several times in a command line.<br><br>See also [`--resolve`](#resolve).<br> |
| <a href="#continue-on-error" id="continue-on-error"><code>--continue-on-error</code></a> | Continue executing requests to the end of the Hurl file even when an assert error occurs.<br>By default, Hurl exits after an assert error in the HTTP response.<br><br>Note that this option does not affect the behavior with multiple input Hurl files.<br><br>All the input files are executed independently. The result of one file does not affect the execution of the other Hurl files.<br><br>This is a cli-only option.<br> | | <a href="#continue-on-error" id="continue-on-error"><code>--continue-on-error</code></a> | Continue executing requests to the end of the Hurl file even when an assert error occurs.<br>By default, Hurl exits after an assert error in the HTTP response.<br><br>Note that this option does not affect the behavior with multiple input Hurl files.<br><br>All the input files are executed independently. The result of one file does not affect the execution of the other Hurl files.<br><br>This is a cli-only option.<br> |
| <a href="#cookie" id="cookie"><code>-b, --cookie &lt;FILE&gt;</code></a> | Read cookies from FILE (using the Netscape cookie file format).<br><br>Combined with [`-c, --cookie-jar`](#cookie-jar), you can simulate a cookie storage between successive Hurl runs.<br><br>This is a cli-only option.<br> | | <a href="#cookie" id="cookie"><code>-b, --cookie &lt;FILE&gt;</code></a> | Read cookies from FILE (using the Netscape cookie file format).<br><br>Combined with [`-c, --cookie-jar`](#cookie-jar), you can simulate a cookie storage between successive Hurl runs.<br><br>This is a cli-only option.<br> |
| <a href="#cookie-jar" id="cookie-jar"><code>-c, --cookie-jar &lt;FILE&gt;</code></a> | Write cookies to FILE after running the session (only for one session).<br>The file will be written using the Netscape cookie file format.<br><br>Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage between successive Hurl runs.<br><br>This is a cli-only option.<br> | | <a href="#cookie-jar" id="cookie-jar"><code>-c, --cookie-jar &lt;FILE&gt;</code></a> | Write cookies to FILE after running the session.<br>The file will be written using the Netscape cookie file format.<br><br>Combined with [`-b, --cookie`](#cookie), you can simulate a cookie storage between successive Hurl runs.<br><br>This is a cli-only option.<br> |
| <a href="#delay" id="delay"><code>--delay &lt;MILLISECONDS&gt;</code></a> | Sets delay before each request. The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.<br><br>You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. No spaces allowed.<br> | | <a href="#curl" id="curl"><code>--curl &lt;FILE&gt;</code></a> | Export each request to a list of curl commands.<br><br>This is a cli-only option.<br> |
| <a href="#error-format" id="error-format"><code>--error-format &lt;FORMAT&gt;</code></a> | Control the format of error message (short by default or long)<br><br>This is a cli-only option.<br> | | <a href="#delay" id="delay"><code>--delay &lt;MILLISECONDS&gt;</code></a> | Sets delay before each request (aka sleep). The delay is not applied to requests that have been retried because of [`--retry`](#retry). See [`--retry-interval`](#retry-interval) to space retried requests.<br><br>You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. Supported time units: ms, s, m, h. No spaces allowed.<br> |
| <a href="#file-root" id="file-root"><code>--file-root &lt;DIR&gt;</code></a> | Set root directory to import files in Hurl. This is used for files in multipart form data, request body and response output.<br>When it is not explicitly defined, files are relative to the Hurl file's directory.<br><br>This is a cli-only option.<br> | | <a href="#error-format" id="error-format"><code>--error-format &lt;FORMAT&gt;</code></a> | Control the format of error message (short by default or long)<br><br>This is a cli-only option.<br> |
| <a href="#from-entry" id="from-entry"><code>--from-entry &lt;ENTRY_NUMBER&gt;</code></a> | Execute Hurl file from ENTRY_NUMBER (starting at 1).<br><br>This is a cli-only option.<br> | | <a href="#file-root" id="file-root"><code>--file-root &lt;DIR&gt;</code></a> | Set root directory to import files in Hurl. This is used for files in multipart form data, request body and response output.<br>When it is not explicitly defined, files are relative to the Hurl file's directory.<br><br>This is a cli-only option.<br> |
| <a href="#glob" id="glob"><code>--glob &lt;GLOB&gt;</code></a> | Specify input files that match the given glob pattern.<br><br>Multiple glob flags may be used. This flag supports common Unix glob patterns like *, ? and [].<br>However, to avoid your shell accidentally expanding glob patterns before Hurl handles them, you must use single quotes or double quotes around each pattern.<br><br>This is a cli-only option.<br> | | <a href="#from-entry" id="from-entry"><code>--from-entry &lt;ENTRY_NUMBER&gt;</code></a> | Execute Hurl file from ENTRY_NUMBER (starting at 1).<br><br>This is a cli-only option.<br> |
| <a href="#http10" id="http10"><code>-0, --http1.0</code></a> | Tells Hurl to use HTTP version 1.0 instead of using its internally preferred HTTP version.<br> | | <a href="#glob" id="glob"><code>--glob &lt;GLOB&gt;</code></a> | Specify input files that match the given glob pattern.<br><br>Multiple glob flags may be used. This flag supports common Unix glob patterns like *, ? and [].<br>However, to avoid your shell accidentally expanding glob patterns before Hurl handles them, you must use single quotes or double quotes around each pattern.<br><br>This is a cli-only option.<br> |
| <a href="#http11" id="http11"><code>--http1.1</code></a> | Tells Hurl to use HTTP version 1.1.<br> | | <a href="#header" id="header"><code>-H, --header &lt;HEADER&gt;</code></a> | Add an extra header to include in information sent. Can be used several times in a command<br><br>Do not add newlines or carriage returns<br> |
| <a href="#http2" id="http2"><code>--http2</code></a> | Tells Hurl to use HTTP version 2.<br>For HTTPS, this means Hurl negotiates HTTP/2 in the TLS handshake. Hurl does this by default.<br>For HTTP, this means Hurl attempts to upgrade the request to HTTP/2 using the Upgrade: request header.<br> | | <a href="#http10" id="http10"><code>-0, --http1.0</code></a> | Tells Hurl to use HTTP version 1.0 instead of using its internally preferred HTTP version.<br> |
| <a href="#http3" id="http3"><code>--http3</code></a> | Tells Hurl to try HTTP/3 to the host in the URL, but fallback to earlier HTTP versions if the HTTP/3 connection establishment fails. HTTP/3 is only available for HTTPS and not for HTTP URLs.<br> | | <a href="#http11" id="http11"><code>--http1.1</code></a> | Tells Hurl to use HTTP version 1.1.<br> |
| <a href="#ignore-asserts" id="ignore-asserts"><code>--ignore-asserts</code></a> | Ignore all asserts defined in the Hurl file.<br><br>This is a cli-only option.<br> | | <a href="#http2" id="http2"><code>--http2</code></a> | Tells Hurl to use HTTP version 2.<br>For HTTPS, this means Hurl negotiates HTTP/2 in the TLS handshake. Hurl does this by default.<br>For HTTP, this means Hurl attempts to upgrade the request to HTTP/2 using the Upgrade: request header.<br> |
| <a href="#include" id="include"><code>-i, --include</code></a> | Include the HTTP headers in the output<br><br>This is a cli-only option.<br> | | <a href="#http3" id="http3"><code>--http3</code></a> | Tells Hurl to try HTTP/3 to the host in the URL, but fallback to earlier HTTP versions if the HTTP/3 connection establishment fails. HTTP/3 is only available for HTTPS and not for HTTP URLs.<br> |
| <a href="#insecure" id="insecure"><code>-k, --insecure</code></a> | This option explicitly allows Hurl to perform "insecure" SSL connections and transfers.<br> | | <a href="#ignore-asserts" id="ignore-asserts"><code>--ignore-asserts</code></a> | Ignore all asserts defined in the Hurl file.<br><br>This is a cli-only option.<br> |
| <a href="#interactive" id="interactive"><code>--interactive</code></a> | Stop between requests.<br><br>This is similar to a break point, You can then continue (Press C) or quit (Press Q).<br><br>This is a cli-only option.<br> | | <a href="#include" id="include"><code>-i, --include</code></a> | Include the HTTP headers in the output<br><br>This is a cli-only option.<br> |
| <a href="#ipv4" id="ipv4"><code>-4, --ipv4</code></a> | This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.<br> | | <a href="#insecure" id="insecure"><code>-k, --insecure</code></a> | This option explicitly allows Hurl to perform "insecure" SSL connections and transfers.<br> |
| <a href="#ipv6" id="ipv6"><code>-6, --ipv6</code></a> | This option tells Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4.<br> | | <a href="#ipv4" id="ipv4"><code>-4, --ipv4</code></a> | This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.<br> |
| <a href="#jobs" id="jobs"><code>--jobs &lt;NUM&gt;</code></a> | Maximum number of parallel jobs in parallel mode. Default value corresponds (in most cases) to the<br>current amount of CPUs.<br><br>See also [`--parallel`](#parallel).<br><br>This is a cli-only option.<br> | | <a href="#ipv6" id="ipv6"><code>-6, --ipv6</code></a> | This option tells Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4.<br> |
| <a href="#json" id="json"><code>--json</code></a> | Output each Hurl file result to JSON. The format is very closed to HAR format.<br><br>This is a cli-only option.<br> | | <a href="#jobs" id="jobs"><code>--jobs &lt;NUM&gt;</code></a> | Maximum number of parallel jobs in parallel mode. Default value corresponds (in most cases) to the<br>current amount of CPUs.<br><br>See also [`--parallel`](#parallel).<br><br>This is a cli-only option.<br> |
| <a href="#key" id="key"><code>--key &lt;KEY&gt;</code></a> | Private key file name.<br> | | <a href="#json" id="json"><code>--json</code></a> | Output each Hurl file result to JSON. The format is very closed to HAR format.<br><br>This is a cli-only option.<br> |
| <a href="#location" id="location"><code>-L, --location</code></a> | Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option<br> | | <a href="#key" id="key"><code>--key &lt;KEY&gt;</code></a> | Private key file name.<br> |
| <a href="#location-trusted" id="location-trusted"><code>--location-trusted</code></a> | Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.<br>This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).<br> | | <a href="#limit-rate" id="limit-rate"><code>--limit-rate &lt;SPEED&gt;</code></a> | Specify the maximum transfer rate you want Hurl to use, for both downloads and uploads. This feature is useful if you have a limited pipe and you would like your transfer not to use your entire bandwidth. To make it slower than it otherwise would be.<br>The given speed is measured in bytes/second.<br> |
| <a href="#max-filesize" id="max-filesize"><code>--max-filesize &lt;BYTES&gt;</code></a> | Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start.<br><br>This is a cli-only option.<br> | | <a href="#location" id="location"><code>-L, --location</code></a> | Follow redirect. To limit the amount of redirects to follow use the [`--max-redirs`](#max-redirs) option<br> |
| <a href="#max-redirs" id="max-redirs"><code>--max-redirs &lt;NUM&gt;</code></a> | Set maximum number of redirection-followings allowed<br><br>By default, the limit is set to 50 redirections. Set this option to -1 to make it unlimited.<br> | | <a href="#location-trusted" id="location-trusted"><code>--location-trusted</code></a> | Like [`-L, --location`](#location), but allows sending the name + password to all hosts that the site may redirect to.<br>This may or may not introduce a security breach if the site redirects you to a site to which you send your authentication info (which is plaintext in the case of HTTP Basic authentication).<br> |
| <a href="#max-time" id="max-time"><code>-m, --max-time &lt;SECONDS&gt;</code></a> | Maximum time in seconds that you allow a request/response to take. This is the standard timeout.<br><br>You can specify time units in the maximum time expression. Set Hurl to use a maximum time of 20 seconds with `--max-time 20s` or set it to 35,000 milliseconds with `--max-time 35000ms`. No spaces allowed.<br><br>See also [`--connect-timeout`](#connect-timeout).<br><br>This is a cli-only option.<br> | | <a href="#max-filesize" id="max-filesize"><code>--max-filesize &lt;BYTES&gt;</code></a> | Specify the maximum size in bytes of a file to download. If the file requested is larger than this value, the transfer does not start.<br><br>This is a cli-only option.<br> |
| <a href="#netrc" id="netrc"><code>-n, --netrc</code></a> | Scan the .netrc file in the user's home directory for the username and password.<br><br>See also [`--netrc-file`](#netrc-file) and [`--netrc-optional`](#netrc-optional).<br> | | <a href="#max-redirs" id="max-redirs"><code>--max-redirs &lt;NUM&gt;</code></a> | Set maximum number of redirection-followings allowed<br><br>By default, the limit is set to 50 redirections. Set this option to -1 to make it unlimited.<br> |
| <a href="#netrc-file" id="netrc-file"><code>--netrc-file &lt;FILE&gt;</code></a> | Like [`--netrc`](#netrc), but provide the path to the netrc file.<br><br>See also [`--netrc-optional`](#netrc-optional).<br> | | <a href="#max-time" id="max-time"><code>-m, --max-time &lt;SECONDS&gt;</code></a> | Maximum time in seconds that you allow a request/response to take. This is the standard timeout.<br><br>You can specify time units in the maximum time expression. Set Hurl to use a maximum time of 20 seconds with `--max-time 20s` or set it to 35,000 milliseconds with `--max-time 35000ms`. No spaces allowed.<br><br>See also [`--connect-timeout`](#connect-timeout).<br> |
| <a href="#netrc-optional" id="netrc-optional"><code>--netrc-optional</code></a> | Similar to [`--netrc`](#netrc), but make the .netrc usage optional.<br><br>See also [`--netrc-file`](#netrc-file).<br> | | <a href="#negotiate" id="negotiate"><code>--negotiate</code></a> | Tell Hurl to use Negotiate (SPNEGO) authentication.<br> |
| <a href="#no-color" id="no-color"><code>--no-color</code></a> | Do not colorize output.<br><br>This is a cli-only option.<br> | | <a href="#netrc" id="netrc"><code>-n, --netrc</code></a> | Scan the .netrc file in the user's home directory for the username and password.<br><br>See also [`--netrc-file`](#netrc-file) and [`--netrc-optional`](#netrc-optional).<br> |
| <a href="#no-output" id="no-output"><code>--no-output</code></a> | Suppress output. By default, Hurl outputs the body of the last response.<br><br>This is a cli-only option.<br> | | <a href="#netrc-file" id="netrc-file"><code>--netrc-file &lt;FILE&gt;</code></a> | Like [`--netrc`](#netrc), but provide the path to the netrc file.<br><br>See also [`--netrc-optional`](#netrc-optional).<br> |
| <a href="#noproxy" id="noproxy"><code>--noproxy &lt;HOST(S)&gt;</code></a> | Comma-separated list of hosts which do not use a proxy.<br><br>Override value from Environment variable no_proxy.<br> | | <a href="#netrc-optional" id="netrc-optional"><code>--netrc-optional</code></a> | Similar to [`--netrc`](#netrc), but make the .netrc usage optional.<br><br>See also [`--netrc-file`](#netrc-file).<br> |
| <a href="#output" id="output"><code>-o, --output &lt;FILE&gt;</code></a> | Write output to FILE instead of stdout.<br> | | <a href="#no-color" id="no-color"><code>--no-color</code></a> | Do not colorize output.<br><br>This is a cli-only option.<br> |
| <a href="#parallel" id="parallel"><code>--parallel</code></a> | Run files in parallel.<br><br>Each Hurl file is executed in its own worker thread, without sharing anything with the other workers. The default run mode is sequential. Parallel execution is by default in [`--test`](#test) mode.<br><br>See also [`--jobs`](#jobs).<br><br>This is a cli-only option.<br> | | <a href="#no-output" id="no-output"><code>--no-output</code></a> | Suppress output. By default, Hurl outputs the body of the last response.<br><br>This is a cli-only option.<br> |
| <a href="#path-as-is" id="path-as-is"><code>--path-as-is</code></a> | Tell Hurl to not handle sequences of /../ or /./ in the given URL path. Normally Hurl will squash or merge them according to standards but with this option set you tell it not to do that.<br> | | <a href="#no-pretty" id="no-pretty"><code>--no-pretty</code></a> | Do not prettify response output for supported content type (JSON only for the moment). By default, output is prettified if<br>standard output is a terminal.<br><br>This is a cli-only option.<br> |
| <a href="#proxy" id="proxy"><code>-x, --proxy &lt;[PROTOCOL://]HOST[:PORT]&gt;</code></a> | Use the specified proxy.<br> | | <a href="#noproxy" id="noproxy"><code>--noproxy &lt;HOST(S)&gt;</code></a> | Comma-separated list of hosts which do not use a proxy.<br><br>Override value from Environment variable no_proxy.<br> |
| <a href="#repeat" id="repeat"><code>--repeat &lt;NUM&gt;</code></a> | Repeat the input files sequence NUM times, -1 for infinite loop. Given a.hurl, b.hurl, c.hurl as input, repeat two<br>times will run a.hurl, b.hurl, c.hurl, a.hurl, b.hurl, c.hurl.<br><br>This is a cli-only option.<br> | | <a href="#ntlm" id="ntlm"><code>--ntlm</code></a> | Tell Hurl to use NTLM authentication<br> |
| <a href="#report-html" id="report-html"><code>--report-html &lt;DIR&gt;</code></a> | Generate HTML report in DIR.<br><br>If the HTML report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> | | <a href="#output" id="output"><code>-o, --output &lt;FILE&gt;</code></a> | Write output to FILE instead of stdout. Use '-' for stdout in [Options] sections.<br> |
| <a href="#report-json" id="report-json"><code>--report-json &lt;DIR&gt;</code></a> | Generate JSON report in DIR.<br><br>If the JSON report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> | | <a href="#parallel" id="parallel"><code>--parallel</code></a> | Run files in parallel.<br><br>Each Hurl file is executed in its own worker thread, without sharing anything with the other workers. The default run mode is sequential. Parallel execution is by default in [`--test`](#test) mode.<br><br>See also [`--jobs`](#jobs).<br><br>This is a cli-only option.<br> |
| <a href="#report-junit" id="report-junit"><code>--report-junit &lt;FILE&gt;</code></a> | Generate JUnit File.<br><br>If the FILE report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> | | <a href="#path-as-is" id="path-as-is"><code>--path-as-is</code></a> | Tell Hurl to not handle sequences of /../ or /./ in the given URL path. Normally Hurl will squash or merge them according to standards but with this option set you tell it not to do that.<br> |
| <a href="#report-tap" id="report-tap"><code>--report-tap &lt;FILE&gt;</code></a> | Generate TAP report.<br><br>If the FILE report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> | | <a href="#pinnedpubkey" id="pinnedpubkey"><code>--pinnedpubkey &lt;HASHES&gt;</code></a> | When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and if it does not exactly match the public key provided to this option, Hurl aborts the connection before sending or receiving any data.<br> |
| <a href="#resolve" id="resolve"><code>--resolve &lt;HOST:PORT:ADDR&gt;</code></a> | Provide a custom address for a specific host and port pair. Using this, you can make the Hurl requests(s) use a specified address and prevent the otherwise normally resolved address to be used. Consider it a sort of /etc/hosts alternative provided on the command line.<br> | | <a href="#pretty" id="pretty"><code>--pretty</code></a> | Prettify response output for supported content type (JSON only for the moment). By default, JSON response is prettified if standard output is a terminal, and colorized, see[`--no-color`](#no-color) to format without color.<br><br>This is a cli-only option.<br> |
| <a href="#retry" id="retry"><code>--retry &lt;NUM&gt;</code></a> | Maximum number of retries, 0 for no retries, -1 for unlimited retries. Retry happens if any error occurs (asserts, captures, runtimes etc...).<br> | | <a href="#progress-bar" id="progress-bar"><code>--progress-bar</code></a> | Display a progress bar in test mode. The progress bar is displayed only in interactive TTYs. This option forces the progress bar to be displayed even in non-interactive TTYs.<br><br>This is a cli-only option.<br> |
| <a href="#retry-interval" id="retry-interval"><code>--retry-interval &lt;MILLISECONDS&gt;</code></a> | Duration in milliseconds between each retry. Default is 1000 ms.<br><br>You can specify time units in the retry interval expression. Set Hurl to use a retry interval of 2 seconds with `--retry-interval 2s` or set it to 500 milliseconds with `--retry-interval 500ms`. No spaces allowed.<br> | | <a href="#proxy" id="proxy"><code>-x, --proxy &lt;[PROTOCOL://]HOST[:PORT]&gt;</code></a> | Use the specified proxy.<br> |
| <a href="#ssl-no-revoke" id="ssl-no-revoke"><code>--ssl-no-revoke</code></a> | (Windows) This option tells Hurl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for exactly that.<br><br>This is a cli-only option.<br> | | <a href="#repeat" id="repeat"><code>--repeat &lt;NUM&gt;</code></a> | Repeat the input files sequence NUM times, -1 for infinite loop. Given a.hurl, b.hurl, c.hurl as input, repeat two<br>times will run a.hurl, b.hurl, c.hurl, a.hurl, b.hurl, c.hurl.<br> |
| <a href="#test" id="test"><code>--test</code></a> | Activate test mode: with this, the HTTP response is not outputted anymore, progress is reported for each Hurl file tested, and a text summary is displayed when all files have been run.<br><br>In test mode, files are executed in parallel. To run test in a sequential way use `--job 1`.<br><br>See also [`--jobs`](#jobs).<br><br>This is a cli-only option.<br> | | <a href="#report-html" id="report-html"><code>--report-html &lt;DIR&gt;</code></a> | Generate HTML report in DIR.<br><br>If the HTML report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> |
| <a href="#to-entry" id="to-entry"><code>--to-entry &lt;ENTRY_NUMBER&gt;</code></a> | Execute Hurl file to ENTRY_NUMBER (starting at 1).<br>Ignore the remaining of the file. It is useful for debugging a session.<br><br>This is a cli-only option.<br> | | <a href="#report-json" id="report-json"><code>--report-json &lt;DIR&gt;</code></a> | Generate JSON report in DIR.<br><br>If the JSON report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> |
| <a href="#unix-socket" id="unix-socket"><code>--unix-socket &lt;PATH&gt;</code></a> | (HTTP) Connect through this Unix domain socket, instead of using the network.<br> | | <a href="#report-junit" id="report-junit"><code>--report-junit &lt;FILE&gt;</code></a> | Generate JUnit File.<br><br>If the FILE report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> |
| <a href="#user" id="user"><code>-u, --user &lt;USER:PASSWORD&gt;</code></a> | Add basic Authentication header to each request.<br> | | <a href="#report-tap" id="report-tap"><code>--report-tap &lt;FILE&gt;</code></a> | Generate TAP report.<br><br>If the FILE report already exists, it will be updated with the new test results.<br><br>This is a cli-only option.<br> |
| <a href="#user-agent" id="user-agent"><code>-A, --user-agent &lt;NAME&gt;</code></a> | Specify the User-Agent string to send to the HTTP server.<br><br>This is a cli-only option.<br> | | <a href="#resolve" id="resolve"><code>--resolve &lt;HOST:PORT:ADDR&gt;</code></a> | Provide a custom address for a specific host and port pair. Using this, you can make the Hurl requests(s) use a specified address and prevent the otherwise normally resolved address to be used. Consider it a sort of /etc/hosts alternative provided on the command line.<br> |
| <a href="#variable" id="variable"><code>--variable &lt;NAME=VALUE&gt;</code></a> | Define variable (name/value) to be used in Hurl templates.<br> | | <a href="#retry" id="retry"><code>--retry &lt;NUM&gt;</code></a> | Maximum number of retries, 0 for no retries, -1 for unlimited retries. Retry happens if any error occurs (asserts, captures, runtimes etc...).<br> |
| <a href="#variables-file" id="variables-file"><code>--variables-file &lt;FILE&gt;</code></a> | Set properties file in which your define your variables.<br><br>Each variable is defined as name=value exactly as with [`--variable`](#variable) option.<br><br>Note that defining a variable twice produces an error.<br><br>This is a cli-only option.<br> | | <a href="#retry-interval" id="retry-interval"><code>--retry-interval &lt;MILLISECONDS&gt;</code></a> | Duration in milliseconds between each retry. Default is 1000 ms.<br><br>You can specify time units in the retry interval expression. Set Hurl to use a retry interval of 2 seconds with `--retry-interval 2s` or set it to 500 milliseconds with `--retry-interval 500ms`. No spaces allowed.<br> |
| <a href="#verbose" id="verbose"><code>-v, --verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> | | <a href="#secret" id="secret"><code>--secret &lt;NAME=VALUE&gt;</code></a> | Define secret value to be redacted from logs and report. When defined, secrets can be used as variable everywhere variables are used.<br><br>This is a cli-only option.<br> |
| <a href="#very-verbose" id="very-verbose"><code>--very-verbose</code></a> | Turn on more verbose output on standard error stream.<br><br>In contrast to [`--verbose`](#verbose) option, this option outputs the full HTTP body request and response on standard error. In addition, lines starting with '**' are libcurl debug logs.<br> | | <a href="#secrets-file" id="secrets-file"><code>--secrets-file &lt;FILE&gt;</code></a> | Define a secrets file in which you define your secrets<br><br>Each secret is defined as name=value exactly as with [`--secret`](#secret) option.<br><br>Note that defining a secret twice produces an error.<br><br>This is a cli-only option.<br> |
| <a href="#help" id="help"><code>-h, --help</code></a> | Usage help. This lists all current command line options with a short description.<br> | | <a href="#ssl-no-revoke" id="ssl-no-revoke"><code>--ssl-no-revoke</code></a> | (Windows) This option tells Hurl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for exactly that.<br><br>This is a cli-only option.<br> |
| <a href="#version" id="version"><code>-V, --version</code></a> | Prints version information<br> | | <a href="#test" id="test"><code>--test</code></a> | Activate test mode: with this, the HTTP response is not outputted anymore, progress is reported for each Hurl file tested, and a text summary is displayed when all files have been run.<br><br>In test mode, files are executed in parallel. To run test in a sequential way use `--job 1`.<br><br>See also [`--jobs`](#jobs).<br><br>This is a cli-only option.<br> |
| <a href="#to-entry" id="to-entry"><code>--to-entry &lt;ENTRY_NUMBER&gt;</code></a> | Execute Hurl file to ENTRY_NUMBER (starting at 1).<br>Ignore the remaining of the file. It is useful for debugging a session.<br><br>This is a cli-only option.<br> |
| <a href="#unix-socket" id="unix-socket"><code>--unix-socket &lt;PATH&gt;</code></a> | (HTTP) Connect through this Unix domain socket, instead of using the network.<br> |
| <a href="#user" id="user"><code>-u, --user &lt;USER:PASSWORD&gt;</code></a> | Add basic Authentication header to each request.<br> |
| <a href="#user-agent" id="user-agent"><code>-A, --user-agent &lt;NAME&gt;</code></a> | Specify the User-Agent string to send to the HTTP server.<br><br>This is a cli-only option.<br> |
| <a href="#variable" id="variable"><code>--variable &lt;NAME=VALUE&gt;</code></a> | Define variable (name/value) to be used in Hurl templates.<br> |
| <a href="#variables-file" id="variables-file"><code>--variables-file &lt;FILE&gt;</code></a> | Set properties file in which your define your variables.<br><br>Each variable is defined as name=value exactly as with [`--variable`](#variable) option.<br><br>Note that defining a variable twice produces an error.<br><br>This is a cli-only option.<br> |
| <a href="#verbose" id="verbose"><code>-v, --verbose</code></a> | Turn on verbose output on standard error stream.<br>Useful for debugging.<br><br>A line starting with '>' means data sent by Hurl.<br>A line staring with '<' means data received by Hurl.<br>A line starting with '*' means additional info provided by Hurl.<br><br>If you only want HTTP headers in the output, [`-i, --include`](#include) might be the option you're looking for.<br> |
| <a href="#very-verbose" id="very-verbose"><code>--very-verbose</code></a> | Turn on more verbose output on standard error stream.<br><br>In contrast to [`--verbose`](#verbose) option, this option outputs the full HTTP body request and response on standard error. In addition, lines starting with '**' are libcurl debug logs.<br> |
| <a href="#help" id="help"><code>-h, --help</code></a> | Usage help. This lists all current command line options with a short description.<br> |
| <a href="#version" id="version"><code>-V, --version</code></a> | Prints version information<br> |
## Environment ## Environment
@ -1288,14 +1523,15 @@ Environment variables can only be specified in lowercase.
Using an environment variable to set the proxy has the same effect as using the [`-x, --proxy`](#proxy) option. Using an environment variable to set the proxy has the same effect as using the [`-x, --proxy`](#proxy) option.
| Variable | Description | | Variable | Description |
|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| |--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `http_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use for HTTP.<br> | | `http_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use for HTTP.<br> |
| `https_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use for HTTPS.<br> | | `https_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use for HTTPS.<br> |
| `all_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use if no protocol-specific proxy is set.<br> | | `all_proxy [PROTOCOL://]<HOST>[:PORT]` | Sets the proxy server to use if no protocol-specific proxy is set.<br> |
| `no_proxy <comma-separated list of hosts>` | List of host names that shouldn't go through any proxy.<br> | | `no_proxy <comma-separated list of hosts>` | List of host names that shouldn't go through any proxy.<br> |
| `HURL_name value` | Define variable (name/value) to be used in Hurl templates. This is similar than [`--variable`](#variable) and [`--variables-file`](#variables-file) options.<br> | | `HURL_VARIABLE_name value` | Define variable (name/value) to be used in Hurl templates. This is similar to [`--variable`](#variable) and [`--variables-file`](#variables-file) options.<br> |
| `NO_COLOR` | When set to a non-empty string, do not colorize output (see [`--no-color`](#no-color) option).<br> | | `HURL_SECRET_name value` | Define secret (name/value) to be used in Hurl templates. This is similar to [`--secret`](#secret) and [`--secrets-file`](#secrets-file) options.<br> |
| `NO_COLOR` | When set to a non-empty string, do not colorize output (see [`--no-color`](#no-color) option).<br> |
## Exit Codes ## Exit Codes
@ -1322,25 +1558,33 @@ curl(1) hurlfmt(1)
### Linux ### Linux
Precompiled binary is available at [Hurl latest GitHub release]: Precompiled binary (depending on libc >=2.35) is available at [Hurl latest GitHub release]:
```shell ```shell
$ INSTALL_DIR=/tmp $ INSTALL_DIR=/tmp
$ VERSION=5.0.0 $ VERSION=7.1.0
$ curl --silent --location https://github.com/Orange-OpenSource/hurl/releases/download/$VERSION/hurl-$VERSION-x86_64-unknown-linux-gnu.tar.gz | tar xvz -C $INSTALL_DIR $ curl --silent --location https://github.com/Orange-OpenSource/hurl/releases/download/$VERSION/hurl-$VERSION-x86_64-unknown-linux-gnu.tar.gz | tar xvz -C $INSTALL_DIR
$ export PATH=$INSTALL_DIR/hurl-$VERSION-x86_64-unknown-linux-gnu/bin:$PATH $ export PATH=$INSTALL_DIR/hurl-$VERSION-x86_64-unknown-linux-gnu/bin:$PATH
``` ```
#### Debian / Ubuntu #### Debian / Ubuntu
For Debian / Ubuntu, Hurl can be installed using a binary .deb file provided in each Hurl release. For Debian >=12 / Ubuntu 22.04 and 24.04, Hurl can be installed using a binary .deb file provided in each Hurl release.
```shell ```shell
$ VERSION=5.0.0 $ VERSION=7.1.0
$ curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/$VERSION/hurl_${VERSION}_amd64.deb $ curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/$VERSION/hurl_${VERSION}_amd64.deb
$ sudo apt update && sudo apt install ./hurl_${VERSION}_amd64.deb $ sudo apt update && sudo apt install ./hurl_${VERSION}_amd64.deb
``` ```
For Ubuntu >=22.04, Hurl can be installed from `ppa:lepapareil/hurl`
```shell
$ VERSION=7.1.0
$ sudo apt-add-repository -y ppa:lepapareil/hurl
$ sudo apt install hurl="${VERSION}"*
```
#### Alpine #### Alpine
Hurl is available on `testing` channel. Hurl is available on `testing` channel.
@ -1418,7 +1662,7 @@ $ winget install hurl
If you're a Rust programmer, Hurl can be installed with cargo. If you're a Rust programmer, Hurl can be installed with cargo.
```shell ```shell
$ cargo install hurl $ cargo install --locked hurl
``` ```
### conda-forge ### conda-forge
@ -1452,31 +1696,31 @@ Hurl depends on libssl, libcurl and libxml2 native libraries. You will need thei
#### Debian based distributions #### Debian based distributions
```shell ```shell
$ apt install -y build-essential pkg-config libssl-dev libcurl4-openssl-dev libxml2-dev $ apt install -y build-essential pkg-config libssl-dev libcurl4-openssl-dev libxml2-dev libclang-dev
``` ```
#### Fedora based distributions #### Fedora based distributions
```shell ```shell
$ dnf install -y pkgconf-pkg-config gcc openssl-devel libxml2-devel $ dnf install -y pkgconf-pkg-config gcc openssl-devel libxml2-devel clang-devel
``` ```
#### Red Hat based distributions #### Red Hat based distributions
```shell ```shell
$ yum install -y pkg-config gcc openssl-devel libxml2-devel $ yum install -y pkg-config gcc openssl-devel libxml2-devel clang-devel
``` ```
#### Arch based distributions #### Arch based distributions
```shell ```shell
$ pacman -S --noconfirm pkgconf gcc glibc openssl libxml2 $ pacman -S --noconfirm pkgconf gcc glibc openssl libxml2 clang
``` ```
#### Alpine based distributions #### Alpine based distributions
```shell ```shell
$ apk add curl-dev gcc libxml2-dev musl-dev openssl-dev $ apk add curl-dev gcc libxml2-dev musl-dev openssl-dev clang-dev
``` ```
### Build on macOS ### Build on macOS
@ -1521,6 +1765,9 @@ Please follow the [contrib on Windows section].
[GitHub]: https://github.com/Orange-OpenSource/hurl [GitHub]: https://github.com/Orange-OpenSource/hurl
[libcurl]: https://curl.se/libcurl/ [libcurl]: https://curl.se/libcurl/
[star Hurl on GitHub]: https://github.com/Orange-OpenSource/hurl/stargazers [star Hurl on GitHub]: https://github.com/Orange-OpenSource/hurl/stargazers
[HTML]: /docs/standalone/hurl-7.0.0.html
[PDF]: /docs/standalone/hurl-7.0.0.pdf
[Markdown]: https://hurl.dev/docs/standalone/hurl-7.0.0.html
[JSON body]: https://hurl.dev/docs/request.html#json-body [JSON body]: https://hurl.dev/docs/request.html#json-body
[XML body]: https://hurl.dev/docs/request.html#xml-body [XML body]: https://hurl.dev/docs/request.html#xml-body
[XML multiline string body]: https://hurl.dev/docs/request.html#multiline-string-body [XML multiline string body]: https://hurl.dev/docs/request.html#multiline-string-body
@ -1539,10 +1786,12 @@ Please follow the [contrib on Windows section].
[Hurl templates]: https://hurl.dev/docs/templates.html [Hurl templates]: https://hurl.dev/docs/templates.html
[AWS Signature Version 4]: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html [AWS Signature Version 4]: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
[Captures]: https://hurl.dev/docs/capturing-response.html [Captures]: https://hurl.dev/docs/capturing-response.html
[option]: https://hurl.dev/docs/request.html#options
[`--json` option]: https://hurl.dev/docs/manual.html#json [`--json` option]: https://hurl.dev/docs/manual.html#json
[`--resolve`]: https://hurl.dev/docs/manual.html#resolve [`--resolve`]: https://hurl.dev/docs/manual.html#resolve
[`--connect-to`]: https://hurl.dev/docs/manual.html#connect-to [`--connect-to`]: https://hurl.dev/docs/manual.html#connect-to
[Functions]: https://hurl.dev/docs/templates.html#functions
[`--location`]: https://hurl.dev/docs/manual.html#location
[`--location-trusted`]: https://hurl.dev/docs/manual.html#location-trusted
[GitHub]: https://github.com/Orange-OpenSource/hurl [GitHub]: https://github.com/Orange-OpenSource/hurl
[Hurl latest GitHub release]: https://github.com/Orange-OpenSource/hurl/releases/latest [Hurl latest GitHub release]: https://github.com/Orange-OpenSource/hurl/releases/latest
[Visual C++ Redistributable Package]: https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version [Visual C++ Redistributable Package]: https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-microsoft-visual-c-redistributable-version

View File

@ -14,20 +14,20 @@ We always have to start with current version x.y.0-snapshot (in all Cargo.toml).
Used to publish a new release from master branch (normal process). Used to publish a new release from master branch (normal process).
- Run `release.yml` workflow on `master` branch - Run `release.yml` workflow on `master` branch
- Fill `Desired delivery version` input with the `x.y.z` version you want to publish, it will: - Fill `Desired delivery version` input with the `x.y.z` version you want to publish, it will:
- Clean pending release - Clean pending release
- Create new `release/x.y.0` branch - Create new `release/x.y.0` branch
- Checkout this new branch - Checkout this new branch
- Update all toml, crates, man and docs with `x.y.0` - Update all toml, crates, man and docs with `x.y.0`
- Generate CHANGELOG - Generate CHANGELOG
- Commit all updates - Commit all updates
- Create the `x.y.0` tag - Create the `x.y.0` tag
- Create draft GitHub release `x.y.0` - Create draft GitHub release `x.y.0`
- Create PR from `release/x.y.0` to `master` - Create PR from `release/x.y.0` to `master`
- Publish the draft release - Publish the draft release
- Test release on external test project
- Change the release status from draft to public on github - Change the release status from draft to public on github
- Accept the PR from `release/x.y.0` to `master` with `/accept` - Accept the PR from `release/x.y.0` to `master` with `/accept`
- Run `extra-package.yml` workflow on `master` branch filling in the `desired tag version` and selecting wanted extra packages
- Run `update-branch-version.yml` workflow on `master` branch, filling in the `desired SNAPSHOT version`, it will: - Run `update-branch-version.yml` workflow on `master` branch, filling in the `desired SNAPSHOT version`, it will:
- Create `bot/update-branch-version-master` branch - Create `bot/update-branch-version-master` branch
- Checkout this new branch - Checkout this new branch
@ -35,23 +35,25 @@ Used to publish a new release from master branch (normal process).
- Commit all updates - Commit all updates
- Create PR from `bot/update-branch-version-master` to `master` - Create PR from `bot/update-branch-version-master` to `master`
- Accept the PR from `bot/update-branch-version-master` to `master` with `/accept` - Accept the PR from `bot/update-branch-version-master` to `master` with `/accept`
- Create/Build/Push all others manual packages like chocolatey, winget, brew, node, docker etc...
## Hotfix steps ## Hotfix steps
Used when you want to deliver a fix from a published release (tag). Used when you want to deliver a fix from a published release (tag).
- Create a new branch `release/x.y.z` from desired tag `x.y.z` by increasing the patch version, for example `release/4.0.1` from tag `4.0.0` - Create a new branch `release/x.y.z` from desired tag `x.y.z` manually by increasing the patch version, for example `release/6.1.1` from tag `6.1.0`
- Create your fix branch, work on it then merge it to the new fresh `release/x.y.z`
- Run `release.yml` workflow on existing `release/x.y.z` branch - Run `release.yml` workflow on existing `release/x.y.z` branch
- Fill `Desired delivery version` input your `x.y.z` version, it will: - Fill `Desired delivery version` input your `x.y.z` version, it will:
- Clean pending release - Clean pending release
- Checkout this new branch - Checkout this new branch
- Update all toml, crates, man and docs with `x.y.z` - Update all toml, crates, man and docs with `x.y.z`
- Generate CHANGELOG - Generate CHANGELOG
- Commit all updates - Commit all updates
- Create the `x.y.z` tag - Create the `x.y.z` tag
- Create draft GitHub release `x.y.z` - Create draft GitHub release `x.y.z`
- Create PR from `release/x.y.z` to `master` - Create PR from `release/x.y.z` to `master`
- Publish the draft release - Publish the draft release
- Change the release status from draft to public on github - Change the release status from draft to public on github
- Close the PR from `release/x.y.z` to `master` and manage it manually rebasing commits to reorder history and keep it linear - Close the PR from `release/x.y.z` to `master` and manage it manually rebasing commits to reorder history and keep it linear

View File

@ -0,0 +1,10 @@
Set-StrictMode -Version latest
$ErrorActionPreference = 'Stop'
write-host -foregroundcolor Cyan "----- activate python venv -----"
$global:OriginalPath = $env:PATH
python -m venv "$env:TMP\venv"
. $env:TMP\venv\Scripts\activate.ps1
$env:PATH = "$env:PATH" + ";" + "$global:OriginalPath"
python -m pip install --upgrade pip --quiet

View File

@ -2,7 +2,7 @@
# shellcheck source=/dev/null # shellcheck source=/dev/null
set -Eeuo pipefail set -Eeuo pipefail
echo "----- install python3 venv -----" echo "----- activate python3 venv -----"
python3 -m venv /tmp/hurl-python3-venv python3 -m venv /tmp/hurl-python3-venv
source /tmp/hurl-python3-venv/bin/activate source /tmp/hurl-python3-venv/bin/activate
python3 -m pip install --upgrade pip --quiet python3 -m pip install --upgrade pip --quiet

View File

@ -1,6 +1,7 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
color_red=$(echo -e "\033[1;31m") color_red=$(echo -e "\033[1;31m")
color_green=$(echo -ne "\033[1;32m") color_green=$(echo -ne "\033[1;32m")
color_reset=$(echo -e "\033[0m") color_reset=$(echo -e "\033[0m")
@ -9,11 +10,11 @@ errors_count=0
# Check *.rs Orange Copyright # Check *.rs Orange Copyright
echo "------------------------------------------------------------------------------------------" echo "------------------------------------------------------------------------------------------"
while read -r rust_file ; do while read -r rust_file ; do
if [ "$(grep -c "Copyright (C) 2024 Orange" "$rust_file" || true)" -eq 0 ] ; then if [ "$(grep -c "Copyright (C) 2025 Orange" "$rust_file" || true)" -eq 0 ] ; then
echo "Missing [Copyright (C) 2024 Orange] in ${color_red}${rust_file}${color_reset}" echo "Missing [Copyright (C) 2025 Orange] in ${color_red}${rust_file}${color_reset}"
errors_count=$((errors_count+1)) errors_count=$((errors_count+1))
else else
echo "[Copyright (C) 2024 Orange] is present in ${color_green}${rust_file}${color_reset}" echo "[Copyright (C) 2025 Orange] is present in ${color_green}${rust_file}${color_reset}"
fi fi
done < <(find packages -type f -name "*.rs") done < <(find packages -type f -name "*.rs")
@ -42,15 +43,16 @@ done < <(find . -type f -name "*.sh")
# Check bash function names in kebab case instead of camel case # Check bash function names in kebab case instead of camel case
echo "------------------------------------------------------------------------------------------" echo "------------------------------------------------------------------------------------------"
while read -r script ; do while read -r script ; do
kebab_case_function_list=$( (grep -Ev "^#" "${script}" || true) | (grep -E "^function" "${script}" || true) | (grep '-' || true) ) kebab_case_function_list=$( (grep -Ev "^#" "${script}" || true) | (grep -E "^function" "${script}" || true) | cut --delimiter '{' --field 1 | cut --delimiter '(' --field 1 | tr -s ' ' | cut --delimiter ' ' --field 2)
if [ -n "${kebab_case_function_list}" ] ; then if [ -n "${kebab_case_function_list}" ] ; then
echo "Kebab case is not allowed for function naming, use snake case instead in ${color_red}${script}${color_reset}"
while read -r function ; do while read -r function ; do
clean_function=$(echo "${function}" | tr -s ' ' | cut --delimiter ' ' --field 2 | cut --delimiter '(' --field 1) if [[ "${function}" =~ "-" ]] ; then
echo "${color_red}${clean_function}${color_reset} have to be: $(echo "${clean_function}" | tr '-' '_')" echo "${color_red}${script}: function ${function}${color_reset} have to be: $(echo "${function}" | tr '-' '_')"
errors_count=$((errors_count+1))
else
echo "${script}: function ${function} ${color_green}well formated${color_reset}"
fi
done < <(echo "${kebab_case_function_list}") done < <(echo "${kebab_case_function_list}")
echo
errors_count=$((errors_count+1))
fi fi
done < <(find . -type f -name "*.sh") done < <(find . -type f -name "*.sh")
@ -71,6 +73,55 @@ while read -r script ; do
fi fi
done < <(find . -type f -name "*.ps1" | grep -v "./completions/") done < <(find . -type f -name "*.ps1" | grep -v "./completions/")
# Check hurl command diffs between sh and ps1 tests files
echo "------------------------------------------------------------------------------------------"
tmp_sh="/tmp/sh"
tmp_ps1="/tmp/ps1"
tmp_diff="/tmp/diff"
touch "${tmp_sh}" "${tmp_ps1}" "${tmp_diff}"
command -v icdiff >/dev/null 2>&1 || sudo apt-get install -qq -y icdiff > /dev/null 2>&1
if tput cols >/dev/null 2>&1 ; then
nb_cols="$(tput cols)"
else
nb_cols=220
fi
function filter_hurl_and_hurlfmt { grep -E "hurl | hurl|hurlfmt | hurlfmt" "$1" || true ;}
function clean_indent { sed "s/^ *hurl/hurl/g" ;}
function uncomment { sed "s/^#//g" ;}
function clean_sh_var_redirect { sed "s/.*=.*(hurl/hurl/g" | sed "s/)$//g" ;}
function clean_completion_function { grep -v _hurl || true ;}
function clean_non_exec_redirected_command { grep -Ev "=\(.*hurl" || true ;}
function clean_ps1_var_redirect { sed "s/.*=hurl/hurl/g" ;}
function clean_c_drive { sed "s/C://g" ;}
function conv_ps1_antislash_to_sh { sed "s#\`\$#\\\#g" | sed "s#\`\\\#\\\\\\\#g" ;}
function conv_ps1_null_to_sh { sed "s#\$null#/dev/null#g" | sed "s#--output NUL#--output /dev/null#g" ;}
while read -r script_sh ; do
script_ps1="${script_sh%.sh}.ps1"
if [[ -f "${script_ps1}" ]] ; then
filter_hurl_and_hurlfmt "${script_sh}" | clean_completion_function | clean_non_exec_redirected_command | clean_sh_var_redirect | clean_indent | uncomment > "${tmp_sh}"
filter_hurl_and_hurlfmt "${script_ps1}" | clean_ps1_var_redirect | clean_c_drive | conv_ps1_antislash_to_sh | conv_ps1_null_to_sh | clean_indent | uncomment > "${tmp_ps1}"
if ! cmp -s "${tmp_sh}" "${tmp_ps1}" >/dev/null 2>&1 ; then
icdiff \
--show-all-spaces \
--highlight \
--strip-trailing-cr \
--cols="${nb_cols}" \
--label="${script_sh}" \
--label="${script_ps1}" \
"${tmp_sh}" "${tmp_ps1}" | tee -a "${tmp_diff}"
echo
errors_count=$((errors_count+1))
else
echo "${script_sh} has the same hurl commands as ${color_green}${script_ps1}${color_reset}"
fi
else
echo "${color_red}${script_sh}${color_reset} does not have his ${color_red}${script_ps1}${color_reset} clone."
echo
errors_count=$((errors_count+1))
fi
done < <(find ./integration/hurl*/*/ -maxdepth 2 -type f -name "*sh" | grep --invert-match "utils" | sort)
unset -f filter_hurl_and_hurlfmt clean_indent uncomment clean_sh_var_redirect clean_ps1_var_redirect clean_c_drive conv_ps1_antislash_to_sh conv_ps1_null_to_sh
# Control errors count # Control errors count
if [ "${errors_count}" -gt 0 ] ; then if [ "${errors_count}" -gt 0 ] ; then
exit 1 exit 1

View File

@ -9,9 +9,16 @@ if [[ -z "$version" ]]; then
exit 1 exit 1
fi fi
date=$(echo "$first_line" | cut -d"(" -f2 | cut -d')' -f1)
if [[ ! "$date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
echo "Date must set to format yyyy-mm-dd in the first line <$first_line> of the CHANGELOG"
exit 1
fi
echo "version=$version" echo "version=$version"
echo "date=$date"
changelog=$(bin/release/changelog_extract.py "$version" | grep '^\* ') changelog=$(bin/release/changelog_extract.py "$version" | grep '^\* ')
issues=$(bin/release/get_release_note.py "$version" | grep '^\* ') issues=$(bin/release/get_release_note.py --token "$GITHUB_TOKEN" "$version" | grep '^\* ')
if [ "$changelog" != "$issues" ]; then if [ "$changelog" != "$issues" ]; then
echo "Diff in issues in CHANGELOG" echo "Diff in issues in CHANGELOG"

View File

@ -1,3 +1,4 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
cargo clippy
cargo clippy --all-targets

View File

@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
for hurl_file in integration/hurl/{tests_failed,tests_ok}/*.hurl; do for hurl_file in integration/hurl/{tests_failed,tests_ok/**}/*.hurl; do
echo "hurlfmt $hurl_file" echo "hurlfmt $hurl_file"
output_file=/tmp/$(basename "$hurl_file") output_file=/tmp/$(basename "$hurl_file")
hurlfmt "$hurl_file" >"$output_file" hurlfmt "$hurl_file" >"$output_file"

View File

@ -1,7 +1,8 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
bin/install_rust.sh
python3 -m pip install --requirement bin/requirements-frozen.txt python3 -m pip install --requirement bin/requirements-frozen.txt
sudo apt-get update && sudo apt-get install -y libxml2-utils sudo apt-get update
sudo apt-get install -y libxml2-utils
bin/install_rust.sh

View File

@ -6,10 +6,10 @@ This script checks that there is no dependencies with unauthorized license (GPL
Examples: Examples:
$ python3 bin/check/license.py $ python3 bin/check/license.py
""" """
from typing import List, Tuple
import json import json
import subprocess import subprocess
from typing import List, Tuple
def main(): def main():
@ -17,8 +17,8 @@ def main():
check_licenses(deps) check_licenses(deps)
def is_authorized(license: str) -> bool: def is_authorized(name: str) -> bool:
for l in [ for licence in [
"MIT", "MIT",
"Apache-2.0", "Apache-2.0",
"Zlib", "Zlib",
@ -27,15 +27,16 @@ def is_authorized(license: str) -> bool:
"BSD-2-Clause", "BSD-2-Clause",
"BSD-3-Clause", "BSD-3-Clause",
"Unicode-3.0", "Unicode-3.0",
"ISC",
]: ]:
if l in license: if licence in name:
return True return True
return False return False
def is_forbidden(license: str) -> bool: def is_forbidden(name: str) -> bool:
for l in ["GPL"]: for licence in ["GPL"]:
if l in license: if licence in name:
return True return True
return False return False

7
bin/check/ruff.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -Eeuo pipefail
ruff --version
ruff format --check
ruff check

View File

@ -1,13 +1,25 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse
import datetime import datetime
import json import json
import os import os
import requests
import sys import sys
import requests
def get_latest_release(token: str | None) -> None | tuple[str, datetime]:
"""Returns the latest Rust release available."""
url = "https://api.github.com/repos/rust-lang/rust/releases"
headers = {}
if token:
headers["Authorization"] = f"Bearer {token}"
r = requests.get(url, headers=headers)
if r.status_code != 200:
sys.stderr.write(f"Error GET {url} {r.status_code}\n")
sys.stderr.write(f"{r.text}\n")
return None
def get_latest_release():
r = requests.get("https://api.github.com/repos/rust-lang/rust/releases")
releases = json.loads(r.text) releases = json.loads(r.text)
latest_release = releases[0] latest_release = releases[0]
version = latest_release["tag_name"] version = latest_release["tag_name"]
@ -16,26 +28,43 @@ def get_latest_release():
return version, date return version, date
def get_current_version(): def get_current_version() -> str:
"""Returns the current Rust version used by the project."""
return os.popen("cargo --version").read().split(" ")[1] return os.popen("cargo --version").read().split(" ")[1]
def main(): def main():
if len(sys.argv) < 2: parser = argparse.ArgumentParser(
print("Usage: rust_version.py NUM_DAYS_BEFORE_ERROR") description="Check if Hurl uses the latest Rust version"
sys.exit(1) )
num_days_before_error = int(sys.argv[1]) parser.add_argument(
"num_days_before_error",
type=int,
metavar="NUM_DAYS_BEFORE_ERROR",
help="Interval in days before raising an error if Hurl is not using latest Rust",
)
parser.add_argument("--token", help="GitHub authentication token")
args = parser.parse_args()
latest_version, date = get_latest_release() num_days_before_error = args.num_days_before_error
token = args.token
ret = get_latest_release(token=token)
if not ret:
sys.exit(2)
latest_version, date = ret
current_version = get_current_version() current_version = get_current_version()
if current_version < latest_version: if current_version < latest_version:
sys.stderr.write( sys.stderr.write(
"Rust version must be updated from %s to the latest version %s\n" f"Rust version must be updated from {current_version} to the latest version {latest_version}\n"
% (current_version, latest_version)
) )
days_before_now = datetime.datetime.now() - date days_before_now = datetime.datetime.now() - date
if days_before_now > datetime.timedelta(days=num_days_before_error): if days_before_now > datetime.timedelta(days=num_days_before_error):
sys.exit(1) sys.exit(1)
else:
sys.stderr.write(f"Latest Rust version: {latest_version}\n")
sys.stderr.write(f"Hurl Rust version: {current_version}\n")
if __name__ == "__main__": if __name__ == "__main__":

10
bin/check/valgrind.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
set -Eeuo pipefail
valgrind --version
cargo-valgrind --help
cat <<END | cargo valgrind run -p hurl -- --test
GET https://unpkg.com/vue@3.4.27/dist/vue.global.prod.js
HTTP 200
END

127
bin/check/zizmor.sh Executable file
View File

@ -0,0 +1,127 @@
#!/bin/bash
set -Eeuo pipefail
# functions
function init_terminal_colors(){
color_red=$(echo -ne "\033[1;31m")
color_green=$(echo -ne "\033[1;32m")
color_yellow=$(echo -ne "\033[1;33m")
color_reset=$(echo -ne "\033[0m")
}
function usage(){
echo
echo "Usage: $(basename "$0") [Options]... file1 file2..."
echo
echo "Options: #mandatory #optional"
echo
echo " --help #optional"
echo " This help text"
echo
echo " --github-token <github token access> #mandatory"
echo " specify github user token"
echo " : example: --github-token ghp_kJvDuaalZidk3nB1uYtgsqMrkQ5Hkh76jh2o"
}
function consume_args(){
github_token=
files_count=0
while [[ $# -gt 0 ]] ; do
case "$1" in
--help)
usage
exit 0
;;
--github-token)
if [[ -n ${2:-} ]] ; then
github_token="$2"
shift
shift
else
echo "${color_red}Error${color_reset} - Option $1 can not be null."
usage >&2
return 1
fi
;;
*)
if [[ -f ${1} ]] ; then
files+=("$1")
files_count=$((files_count+1))
shift
else
echo "${color_red}Error${color_reset} - $1 is not a file or is not readable"
usage >&2
return 1
fi
;;
esac
done
if [[ -z "${github_token}" ]] ; then
echo "${color_red}Error${color_reset} - Option --github_token is mandatory."
usage >&2
return 1
fi
if [[ $files_count == 0 ]] ; then
echo "${color_red}Error${color_reset} - You must provide at least one file for analysis."
usage >&2
return 1
fi
if ! (command -v zizmor >/dev/null 2>&1) ; then
echo "${color_red}Error${color_reset} - Zizmor has to be installed on your system (https://woodruffw.github.io/zizmor/installation)."
return 1
fi
}
function set_zizmor_conf(){
cat <<- "EOF" > "$1"
rules:
excessive-permissions:
ignore:
- accept-pull-request.yml
- auto-close-inactive-pr.yml
- coverage.yml
- extra-package.yml
- release.yml
- update-actions.yml
- update-branch-version.yml
- update-crates.yml
unpinned-uses:
config:
policies:
"*": ref-pin
EOF
}
# main
init_terminal_colors
consume_args "$@"
zizmor --version
conf="/tmp/conf"
set_zizmor_conf "${conf}"
error_count=0
for file in "${files[@]}" ; do
# disable release.yml for now because output vars have to be rewrited from scratch"
if [[ "${file}" =~ release.yml ]] ; then
echo "${color_yellow}$file is disabled for now because output vars have to be rewrited from scratch${color_reset}"
continue
fi
# disable accept-pull-request.yml for now because input vars have to be rewrited from scratch"
if [[ "${file}" =~ accept-pull-request.yml ]] ; then
echo "${color_yellow}$file is disabled for now because input vars have to be rewrited from scratch${color_reset}"
continue
fi
tmpfile="/tmp/$(basename "${file}")"
(sed "s/❌//g" "${file}" 2>/dev/null || true) | \
(sed "s/✅//g" "${file}" 2>/dev/null || true) | \
(sed "s/🔨//g" "${file}" 2>/dev/null || true) | \
(sed "s/🕗//g" "${file}" 2>/dev/null || true) > "${tmpfile}"
echo "> ${file} (tmp file: ${tmpfile}):"
zizmor --no-progress --config "${conf}" --gh-token "${github_token}" "${tmpfile}" || error_count=$((error_count+1))
done
if [[ $error_count -gt 0 ]] ; then
echo "${color_red}There are problems with github workflows${color_reset}"
exit 1
else
echo "${color_green}No problem with github workflows${color_reset}"
fi

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
COVERAGE_DIR = "target/coverage" COVERAGE_DIR = "target/coverage"

11
bin/disable_pam_for_sudo.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
set -Eeuo pipefail
echo "----- Disable PAM for sudo -----"
{
echo "auth sufficient pam_permit.so"
echo "account sufficient pam_permit.so"
echo "session sufficient pam_permit.so"
} > /etc/pam.d/sudo
cat /etc/pam.d/sudo

View File

@ -9,19 +9,20 @@ Examples:
$ python3 bin/docs/build_man_md.py docs/manual/hurl.md > docs/manual.md $ python3 bin/docs/build_man_md.py docs/manual/hurl.md > docs/manual.md
""" """
import re import re
import sys import sys
from pathlib import Path from pathlib import Path
from typing import List from typing import List
from markdown import ( from markdown import (
parse_markdown,
MarkdownDoc,
Header, Header,
Paragraph, MarkdownDoc,
Whitespace,
Node, Node,
Paragraph,
Table, Table,
Whitespace,
parse_markdown,
) )

View File

@ -14,12 +14,13 @@ Examples:
$ python3 bin/docs/build_readme.py crates > packages/hurl/README.md $ python3 bin/docs/build_readme.py crates > packages/hurl/README.md
""" """
import os import os
import re import re
import sys import sys
from pathlib import Path from pathlib import Path
from markdown import parse_markdown, MarkdownDoc from markdown import MarkdownDoc, parse_markdown
def build_home_md(text: str) -> MarkdownDoc: def build_home_md(text: str) -> MarkdownDoc:
@ -137,6 +138,22 @@ def replace(text: str, dest: str) -> str:
</picture> </picture>
""", """,
), ),
# TODO: extract version from Cargo.toml
(
"[HTML]: /docs/standalone/hurl-6.1.0.html",
"[HTML]: /docs/standalone/hurl-6.1.0.html",
"[HTML]: https://hurl.dev/assets/docs/hurl-6.1.0.html.gz",
),
(
"[PDF]: /docs/standalone/hurl-6.1.0.pdf",
"[PDF]: /docs/standalone/hurl-6.1.0.pdf",
"[PDF]: https://hurl.dev/assets/docs/hurl-6.1.0.pdf.gz",
),
(
"[Markdown]: https://hurl.dev/docs/standalone/hurl-6.1.0.html",
"[Markdown]: /docs/standalone/hurl-6.1.0.md",
"[Markdown]: https://hurl.dev/assets/docs/hurl-6.1.0.md.gz",
),
] ]
for old, new_for_github, new_for_crates in snippets: for old, new_for_github, new_for_crates in snippets:
if dest == "github": if dest == "github":

View File

@ -0,0 +1,359 @@
#!/usr/bin/env python3
"""
Build a standalone Markdown file of all the documentation. All links and anchors are rewritten so the
links are functional: during the concatenation of two files, the script insures that an anchor is well
specific to a given pages. "The essential, it works": means that while this script is working, it may be
not easy to maintain it.
Examples:
$ python3 bin/docs/build_standalone_md.py > docs/standalone/hurl-5.0.1.md
"""
import os
import re
import sys
import unicodedata
from datetime import datetime
from pathlib import Path
import markdown
import tomllib
from markdown import Header, MarkdownDoc, Paragraph, RefLink, Table, Whitespace
def add_section_header(doc: MarkdownDoc, title: str):
"""Add a section header h1 to a Markdown document, with a given title"""
node = Header(title=title, level=1)
add_header_id(header=node, prefix=None)
doc.add_child(node)
node = Whitespace(content="\n")
doc.add_child(node)
def add_sections(doc: MarkdownDoc, title: str | None, files: [str]):
"""Add a new section to a markdown documentation, using a list of files to concatenate"""
if title:
add_section_header(doc=doc, title=title)
for file in files:
sys.stderr.write(f">>> Processing <{file}>...\n")
path = Path(file)
text = path.read_text()
file_md = markdown.parse_markdown(text=text)
file_md.indent()
# All ref links (https://daringfireball.net/projects/markdown/syntax) are inlined so we can concatenate
# multiple documents without any problem
#
# Before:
# ```markdown
# Some bla bal [a reference][ref]
# [ref]: https://foo.com
# ```
#
# After:
# ```markdown
# Some bla bal [a reference](https://foo.com)
# ```
inline_ref_link(md=file_md)
# Anchors are normalize so we can concatenate multiple documents that have the same anchors
#
# Before:
# ```markdown
# Some bla bal [a reference](#anchor)
# ```
#
# After:
# ```markdown
# Some bla bal [a reference](#name-of-the-document-anchor)
anchors_prefix = f"{title} {path.stem}"
anchors_prefix = slugify(anchors_prefix)
rewrite_links(md=file_md, prefix=anchors_prefix)
hr = Paragraph(content="\n\n<hr>\n\n")
file_md.add_child(hr)
doc.extend(file_md)
def add_header_id(header: Header, prefix: str | None):
"""Add an anchor id to a header
Example: `# Some title` => `# Some title {#a-prefix-some-title}`
"""
slug = slugify(header.title)
if prefix:
_id = f"{prefix}-{slug}"
else:
_id = slug
header.id = _id
header.update_content()
def slugify(text: str) -> str:
"""Makes a slug from a text."""
text = unicodedata.normalize("NFKD", text).encode("ascii", "ignore").decode("ascii")
text = re.sub(r"[^\w\s/-]", "", text).strip().lower()
return re.sub(r"[-\s]+", "-", text).replace("/", "")
def section_from_page(page: str):
"""Returns the section title from a page ex: "manual.md" => "Getting Started" """
if page in ["home.md"]:
return "Introduction"
elif page in ["license.md"]:
return "Resources"
elif page in [
"installation.md",
"manual.md",
"sample.md",
"running-tests.md",
"frequently-asked-questions.md",
]:
return "Getting Started"
else:
return "File Format"
def rewrite_links(md: MarkdownDoc, prefix: str):
"""When multiple Markdown documents are concatenate, we need to rewrite links and anchor because
some anchors can overlapped and documents are merged into a single document."""
# Find all headers and add an id specific to the page
# `# Some title` => `# Some title {#some-title}`
headers = [c for c in md.children if isinstance(c, Header)]
for header in headers:
add_header_id(header, prefix=prefix)
# Replace `[Foo](#anchor)` => `[Foo](#current-page-anchor)`
nodes = [c for c in md.children if isinstance(c, Paragraph) or isinstance(c, Table)]
for node in nodes:
def repl(match_obj):
title = match_obj.group("title")
anchor = match_obj.group("anchor")
_id = f"#{prefix}-{anchor}"
return f"[{title}]({_id})"
node.content = re.sub(
r"\[(?P<title>.+?)]\(#(?P<anchor>.+?)\)", repl, node.content
)
# Replace `[Foo](/docs/some-page.md#anchor)` => `[Foo](#some-page-anchor)`
nodes = [c for c in md.children if isinstance(c, Paragraph) or isinstance(c, Table)]
for node in nodes:
def repl(match_obj):
old = match_obj.group(0)
title = match_obj.group("title")
page = match_obj.group("page")
section = section_from_page(page)
section = slugify(section)
page = page[:-3] # Remove .md extension
anchor = match_obj.group("anchor")
if anchor:
_id = f"#{section}-{page}-{anchor}"
else:
_id = f"#{section}-{page}"
new = f"[{title}]({_id})"
sys.stderr.write(f"Replace `{old}` to `{new}\n")
return new
node.content = re.sub(
r"\[(?P<title>.+?)]\(/docs/(?P<page>[a-zA-Z0-9-/]+?\.md)#?(?P<anchor>[a-z0-9-]+?)?\)",
repl,
node.content,
)
# Replace Manual links
# `<a href="#aws-sigv4" id="aws-sigv4">`
tables = [c for c in md.children if isinstance(c, Table)]
for table in tables:
def repl(match_obj):
href = match_obj.group("href")
_id = match_obj.group("_id")
if href != _id:
return f'<a href="{href}" id="{_id}">'
else:
return f'<a href="#{prefix}-{href}" id="{prefix}-{_id}">'
table.content = re.sub(
r"<a href=\"#(?P<href>.+?)\" id=\"(?P<_id>.+?)\">", repl, table.content
)
table.reformat()
def inline_ref_link(md: MarkdownDoc):
"""Ref links are inline: as documents are merged, we do not want to have ref links in the
middle of the final document."""
# Find all ref link:
p_nodes = [c for c in md.children if isinstance(c, Paragraph)]
ref_nodes = [c for c in md.children if isinstance(c, RefLink)]
# Inline ref links
for p in p_nodes:
def repl(match_obj):
ref = match_obj.group("ref")
ref_links = (n for n in ref_nodes if n.ref == ref)
ref_link = next(ref_links, None)
if not ref_link:
sys.stderr.write(f"No ref for [{ref}]\n")
return f"[{ref}]"
url = ref_link.link.strip()
new = f"[{ref}]({url})"
sys.stderr.write(f"Inline `[{ref}]` to `{new}`\n")
return new
p.content = re.sub(r"\[(?P<ref>.+?)]", repl, p.content)
# Delete ref links
md.remove_nodes(ref_nodes)
def main() -> int:
# Identify version
with open("packages/hurl/Cargo.toml", "rb") as f:
data = tomllib.load(f)
version = data["package"]["version"]
version = version.replace("-SNAPSHOT", "")
sys.stderr.write(f"version:{version}\n")
standalone_md = MarkdownDoc()
add_sections(
doc=standalone_md,
title="Introduction",
files=[
"docs/home.md",
],
)
add_sections(
doc=standalone_md,
title="Getting Started",
files=[
"docs/installation.md",
"docs/manual.md",
"docs/samples.md",
"docs/running-tests.md",
"docs/frequently-asked-questions.md",
],
)
add_sections(
doc=standalone_md,
title="File Format",
files=[
"docs/hurl-file.md",
"docs/entry.md",
"docs/request.md",
"docs/response.md",
"docs/capturing-response.md",
"docs/asserting-response.md",
"docs/filters.md",
"docs/templates.md",
"docs/grammar.md",
],
)
add_sections(
doc=standalone_md,
title="Resources",
files=[
"docs/license.md",
],
)
# Make the cover
toc_txt = standalone_md.toc()
toc = Paragraph(content=toc_txt)
standalone_md.children.insert(0, toc)
title = Header(title="Hurl Documentation", level=1)
standalone_md.children.insert(0, title)
ws = Whitespace(content="\n")
standalone_md.children.insert(1, ws)
date = datetime.today().strftime("%d-%m-%Y")
title = Header(title=f"Version {version} - {date}", level=2)
standalone_md.children.insert(2, title)
ws = Whitespace(content="\n")
standalone_md.children.insert(3, ws)
standalone = standalone_md.to_text()
standalone = rewrite_content(text=standalone, version=version)
print(standalone)
return os.EX_OK
def rewrite_content(text: str, version: str) -> str:
"""Some hardcoded replacement."""
return (
text.replace("/docs/assets/img/", "https://hurl.dev/assets/img/")
.replace('<div id="home-demo"></div>', "")
.replace("[Blog](blog.md)", "[Blog](https://hurl.dev/blog)")
.replace(
"[Tutorial](#file-format-tutorial/your-first-hurl-file)",
"[Tutorial](https://hurl.dev/docs/tutorial/your-first-hurl-file.html)",
)
.replace(
"[Documentation](#getting-started-installation)",
"[Documentation](https://hurl.dev)",
)
.replace(
f" (download [HTML](/docs/standalone/hurl-{version}.html), [PDF](/docs/standalone/hurl-{version}.pdf), [Markdown](/docs/standalone/hurl-{version}.md))",
"",
)
.replace("/docs/asserting-response.html#", "#file-format-asserting-response-")
.replace(
'<a href="/docs/capturing-response.html">',
'<a href="#file-format-capturing-response-capturing-response">',
)
.replace(
'<a href="#method">Method</a>',
'<a href="#file-format-request-method">Method</a>',
)
.replace('<a href="#url">URL</a>', '<a href="#file-format-request-url">URL</a>')
.replace(
'<a href="#headers">HTTP request headers</a>',
'<a href="#file-format-request-headers">HTTP request headers</a>',
)
.replace(
'<a href="#options">Options</a>',
'<a href="#file-format-options">Options</a>',
)
.replace(
'<a href="#query-parameters">query strings</a>',
'<a href="#file-format-request-query-parameters">query strings</a>',
)
.replace(
'<a href="#form-parameters">form params</a>',
'<a href="#file-format-request-form-parameters">form params</a>',
)
.replace(
'<a href="#cookies">cookies</a>',
'<a href="#file-format-request-cookies">cookies</a>',
)
.replace(
'<a href="#basic-authentication">authentication</a>',
'<a href="#file-format-request-basic-authentication">authentication</a>',
)
.replace(
'<a href="#body">HTTP request body</a>',
'<a href="#file-format-request-body">HTTP request body</a>',
)
.replace(
"[UUID v4 random string]",
"[UUID v4 random string](https://en.wikipedia.org/wiki/Universally_unique_identifier)",
)
.replace(
"[RFC 3339]",
"[RFC 3339](https://www.rfc-editor.org/rfc/rfc3339)",
)
)
if __name__ == "__main__":
main()

View File

@ -42,7 +42,7 @@ class Whitespace(Node):
pass pass
def build_header(title: str, level: int) -> str: def build_header(title: str, level: int, _id: str | None) -> str:
"""Constructs a header in Markdown format. """Constructs a header in Markdown format.
Arg: Arg:
@ -50,7 +50,10 @@ def build_header(title: str, level: int) -> str:
level: 1 base index of the header level level: 1 base index of the header level
""" """
hashes = "#" * level hashes = "#" * level
return f"{hashes} {title}\n" if _id:
return f"{hashes} {title} {{#{_id}}}\n"
else:
return f"{hashes} {title}\n"
class Header(Node): class Header(Node):
@ -58,11 +61,13 @@ class Header(Node):
title: str title: str
level: int level: int
_id: str | None
def __init__(self, title: str, level: int) -> None: def __init__(self, title: str, level: int, _id: str = None) -> None:
super().__init__(content=None) super().__init__(content=None)
self.title = title self.title = title
self.level = level self.level = level
self._id = _id
self.update_content() self.update_content()
def indent(self, count: int) -> None: def indent(self, count: int) -> None:
@ -75,7 +80,15 @@ class Header(Node):
self.update_content() self.update_content()
def update_content(self) -> None: def update_content(self) -> None:
self.content = build_header(title=self.title, level=self.level) self.content = build_header(title=self.title, level=self.level, _id=self._id)
@property
def id(self) -> str | None:
return self._id
@id.setter
def id(self, value: str | None):
self._id = value
class RefLink(Node): class RefLink(Node):
@ -198,6 +211,19 @@ def parse_code(parser: Parser) -> Code:
return Code(content=content) return Code(content=content)
def parse_table(parser: Parser) -> Table:
"""Parse and return a table token."""
content = ""
while parser.left() > 0:
line = parser.read_while(lambda it: it != "\n")
_ = parser.read()
content += line + "\n"
c = parser.peek()
if c != "|":
break
return Table(content=content)
def parse_header(parser: Parser) -> Header: def parse_header(parser: Parser) -> Header:
"""Parse and return a header token.""" """Parse and return a header token."""
hashes = parser.read_while(lambda it: it == "#") hashes = parser.read_while(lambda it: it == "#")
@ -255,6 +281,11 @@ def parse_markdown(text: str) -> "MarkdownDoc":
root.add_child(node) root.add_child(node)
continue continue
if c == "|":
node = parse_table(parser=parser)
root.add_child(node)
continue
# Default node parsing: # Default node parsing:
node = parse_paragraph(parser=parser) node = parse_paragraph(parser=parser)
root.add_child(node) root.add_child(node)
@ -312,12 +343,12 @@ class MarkdownDoc:
self.children.extend(other.children) self.children.extend(other.children)
def insert_node(self, start: Node, node: Node) -> None: def insert_node(self, start: Node, node: Node) -> None:
"""Insert a child node to the current document, after a specified node.""" """Insert a child node to the current document, before a specified node."""
index = self.children.index(start) index = self.children.index(start)
self.children.insert(index, node) self.children.insert(index, node)
def insert_nodes(self, start: Node, nodes: List[Node]) -> None: def insert_nodes(self, start: Node, nodes: List[Node]) -> None:
"""Insert children nodes to the current document, after a specified node.""" """Insert children nodes to the current document, before a specified node."""
index = self.children.index(start) index = self.children.index(start)
self.children[index:index] = nodes self.children[index:index] = nodes
@ -373,15 +404,23 @@ class MarkdownDoc:
return re.sub(r"[-\s]+", "-", value).replace("/", "") return re.sub(r"[-\s]+", "-", value).replace("/", "")
headers = [child for child in self.children if isinstance(child, Header)] headers = [child for child in self.children if isinstance(child, Header)]
# Find the minimum header level, we'll delta all documents level from this
min_level = min([h.level for h in headers])
toc = dedent( toc = dedent(
"""\ """\
Table of Contents # Table of Contents
=================
""" """
) )
for header in headers: for header in headers:
indent = " " * header.level indent = " " * (header.level - min_level)
slug = slugify(header.title) if header.id:
slug = header.id
else:
slug = slugify(header.title)
line = f"{indent}* [{header.title}](#{slug})\n" line = f"{indent}* [{header.title}](#{slug})\n"
toc += line toc += line
toc += "\n"
return toc return toc

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import unittest import unittest
from markdown import * from markdown import Table
class UtilsTest(unittest.TestCase): class UtilsTest(unittest.TestCase):

12
bin/docs/update_all.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
set -Eeuo pipefail
# First generates Rust code, bash completion, part of hurl.md and hurlfmt.md
python3 bin/spec/options/generate_all.py
# Regenerates manual, READMEs etc..
python3 bin/release/gen_manpage.py docs/manual/hurl.md > docs/manual/hurl.1
python3 bin/release/gen_manpage.py docs/manual/hurlfmt.md > docs/manual/hurlfmt.1
python3 bin/docs/build_man_md.py docs/manual/hurl.md > docs/manual.md
python3 bin/docs/build_readme.py github > README.md
python3 bin/docs/build_readme.py crates > packages/hurl/README.md

View File

@ -15,10 +15,12 @@ vcpkg --version
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
write-host "# python" write-host "# python"
(Get-Command -Name python -CommandType Application).Source Get-command python | Format-Table -Wrap -Autosize
python -V python -V
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
(Get-Command -Name pip -CommandType Application).Source
write-host "# pip"
Get-command pip | Format-Table -Wrap -Autosize
pip --version pip --version
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }

View File

@ -6,14 +6,23 @@ date
echo "# os" echo "# os"
uname -a uname -a
echo "# user"
whoami
echo "# python3" echo "# python3"
if command -V python3 ; then if command -V python3 ; then
which python3 which python3
python3 -V python3 -V
else
echo "No python3 installed"
fi
echo "# pip"
if command -V pip ; then
which pip which pip
pip --version pip --version
else else
echo "No python3 installed" echo "No pip installed"
fi fi
echo "# curl" echo "# curl"

View File

@ -18,9 +18,12 @@ apk add --quiet \
openssl-dev \ openssl-dev \
python3 \ python3 \
python3-dev \ python3-dev \
py3-pip \
cargo \ cargo \
squid \ squid \
jq jq
# libxml crate >= 0.3.4 uses bindgen
apk add --quiet clang-dev
sudo squid -k shutdown || true sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true

View File

@ -9,7 +9,6 @@ pacman -Syu --noconfirm \
expect \ expect \
openssl \ openssl \
python3 \ python3 \
python-pip \
icu \ icu \
base-devel \ base-devel \
libxml2 \ libxml2 \
@ -17,8 +16,11 @@ pacman -Syu --noconfirm \
openbsd-netcat \ openbsd-netcat \
squid \ squid \
jq jq
# Temporary install to patch a python3/pip crash
pacman -Syu --noconfirm expat
sudo squid -k shutdown || true sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true
# libxml crate >= 0.3.4 uses bindgen
pacman -Syu --noconfirm clang
# Temporary install to patch a python3/pip crash
pacman -Syu --noconfirm expat

View File

@ -0,0 +1,33 @@
#!/bin/bash
set -Eeuo pipefail
echo "----- install prerequisite packages -----"
if ! command -V sudo ; then
echo ":: Installing sudo"
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get -y install sudo
fi
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install \
bash \
expect \
curl \
net-tools \
g++-aarch64-linux-gnu \
libc6-dev-arm64-cross \
libxml2-dev \
pkg-config \
libcurl4-openssl-dev \
libxml2-utils \
libxml2-dev \
libssl-dev \
netcat-openbsd \
squid \
jq \
python3 \
python3-venv \
python3-dev
sudo service squid stop || true
sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true

View File

@ -7,17 +7,18 @@ yum install -y \
sudo \ sudo \
expect \ expect \
which \ which \
python3 \
procps \ procps \
gcc \ gcc \
libxml2-devel \ libxml2-devel \
openssl-devel \ openssl-devel \
libcurl-devel \ libcurl-devel \
python3-devel \ python3.11-devel \
python3-pip \
nc \ nc \
squid \ squid \
jq jq
ln -sf /usr/bin/python3.11 /usr/bin/python3
sudo squid -k shutdown || true sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true
# libxml crate >= 0.3.4 uses bindgen
yum install -y clang-devel

View File

@ -1,21 +1,9 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
echo "----- preinstalled curl version -----"
curl --version
echo "----- install prerequisite packages -----" echo "----- install prerequisite packages -----"
export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=true export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=true
brew uninstall --force --ignore-dependencies curl
brew update brew update
brew install -s curl brew install bash expect squid jq
brew link --force --overwrite curl
CURL_PATH="$(brew --prefix curl)/bin"
export CURL_PATH
echo "CURL_PATH=$CURL_PATH"
PATH="$CURL_PATH:$PATH"
export PATH
brew install bash expect pkg-config squid jq
sudo squid -k shutdown || true sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true

View File

@ -3,15 +3,17 @@ set -Eeuo pipefail
echo "----- install prerequisite packages -----" echo "----- install prerequisite packages -----"
if ! command -V sudo ; then if ! command -V sudo ; then
echo ":: Installing sudo"
apt-get update apt-get update
apt-get -y install sudo DEBIAN_FRONTEND=noninteractive apt-get -y install sudo
fi fi
sudo apt-get update sudo apt-get update
sudo apt-get -y install \ sudo DEBIAN_FRONTEND=noninteractive apt-get -y install \
bash \ bash \
expect \ expect \
curl \ curl \
net-tools \ net-tools \
build-essential \
g++-aarch64-linux-gnu \ g++-aarch64-linux-gnu \
libc6-dev-arm64-cross \ libc6-dev-arm64-cross \
libxml2-dev \ libxml2-dev \
@ -21,7 +23,6 @@ sudo apt-get -y install \
libxml2-dev \ libxml2-dev \
libssl-dev \ libssl-dev \
python3 \ python3 \
python3-pip \
python3-venv \ python3-venv \
netcat-openbsd \ netcat-openbsd \
squid \ squid \
@ -30,3 +31,5 @@ sudo service squid stop || true
sudo squid -k shutdown || true sudo squid -k shutdown || true
sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true sudo rm -v /dev/shm/squid*.shm >/dev/null 2>&1 || true
# libxml crate >= 0.3.4 uses bindgen
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install libclang-dev

View File

@ -8,21 +8,19 @@ $vcpkg_dir=((Get-command vcpkg).Source | Split-Path)
$lib_dir="$vcpkg_dir\installed\x64-windows\bin" $lib_dir="$vcpkg_dir\installed\x64-windows\bin"
git -C $vcpkg_dir pull git -C $vcpkg_dir pull
# install libxml and libcurl[openssl] # install libxml and libcurl
vcpkg install --recurse --x-use-aria2 curl[core,non-http,schannel,ssl,sspi,http2]:x64-windows || true vcpkg install --recurse curl[core,sspi,http2,non-http,ssl]:x64-windows
vcpkg install --recurse --x-use-aria2 libxml2[core,iconv]:x64-windows || true vcpkg install --recurse libxml2[core,iconv]:x64-windows
vcpkg update vcpkg update
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
vcpkg upgrade --no-dry-run vcpkg upgrade --no-dry-run
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
vcpkg integrate install vcpkg integrate install
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
Set-ItemProperty -Path HKCU:\Environment -Name VCPKGRS_DYNAMIC -Value "1"
$env:VCPKGRS_DYNAMIC = [System.Environment]::GetEnvironmentVariable("VCPKGRS_DYNAMIC","User")
if ($LASTEXITCODE) { Throw }
# update pip # install python 3.11
python -m pip install --upgrade pip --quiet choco install --confirm python311
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
# install proxy # install proxy

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -Eeuo pipefail
python_version="${1:-11}"
sudo apt-get install -y software-properties-common
grep -R deadsnakes /etc/apt/ 2>/dev/null 2>&1 || sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo DEBIAN_FRONTEND=noninteractive apt-get -y install \
python3."${python_version}" \
python3."${python_version}"-dev \
python3."${python_version}"-venv
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3."${python_version}" 1 || true
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3."${python_version}" 1 || true

View File

@ -1,6 +1,12 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
case $(uname -m) in
x86_64) arch="amd64" ;;
aarch64) arch="arm64" ;;
*) echo "Unkown arch" ; uname -m ;;
esac
sudo rm -rf target/debian sudo rm -rf target/debian
mkdir target/debian mkdir target/debian
mkdir -p target/debian/usr/bin target/debian/DEBIAN mkdir -p target/debian/usr/bin target/debian/DEBIAN
@ -22,7 +28,7 @@ cat <<END >target/debian/DEBIAN/control
Package: hurl Package: hurl
Version: $VERSION Version: $VERSION
Section: web Section: web
Architecture: amd64 Architecture: $arch
Priority: optional Priority: optional
Standards-Version: 3.9.4 Standards-Version: 3.9.4
Maintainer: Fabrice Reix <fabrice.reix@orange.com> Maintainer: Fabrice Reix <fabrice.reix@orange.com>
@ -36,11 +42,10 @@ Description: Run and test HTTP requests
END END
dpkg --build target/debian dpkg --build target/debian
echo "Check Lintian" echo "Check Lintian"
sudo apt-get install -y lintian sudo apt-get install -y lintian
lintian --verbose target/debian.deb lintian --verbose target/debian.deb
mkdir -p target/upload mkdir -p target/upload
cp target/debian.deb "target/upload/hurl_${VERSION}_amd64.deb" cp target/debian.deb "target/upload/hurl_${VERSION}_${arch}.deb"

View File

@ -6,8 +6,15 @@ write-host -foregroundcolor Cyan "----- create windows64 installer -----"
$actual_dir=(Get-Location).Path $actual_dir=(Get-Location).Path
# install NSIS # install NSIS
if (Get-Command makensis) {echo "makensis already installed"} else {choco install --confirm --no-progress nsis} if (Get-Command makensis -ErrorAction SilentlyContinue) {
echo "makensis already installed"
} else {
choco install --confirm --no-progress nsis
$env:Path = 'C:\Program Files (x86)\NSIS' + ";" + "$env:Path"
}
makensis /VERSION
$nsis_dir=(Get-Command makensis).path | Split-Path -Parent $nsis_dir=(Get-Command makensis).path | Split-Path -Parent
echo "nsis_dir=$nsis_dir"
Expand-Archive -Path "$PSScriptRoot\..\..\bin\windows\EnVar_plugin.zip" -DestinationPath "$nsis_dir" -Force -Verbose Expand-Archive -Path "$PSScriptRoot\..\..\bin\windows\EnVar_plugin.zip" -DestinationPath "$nsis_dir" -Force -Verbose
# create win64 installer # create win64 installer
@ -16,4 +23,3 @@ makensis.exe /NOCD /V4 ..\..\bin\windows\hurl.nsi
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
cd $actual_dir cd $actual_dir

View File

@ -10,8 +10,9 @@ Examples:
$ python3 bin/release/gen_manpage.py docs/manual/hurlfmt.md > docs/manual/hurlfmt.1 $ python3 bin/release/gen_manpage.py docs/manual/hurlfmt.md > docs/manual/hurlfmt.1
""" """
import sys
import re import re
import sys
from datetime import date from datetime import date
from typing import Optional from typing import Optional

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
set -Eeuo pipefail set -Eeuo pipefail
toolchain=$(rustup show active-toolchain | cut -d '-' -f 2- | cut -d ' ' -f1) toolchain=$(rustup show active-toolchain | cut -d '-' -f 2- | cut -d ' ' -f1 | head -1)
echo "${toolchain}" echo "${toolchain}"

View File

@ -5,6 +5,7 @@ Example:
$ python3 bin/release/get_release_note.py 1.7.0 $ python3 bin/release/get_release_note.py 1.7.0
""" """
import argparse import argparse
import datetime import datetime
import json import json
@ -12,7 +13,6 @@ import sys
from typing import List, Optional from typing import List, Optional
import requests import requests
from bs4 import BeautifulSoup
hurl_repo_url = "https://github.com/Orange-OpenSource/hurl" hurl_repo_url = "https://github.com/Orange-OpenSource/hurl"
@ -22,6 +22,7 @@ class Pull:
self, self,
url: str, url: str,
description: str, description: str,
author: str,
tags: Optional[List[str]] = None, tags: Optional[List[str]] = None,
issues: Optional[List[int]] = None, issues: Optional[List[int]] = None,
): ):
@ -31,13 +32,15 @@ class Pull:
issues = [] issues = []
self.url = url self.url = url
self.description = description self.description = description
self.author = author
self.tags = tags self.tags = tags
self.issues = issues self.issues = issues
def __repr__(self): def __repr__(self):
return 'Pull("%s", "%s","%s", %s)' % ( return 'Pull("%s", "%s", "%s", "%s", %s)' % (
self.url, self.url,
self.description, self.description,
self.author,
str(self.tags), str(self.tags),
str(self.issues), str(self.issues),
) )
@ -49,6 +52,8 @@ class Pull:
return False return False
if self.description != other.description: if self.description != other.description:
return False return False
if self.author != other.author:
return False
if self.tags != other.tags: if self.tags != other.tags:
return False return False
if self.issues != other.issues: if self.issues != other.issues:
@ -79,8 +84,74 @@ class Issue:
def release_note(milestone: str, token: Optional[str]) -> str: def release_note(milestone: str, token: Optional[str]) -> str:
"""return markdown release note for the given milestone""" """return markdown release note for the given milestone"""
date = datetime.datetime.now() date = datetime.datetime.now()
milestone_number = get_milestone(title=milestone, token=token)
issues = get_issues(milestone_number=milestone_number, token=token) query = """\
query {
repository(owner:"Orange-OpenSource", name:"hurl") {
milestones(query:"MILESTONE", first:1) {
edges {
node {
issues(last:100, states:CLOSED) {
edges {
node {
title
number
url
author {
login
}
closedByPullRequestsReferences(includeClosedPrs:true, first:5) {
edges {
node {
title
url
author {
login
}
}
}
}
labels(first:5) {
edges {
node {
name
}
}
}
}
}
}
}
}
}
}
}
"""
query = query.replace("MILESTONE", milestone)
payload = github_graphql(token=token, query=query)
response = json.loads(payload)
issues_dict = response["data"]["repository"]["milestones"]["edges"][0]["node"][
"issues"
]["edges"]
issues = []
for issue_dict in issues_dict:
number = issue_dict["node"]["number"]
author_issue = issue_dict["node"]["author"]["login"]
tags_dict = issue_dict["node"]["labels"]["edges"]
tags = [t["node"]["name"] for t in tags_dict]
pulls = []
pulls_dict = issue_dict["node"]["closedByPullRequestsReferences"]["edges"]
for pull_dict in pulls_dict:
title = pull_dict["node"]["title"]
url = pull_dict["node"]["url"]
author_pull = pull_dict["node"]["author"]["login"]
pull = Pull(description=title, url=url, author=author_pull)
pulls.append(pull)
issue = Issue(number=number, tags=tags, author=author_issue, pulls=pulls)
issues.append(issue)
pulls = pulls_from_issues(issues) pulls = pulls_from_issues(issues)
authors = [ authors = [
author author
@ -102,7 +173,7 @@ def pulls_from_issues(issues: List[Issue]) -> List[Pull]:
saved_pull.tags.append(tag) saved_pull.tags.append(tag)
saved_pull.issues.append(issue.number) saved_pull.issues.append(issue.number)
else: else:
if pull.url.startswith("/Orange-OpenSource/hurl"): if pull.url.startswith("https://github.com/Orange-OpenSource/hurl"):
pull.tags = issue.tags pull.tags = issue.tags
pull.issues.append(issue.number) pull.issues.append(issue.number)
pulls[pull.url] = pull pulls[pull.url] = pull
@ -110,65 +181,15 @@ def pulls_from_issues(issues: List[Issue]) -> List[Pull]:
return list(pulls.values()) return list(pulls.values())
def get_issues(milestone_number: int, token: Optional[str]) -> List[Issue]:
"""Return issues for the given milestone and tags"""
path = "/issues?milestone=%s&state=closed&per_page=100" % milestone_number
response = github_get(path=path, token=token)
issues = []
for issue_json in json.loads(response):
if "pull_request" in issue_json:
continue
number = issue_json["number"]
tags = []
if "labels" in issue_json:
labels = issue_json["labels"]
tags = [label["name"] for label in labels]
author = issue_json["user"]["login"]
pulls = get_linked_pulls(issue_number=number, token=token)
issue = Issue(number, tags, author, pulls)
issues.append(issue)
return issues
def get_linked_pulls(issue_number: int, token: Optional[str]) -> List[Pull]:
"""return linked pull request for a given issue"""
# Webscapping the webpage issue
# because the API does not provide the relationship between issues and Pull request
url = "https://github.com/Orange-OpenSource/hurl/issues/%d" % issue_number
sys.stderr.write("* GET %s\n" % url)
headers = {}
if token:
headers["Authorization"] = f"Bearer {token}"
r = requests.get(url, headers=headers)
html = r.text
pulls = webscrapping_linked_pulls(html)
return pulls
def webscrapping_linked_pulls(html: str) -> List[Pull]:
soup = BeautifulSoup(html, "html.parser")
links = soup.select("development-menu a")
pulls = []
for link in links:
url = link["href"]
if not isinstance(url, str):
continue
if url == "/Orange-OpenSource/hurl":
continue
description = "".join(link.getText()).strip()
pull = Pull(url, description)
pulls.append(pull)
return pulls
def authors_from_issues(issues: List[Issue]) -> List[str]: def authors_from_issues(issues: List[Issue]) -> List[str]:
"""return list of unique authors from a list of issues""" """return list of unique authors from a list of issues"""
authors = [] authors = []
for issue in issues: for issue in issues:
author = issue.author if issue.author not in authors:
if author not in authors: authors.append(issue.author)
authors.append(author) for pull in issue.pulls:
if pull.author not in authors:
authors.append(pull.author)
return authors return authors
@ -192,6 +213,7 @@ def generate_md(
"enhancement": "Enhancements", "enhancement": "Enhancements",
"bug": "Bugs Fixed", "bug": "Bugs Fixed",
"security": "Security Issues Fixed", "security": "Security Issues Fixed",
"deprecation": "Deprecations",
} }
for category in categories: for category in categories:
@ -209,25 +231,16 @@ def generate_md(
return s return s
def get_milestone(title: str, token: Optional[str]) -> int: def github_graphql(token: Optional[str], query: str) -> str:
"""Return milestone number""" """Execute a GraphQL query using GitHub API."""
path = "/milestones?state=all" url = "https://api.github.com/graphql"
response = github_get(path=path, token=token) query_json = {"query": query}
for milestone in json.loads(response): body = json.dumps(query_json)
if milestone["title"] == title: sys.stderr.write("* POST %s\n" % url)
return milestone["number"]
return -1
def github_get(path: str, token: Optional[str]) -> str:
"""Execute an HTTP GET with request"""
github_api_url = "https://api.github.com/repos/Orange-OpenSource/hurl"
url = github_api_url + path
sys.stderr.write("* GET %s\n" % url)
headers = {} headers = {}
if token: if token:
headers["Authorization"] = f"Bearer {token}" headers["Authorization"] = f"Bearer {token}"
r = requests.get(url, headers=headers) r = requests.post(url, data=body, headers=headers)
if r.status_code != 200: if r.status_code != 200:
raise Exception("HTTP Error %s - %s" % (r.status_code, r.text)) raise Exception("HTTP Error %s - %s" % (r.status_code, r.text))
return r.text return r.text

View File

@ -1,8 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import datetime
import unittest import unittest
from get_release_note import * from get_release_note import (
Issue,
Pull,
authors_from_issues,
generate_md,
pulls_from_issues,
webscrapping_linked_pulls,
)
ISSUES = [ ISSUES = [
Issue(number=1, tags=["enhancement"], author="bob", pulls=[Pull("url1", "pull1")]), Issue(number=1, tags=["enhancement"], author="bob", pulls=[Pull("url1", "pull1")]),

View File

@ -30,7 +30,10 @@ function prerequisites(){
if ! command -v 7z >/dev/null 2>&1 ; then if ! command -v 7z >/dev/null 2>&1 ; then
log_error "prerequisite" "Please install p7zip-full to make $(basename "$0") work." log_error "prerequisite" "Please install p7zip-full to make $(basename "$0") work."
return 1 return 1
elif ! command -v tar >/dev/null 2>&1 ; then elif ! command -v tar --version >/dev/null 2>&1 ; then
log_error "prerequisite" "Please install tar to make $(basename "$0") work."
return 1
elif ! command -v zstd --version >/dev/null 2>&1 ; then
log_error "prerequisite" "Please install tar to make $(basename "$0") work." log_error "prerequisite" "Please install tar to make $(basename "$0") work."
return 1 return 1
elif ! command -v unzip >/dev/null 2>&1 ; then elif ! command -v unzip >/dev/null 2>&1 ; then
@ -222,12 +225,12 @@ function format_tree(){
function tree_file(){ function tree_file(){
file="$1" file="$1"
if [[ ${file} =~ \.deb$ ]] ; then if [[ ${file} =~ \.deb$ ]] ; then
if ! (7z l "${file}" 2>/dev/null | grep data.tar >/dev/null 2>&1) ; then if ! (7z l "${file}" 2>/dev/null | grep data.tar.zst >/dev/null 2>&1) ; then
log_error "package integrity" "${file} is not a valid deb package as it does not contain a root file named data.tar" log_error "package integrity" "${file} is not a valid deb package as it does not contain a root file named data.tar.zst"
return 1 return 1
fi fi
if ! (7z e -so "${file}" data.tar 2>/dev/null | tar -tvf - >/dev/null 2>&1) ; then if ! (7z e -so "${file}" data.tar.zst 2>/dev/null | tar --use-compress-program=unzstd -tvf - >/dev/null 2>&1) ; then
log_error "package integrity" "${file} is not a valid deb package as his data.tar file is not a valid tar package" log_error "package integrity" "${file} is not a valid deb package as his data.tar.zst file is not a valid tar package"
return 1 return 1
fi fi
raw_tree=$(tree_deb "${file}") raw_tree=$(tree_deb "${file}")
@ -255,7 +258,7 @@ function tree_file(){
function tree_deb(){ function tree_deb(){
file="$1" file="$1"
raw_tree=$(7z e -so "${file}" data.tar | tar -tvf - | grep -vE "\./$" | tr -s ' ' | cut --delimiter " " --field 1,2,3,6) raw_tree=$(7z e -so "${file}" data.tar.zst | tar --use-compress-program=unzstd -tvf - | grep -vE "\./$" | tr -s ' ' | cut --delimiter " " --field 1,2,3,6)
echo "${raw_tree}" echo "${raw_tree}"
} }

View File

@ -6,12 +6,19 @@ write-host -foregroundcolor Cyan "----- build release -----"
$actual_dir=(Get-Location).Path $actual_dir=(Get-Location).Path
$project_root_path=(Resolve-Path -LiteralPath $PSScriptRoot\..\..).path $project_root_path=(Resolve-Path -LiteralPath $PSScriptRoot\..\..).path
# link libs
$actual_path=$env:Path
$vcpkg_dir=(Split-Path -Parent (Get-Command vcpkg).Source) -replace '\\','/'
$lib_dir="$vcpkg_dir/installed/x64-windows/bin"
$env:VCPKGRS_DYNAMIC=1
$env:BINDGEN_EXTRA_CLANG_ARGS="-I$vcpkg_dir/installed/x64-windows/include/libxml2 -v"
$env:Path="$lib_dir" + ";" + "$actual_path"
# build # build
cargo build --release --verbose --locked cargo build --release --verbose --locked
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
# create final package # create final package
$lib_dir=((Get-Command vcpkg).Source | Split-path) + "\installed\x64-windows\bin"
$release_dir="$project_root_path\target\release" $release_dir="$project_root_path\target\release"
$package_dir="$project_root_path\target\win-package" $package_dir="$project_root_path\target\win-package"
New-Item -ItemType Directory -Force -Path $package_dir New-Item -ItemType Directory -Force -Path $package_dir
@ -28,7 +35,7 @@ Get-Content $package_dir\version.txt
# add hurl to PATH # add hurl to PATH
$registry_user_path=(Get-ItemProperty -Path 'HKCU:\Environment').Path $registry_user_path=(Get-ItemProperty -Path 'HKCU:\Environment').Path
$registry_machine_path=(Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment').Path $registry_machine_path=(Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment').Path
$env:Path = "$package_dir;$registry_user_path;$registry_machine_path" $env:Path = $actual_path + ";" + $package_dir + ";" + $registry_user_path + ";" + $registry_machine_path
sleep 10 sleep 10
# hurl infos # hurl infos

21
bin/release/test_caddy.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -Eeuo pipefail
echo "Test Caddy Hurl tests <https://github.com/caddyserver/caddy>"
echo "------------------------------------------------------------"
work_dir=build/
mkdir -p build/
cd "$work_dir".
rm -rf caddy || true
git clone --branch hurl-tests --no-depth https://github.com/caddyserver/caddy.git
cd caddy
# TODO: Install caddy depending on the system
caddy stop || true
caddy start 2>/dev/null
hurl --jobs 1 --variables-file caddytest/spec/hurl_vars.properties --test caddytest/spec/
caddy stop

26
bin/release/test_hurl_tuto.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
set -Eeuo pipefail
echo "Test Hurl tutorial <https://github.com/jcamiel/hurl-express-tutorial>"
echo "---------------------------------------------------------------------"
work_dir=build/
mkdir -p build/
cd "$work_dir".
rm -rf hurl-express-tutorial || true
git clone --no-depth https://github.com/jcamiel/hurl-express-tutorial
cd hurl-express-tutorial
docker stop movies || true
docker run --rm --detach --quiet \
--name movies \
--publish 3000:3000 \
ghcr.io/jcamiel/hurl-express-tutorial:latest
echo -e "GET http://localhost:3000\n200" | hurl --retry 60 --retry-interval 1s > /dev/null
hurl --variable host="http://localhost:3000" --test --color integration/*.hurl
docker stop movies

View File

@ -0,0 +1,29 @@
#!/bin/bash
set -Eeuo pipefail
echo "Test Python infra Hurl tests <https://github.com/python/psf-salt>"
echo "-----------------------------------------------------------------"
work_dir=build/
mkdir -p build/
cd "$work_dir".
rm -rf psf-salt || true
git clone --no-depth https://github.com/python/psf-salt.git
cd psf-salt
docker stop docs-redirects-nginx || true
docker run --rm --detach --quiet \
--name docs-redirects-nginx \
--tty \
--publish 10000:10000 \
--mount type=bind,source=./tests/docs-redirects/nginx.conf,target=/etc/nginx/conf.d/docs.conf,readonly \
--mount type=bind,source=./salt/docs/config/nginx.docs-redirects.conf,target=/etc/nginx/docs-redirects.conf,readonly \
nginx:1.26.1-alpine
echo -e "GET http://localhost:10000\n302" | hurl --retry 60 --retry-interval 1s > /dev/null
hurl --color --continue-on-error --variable host=http://localhost:10000 --test ./tests/docs-redirects/specs/*.hurl
docker stop docs-redirects-nginx

View File

@ -1,22 +1,21 @@
beautifulsoup4==4.12.3 beautifulsoup4==4.14.3
black==24.4.2 blinker==1.9.0
blinker==1.8.2 certifi==2025.11.12
certifi==2024.7.4 charset-normalizer==3.4.4
charset-normalizer==3.3.2 click==8.3.1
click==8.1.7 Flask==3.1.2
Flask==3.0.3 idna==3.11
idna==3.7
itsdangerous==2.2.0 itsdangerous==2.2.0
Jinja2==3.1.4 Jinja2==3.1.6
lxml==5.2.2 librt==0.7.2
MarkupSafe==2.1.5 MarkupSafe==3.0.3
mypy==1.10.0 mypy==1.19.0
mypy-extensions==1.0.0 mypy_extensions==1.1.0
packaging==24.1
pathspec==0.12.1 pathspec==0.12.1
platformdirs==4.2.2 requests==2.32.5
requests==2.32.3 ruff==0.14.8
soupsieve==2.5 soupsieve==2.8
typing_extensions==4.12.2 typing_extensions==4.15.0
urllib3==2.2.2 urllib3==2.6.0
Werkzeug==3.0.3 waitress==3.0.2
Werkzeug==3.1.4

View File

@ -1,6 +1,6 @@
black==24.4.2 beautifulsoup4==4.14.3
beautifulsoup4==4.12.3 Flask==3.1.2
Flask==3.0.3 mypy==1.19.0
lxml==5.2.2 requests==2.32.5
mypy==1.10.0 ruff==0.14.8
requests==2.32.3 waitress==3.0.2

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
from option import Option from option import Option
""" """

View File

@ -1,12 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from typing import List
import glob import glob
from option import Option
import generate_source
import generate_man
import generate_completion
import sys
import re import re
import sys
from typing import List
import generate_completion
import generate_man
import generate_source
from option import Option
def get_option_files(dir) -> List[str]: def get_option_files(dir) -> List[str]:

View File

@ -2,7 +2,9 @@
""" """
Generate Completion files Generate Completion files
""" """
from typing import *
from typing import List
from option import Option from option import Option
@ -19,8 +21,7 @@ _"""
+ name + name
+ """() + """()
{ {
local cur prev words cword cur="${COMP_WORDS[COMP_CWORD]}"
_init_completion || return
if [[ $cur == -* ]]; then if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '""" COMPREPLY=($(compgen -W '"""
@ -28,7 +29,8 @@ _"""
+ """' -- "$cur")) + """' -- "$cur"))
return return
fi fi
# Generate filenames by default
COMPREPLY=($(compgen -f "$cur" | sort))
} && } &&
complete -F _""" complete -F _"""
+ name + name
@ -121,17 +123,15 @@ def zsh_option(option: Option):
action = ": :" action = ": :"
if option.short and option.long: if option.short and option.long:
option_specifier = ( option_specifier = f"(-{option.short} --{option.long}){cardinality}'{{-{option.short},--{option.long}}}'"
f"(-{option.short} --{option.long})'{{-{option.short},--{option.long}}}'"
)
elif option.long: elif option.long:
option_specifier = f"--{option.long}" option_specifier = f"{cardinality}--{option.long}"
elif option.short: elif option.short:
option_specifier = f"-{option.short}" option_specifier = f"{cardinality}-{option.short}"
else: else:
raise ValueError("No long or short option specified") raise ValueError("No long or short option specified")
return f"'{cardinality}{option_specifier}[{help}]{action}' \\" return f"'{option_specifier}[{help}]{action}' \\"
def generate_fish_completion(name: str, options: List[Option]): def generate_fish_completion(name: str, options: List[Option]):

View File

@ -1,11 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
from option import Option from option import Option
""" """
Generate options for man Generate options for man
""" """
import sys
def generate_man(options: list[Option]) -> str: def generate_man(options: list[Option]) -> str:

View File

@ -1,7 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os
import sys import sys
from option import Option from option import Option
import sys
""" """
Generate source file for clap Generate source file for clap
@ -10,7 +11,7 @@ Generate source file for clap
COPYRIGHT = """/* COPYRIGHT = """/*
* Hurl (https://hurl.dev) * Hurl (https://hurl.dev)
* Copyright (C) 2024 Orange * Copyright (C) 2025 Orange
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,8 +26,6 @@ COPYRIGHT = """/*
* limitations under the License. * limitations under the License.
* *
*/""" */"""
import os
import sys
# Relative script file # Relative script file
SCRIPT_FILE = __file__[len(os.getcwd()) + 1 :] SCRIPT_FILE = __file__[len(os.getcwd()) + 1 :]
@ -58,24 +57,27 @@ def generate_source_option(option: Option) -> str:
s += f"\n .short('{option.short}')" s += f"\n .short('{option.short}')"
if option.value is not None: if option.value is not None:
s += f'\n .value_name("{option.value}")' s += f'\n .value_name("{option.value}")'
if option.value_default is not None:
s += f'\n .default_value("{option.value_default}")'
if option.value_parser is not None: if option.value_parser is not None:
s += f"\n .value_parser({option.value_parser})" s += f"\n .value_parser({option.value_parser})"
if "-1" in option.value_parser: if "-1" in option.value_parser:
s += f"\n .allow_hyphen_values(true)" s += "\n .allow_hyphen_values(true)"
s += f'\n .help("{option.help}")' help = option.help
if option.value_default is not None:
help += " [default: " + option.value_default + "]"
s += f'\n .help("{help}")'
if option.help_heading is not None:
s += f'\n .help_heading("{option.help_heading}")'
if option.conflict is not None: if option.conflict is not None:
for conflict in option.conflict: for conflict in option.conflict:
s += f'\n .conflicts_with("{conflict}")' s += f'\n .conflicts_with("{conflict}")'
if option.value is not None: if option.value is not None:
s += f"\n .num_args(1)" s += "\n .num_args(1)"
else: else:
s += f"\n .action(clap::ArgAction::SetTrue)" s += "\n .action(clap::ArgAction::SetTrue)"
if option.append: if option.append:
s += f"\n .action(clap::ArgAction::Append)" s += "\n .action(clap::ArgAction::Append)"
if option.deprecated or option.experimental: if option.deprecated or option.experimental:
s += f"\n .hide(true)" s += "\n .hide(true)"
s += "\n}" s += "\n}"
return s return s

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from dataclasses import dataclass from dataclasses import dataclass
from typing import * from typing import Optional
@dataclass @dataclass
@ -13,6 +13,7 @@ class Option:
value_default: Optional[str] = None value_default: Optional[str] = None
value_parser: Optional[str] = None value_parser: Optional[str] = None
help: Optional[str] = None help: Optional[str] = None
help_heading: Optional[str] = None
conflict: Optional[str] = None conflict: Optional[str] = None
append: bool = False append: bool = False
cli_only: bool = False cli_only: bool = False
@ -32,6 +33,8 @@ class Option:
s += "\nvalue_parser: " + self.value_parser s += "\nvalue_parser: " + self.value_parser
if self.help is not None: if self.help is not None:
s += "\nhelp: " + self.help s += "\nhelp: " + self.help
if self.help_heading is not None:
s += "\nhelp_heading: " + self.help_heading
if self.conflict is not None: if self.conflict is not None:
s += "\nconflict: " + " ".join(self.conflict) s += "\nconflict: " + " ".join(self.conflict)
if self.append: if self.append:
@ -55,6 +58,7 @@ class Option:
value_default = None value_default = None
value_parser = None value_parser = None
help = None help = None
help_heading = None
conflict = None conflict = None
append = False append = False
cli_only = False cli_only = False
@ -86,6 +90,8 @@ class Option:
help = v help = v
if help.endswith("."): if help.endswith("."):
raise Exception(f"{name}: help should not end with period") raise Exception(f"{name}: help should not end with period")
elif key == "help_heading":
help_heading = v
elif key == "conflict": elif key == "conflict":
conflict = [a.strip() for a in v.split(" ")] conflict = [a.strip() for a in v.split(" ")]
elif key == "multi": elif key == "multi":
@ -135,6 +141,7 @@ class Option:
value_default=value_default, value_default=value_default,
value_parser=value_parser, value_parser=value_parser,
help=help, help=help,
help_heading=help_heading,
conflict=conflict, conflict=conflict,
append=append, append=append,
cli_only=cli_only, cli_only=cli_only,
@ -145,8 +152,6 @@ class Option:
@staticmethod @staticmethod
def parse_file(filename: str) -> "Option": def parse_file(filename: str) -> "Option":
import sys
# sys.stderr.write("Parsing " + filename + "\n") # sys.stderr.write("Parsing " + filename + "\n")
s = open(filename).read() s = open(filename).read()
return Option.parse(s) return Option.parse(s)

View File

@ -17,6 +17,7 @@ value: SECONDS
value_default: 300 value_default: 300
value_parser: u64 value_parser: u64
help: Maximum time allowed for connection help: Maximum time allowed for connection
help_heading: HTTP options
--- ---
Maximum time in seconds that you allow Hurls connection to take. Maximum time in seconds that you allow Hurls connection to take.
@ -33,6 +34,7 @@ See also -m, --max-time.
value_default="300", value_default="300",
value_parser="u64", value_parser="u64",
help="Maximum time allowed for connection", help="Maximum time allowed for connection",
help_heading="HTTP options",
conflict=None, conflict=None,
append=False, append=False,
deprecated=False, deprecated=False,
@ -47,6 +49,7 @@ See also -m, --max-time.
long: connect-to long: connect-to
value: HOST1:PORT1:HOST2:PORT2 value: HOST1:PORT1:HOST2:PORT2
help: For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead help: For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead
help_heading: HTTP options
multi: append multi: append
--- ---
For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead. For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead.
@ -62,6 +65,7 @@ For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead.
value_default=None, value_default=None,
value_parser=None, value_parser=None,
help="For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead", help="For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead",
help_heading="HTTP options",
conflict=None, conflict=None,
append=True, append=True,
deprecated=False, deprecated=False,

127
bin/test/convert_hurl_to_crlf.sh Executable file
View File

@ -0,0 +1,127 @@
#!/bin/bash
set -Eeuo pipefail
# functions
function init_terminal_colors(){
color_red=$(echo -ne "\033[1;31m")
color_green=$(echo -ne "\033[1;32m")
color_yellow=$(echo -ne "\033[1;33m")
color_cyan=$(echo -ne "\033[1;36m")
color_reset=$(echo -ne "\033[0m")
}
function log(){
color="$1"
title="$2"
message="$3"
if basename "$0" >/dev/null 2>&1 ; then
parent=$(basename "$0")
else
parent="."
fi
echo "${color}${parent}: ${title}: ${message}${color_reset}"
}
function log_error(){
title="$1"
message="$2"
log "${color_red}" "${title}" "${message}"
}
function usage(){
echo
echo "Usage: $(basename "$0") [Options]..."
echo
echo "Options: #mandatory #optional"
echo
echo " --help #optional"
echo " This help text"
echo
echo " --dest-dir #optional"
echo " path where actual dir is copied to convert hurl files to CRLF"
echo " : default value: /tmp/hurl_tmp"
echo " : example: --dest-dir /tmp/my_tmp_dir"
echo
}
function consume_args(){
dest_dir=/tmp/hurl_tmp
while [[ $# -gt 0 ]] ; do
case "$1" in
--help)
usage
exit 0
;;
--dest-dir)
dest_dir=$2
shift
shift
;;
*)
log_error "option $1" "is unknown"
usage >&2
return 1
;;
esac
done
}
function prerequisites(){
if ! command -V unix2dos --version >/dev/null 2>&1 ; then
log_error "Prerequisites" "Please install dos2unix first."
exit 1
fi
}
function is_not_bad_format(){
file="$1"
if (file "${file}" | grep "very short file" >/dev/null 2>&1) ; then
return 1
else
return 0
fi
}
function is_not_assert_body(){
file="$1"
if (sed '/^HTTP/{N;s/\n/ /;}' "${file}" | grep -E "^HTTP.*\`\`\`" > /dev/null 2>&1) ; then
return 1
else
return 0
fi
}
# main
init_terminal_colors
prerequisites
consume_args "$@"
echo "${color_cyan}# Clone this dir ${PWD} to ${dest_dir}${color_reset}"
echo
if cp -frp . "${dest_dir}" ; then
echo " - current dir ${PWD} : ${color_green}copied to ${dest_dir}${color_reset}"
else
echo " - current dir ${PWD} : ${color_red}copied to ${dest_dir}${color_reset}"
exit 1
fi
cp -frp . "${dest_dir}"
echo
echo "${color_cyan}# Unix2dos all *.hurl files in ${dest_dir}${color_reset}"
echo
exit_code=0
while read -r hurl_file ; do
if is_not_bad_format "${hurl_file}" ; then
if is_not_assert_body "${hurl_file}" ; then
if unix2dos "${hurl_file}" ; then
echo " - ${hurl_file} : ${color_green}converted to dos${color_reset}"
else
echo " - ${hurl_file} : ${color_red}not converted to dos${color_reset}"
exit_code=1
fi
else
echo " - ${hurl_file} : ${color_yellow}not converted to dos because it contains body implicit asserts${color_reset}"
fi
else
echo " - ${hurl_file} : ${color_yellow}not converted (bad file format)${color_reset}"
fi
done < <(find "${dest_dir}/integration/hurl" -name "*.hurl")
exit "${exit_code}"

View File

@ -7,7 +7,7 @@ $actual_dir=(Get-Location).Path
$project_root_path=(Resolve-Path -LiteralPath $PSScriptRoot\..\..).path $project_root_path=(Resolve-Path -LiteralPath $PSScriptRoot\..\..).path
# install python libs # install python libs
python3 -m pip install --requirement $project_root_path\bin\requirements-frozen.txt python -m pip install --requirement $project_root_path\bin\requirements-frozen.txt
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
# start mock servers # start mock servers
@ -19,17 +19,17 @@ if ($LASTEXITCODE) { Throw }
sleep 5 sleep 5
if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8000) {write-host -foregroundcolor Green "server is up"} else {write-host -foregroundcolor Red "server is down" ; cat build\server.log ; exit 1} if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8000) {write-host -foregroundcolor Green "server is up"} else {write-host -foregroundcolor Red "server is down" ; cat build\server.log ; exit 1}
python ssl/server.py 8001 ssl/server/cert.selfsigned.pem false 2>&1 > build\server-ssl-selfsigned.log & python tests_ssl/ssl_server.py 8001 tests_ssl/certs/server/cert.selfsigned.pem false 2>&1 > build\server-ssl-selfsigned.log &
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
sleep 5 sleep 5
if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8001) {write-host -foregroundcolor Green "server-ssl-selfsigned up"} else {write-host -foregroundcolor Red "server-ssl-selfsigned is down" ; cat build\server-ssl-selfsigned.log ; exit 1} if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8001) {write-host -foregroundcolor Green "server-ssl-selfsigned up"} else {write-host -foregroundcolor Red "server-ssl-selfsigned is down" ; cat build\server-ssl-selfsigned.log ; exit 1}
python ssl/server.py 8002 ssl/server/cert.pem false 2>&1 > build\server-ssl-signedbyca.log & python tests_ssl/ssl_server.py 8002 tests_ssl/certs/server/cert.pem false 2>&1 > build\server-ssl-signedbyca.log &
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
sleep 5 sleep 5
if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8002) {write-host -foregroundcolor Green "server-ssl-signedbyca up"} else {write-host -foregroundcolor Red "server-ssl-signedbyca is down" ; cat build\server-ssl-signedbyca.log ; exit 1} if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8002) {write-host -foregroundcolor Green "server-ssl-signedbyca up"} else {write-host -foregroundcolor Red "server-ssl-signedbyca is down" ; cat build\server-ssl-signedbyca.log ; exit 1}
python ssl/server.py 8003 ssl/server/cert.pem true 2>&1 > build\server-ssl-client-authent.log & python tests_ssl/ssl_server.py 8003 tests_ssl/certs/server/cert.pem true 2>&1 > build\server-ssl-client-authent.log &
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
sleep 5 sleep 5
if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8003) {write-host -foregroundcolor Green "server-ssl-client-authent up"} else {write-host -foregroundcolor Red "server-ssl-client-authent is down" ; cat build\server-ssl-client-authent.log ; exit 1} if (netstat -ano | Select-String LISTENING | Select-string 127.0.0.1:8003) {write-host -foregroundcolor Green "server-ssl-client-authent up"} else {write-host -foregroundcolor Red "server-ssl-client-authent is down" ; cat build\server-ssl-client-authent.log ; exit 1}

View File

@ -77,21 +77,21 @@ echo -e "\n------------------ Starting server.py"
python3 server.py > build/server.log 2>&1 & python3 server.py > build/server.log 2>&1 &
check_listen_port "server.py" 8000 || cat_and_exit_err build/server.log check_listen_port "server.py" 8000 || cat_and_exit_err build/server.log
echo -e "\n------------------ Starting ssl/server.py (Self-signed certificate)" echo -e "\n------------------ Starting tests_ssl/ssl_server.py (Self-signed certificate)"
python3 ssl/server.py 8001 ssl/server/cert.selfsigned.pem false > build/server-ssl-selfsigned.log 2>&1 & python3 tests_ssl/ssl_server.py 8001 tests_ssl/certs/server/cert.selfsigned.pem false > build/server-ssl-selfsigned.log 2>&1 &
check_listen_port "ssl/server.py" 8001 || cat_and_exit_err build/server-ssl-selfsigned.log check_listen_port "tests_ssl/ssl_server.py" 8001 || cat_and_exit_err build/server-ssl-selfsigned.log
echo -e "\n------------------ Starting ssl/server.py (Signed by CA)" echo -e "\n------------------ Starting tests_ssl/ssl_server.py (Signed by CA)"
python3 ssl/server.py 8002 ssl/server/cert.pem false > build/server-ssl-signedbyca.log 2>&1 & python3 tests_ssl/ssl_server.py 8002 tests_ssl/certs/server/cert.pem false > build/server-ssl-signedbyca.log 2>&1 &
check_listen_port "ssl/server.py" 8002 || cat_and_exit_err build/server-ssl-signedbyca.log check_listen_port "tests_ssl/ssl_server.py" 8002 || cat_and_exit_err build/server-ssl-signedbyca.log
echo -e "\n------------------ Starting ssl/server.py (Self-signed certificate + Client certificate authentication)" echo -e "\n------------------ Starting ssl/ssl_server.py (Self-signed certificate + Client certificate authentication)"
python3 ssl/server.py 8003 ssl/server/cert.selfsigned.pem true > build/server-ssl-client-authent.log 2>&1 & python3 tests_ssl/ssl_server.py 8003 tests_ssl/certs/server/cert.selfsigned.pem true > build/server-ssl-client-authent.log 2>&1 &
check_listen_port "ssl/server.py" 8003 || cat_and_exit_err build/server-ssl-client-authent.log check_listen_port "tests_ssl/ssl_server.py" 8003 || cat_and_exit_err build/server-ssl-client-authent.log
echo -e "\n------------------ Starting unix_socket/server.py" echo -e "\n------------------ Starting tests_unix_socket/unix_socket_server.py"
python3 unix_socket/server.py > build/server-unix-socket.log 2>&1 & python3 tests_unix_socket/unix_socket_server.py > build/server-unix-socket.log 2>&1 &
check_unix_socket "unix_socket/server.py" build/unix_socket.sock "GET /hello HTTP/1.0\r\n" check_unix_socket "tests_unix_socket/unix_socket_server.py" build/unix_socket.sock "GET /hello HTTP/1.0\r\n"
echo -e "\n------------------ Starting squid (proxy)" echo -e "\n------------------ Starting squid (proxy)"
if [ -f /var/run/squid.pid ] ; then if [ -f /var/run/squid.pid ] ; then

View File

@ -3,20 +3,15 @@ $ErrorActionPreference = 'Stop'
write-host -foregroundcolor Cyan "----- unit tests -----" write-host -foregroundcolor Cyan "----- unit tests -----"
# exe dir
$original_env_path="$env:Path"
# lib dir
$vcpkg_dir=((Get-command vcpkg).Source | Split-Path)
$lib_dir="$vcpkg_dir\installed\x64-windows\bin"
# link libs # link libs
$env:Path = "$lib_dir" + ";" + "$original_env_path" $actual_path=$env:Path
$vcpkg_dir=(Split-Path -Parent (Get-Command vcpkg).Source) -replace '\\','/'
$lib_dir="$vcpkg_dir/installed/x64-windows/bin"
$env:VCPKGRS_DYNAMIC=1
$env:BINDGEN_EXTRA_CLANG_ARGS="-I$vcpkg_dir/installed/x64-windows/include/libxml2 -v"
$env:Path="$lib_dir" + ";" + "$actual_path"
# execute test units # execute test units
cargo test --release --tests cargo test --release --tests
if ($LASTEXITCODE) { Throw } if ($LASTEXITCODE) { Throw }
# unlink libs
$env:Path = "$original_env_path"

View File

@ -43,12 +43,10 @@ convert_toml_crates_to_key_value() {
get_crate_latest_version() { get_crate_latest_version() {
# init args # init args
crate_url="$1" crate="$1"
# get crate latest version # get crate latest version
crate_object=$(curl -kLs "${crate_url}" || true) last_version=$( (cargo info "${crate}" 2<&1 || true) | (grep "^version: " || true) | cut -d':' -f2 | tr -d ' ' | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
crate_max_stable_version=$(echo "${crate_object}" | (jq -r .crate.max_stable_version 2>/dev/null || true))
last_version=$(echo "${crate_max_stable_version}" | (grep --extended-regexp --only-matching "^[0-9]*\.[0-9]*\.[0-9]*" || true))
echo "${last_version}" echo "${last_version}"
} }
@ -112,10 +110,9 @@ main() {
echo -e "\n--------------------------------------------------------" echo -e "\n--------------------------------------------------------"
echo -e "### Crates updates for *${toml_file}*\n" echo -e "### Crates updates for *${toml_file}*\n"
while read -r crate actual_version; do while read -r crate actual_version; do
crate_url="${crates_api_root_url}/${crate}" last_version=$(get_crate_latest_version "${crate}")
last_version=$(get_crate_latest_version "${crate_url}")
if [ -z "${last_version}" ]; then if [ -z "${last_version}" ]; then
echo "${color_red}runtime error${color_reset}, i could not get last version from ${crate_url}" echo "${color_red}runtime error${color_reset}, i could not get last version for ${crate}"
return 1 return 1
fi fi
echo -n "- ${crate} ${actual_version} " echo -n "- ${crate} ${actual_version} "
@ -127,6 +124,7 @@ main() {
updated_count=$((updated_count + 1)) updated_count=$((updated_count + 1))
else else
update_crate_version_in_toml "${crate}" "${actual_version}" "${last_version}" "${toml_file}" update_crate_version_in_toml "${crate}" "${actual_version}" "${last_version}" "${toml_file}"
crate_url="${crates_api_root_url}/${crate}"
get_crate_github_release_body "${crate_url}" "${last_version}" get_crate_github_release_body "${crate_url}" "${last_version}"
fi fi
fi fi
@ -164,4 +162,3 @@ main() {
# run # run
main "$@" main "$@"

View File

@ -25,15 +25,16 @@ _hurl() {
'*--connect-to[For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead]: :' \ '*--connect-to[For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead]: :' \
'--continue-on-error[Continue executing requests even if an error occurs]' \ '--continue-on-error[Continue executing requests even if an error occurs]' \
'(-b --cookie)'{-b,--cookie}'[Read cookies from FILE]: :_files' \ '(-b --cookie)'{-b,--cookie}'[Read cookies from FILE]: :_files' \
'(-c --cookie-jar)'{-c,--cookie-jar}'[Write cookies to FILE after running the session (only for one session)]: :_files' \ '(-c --cookie-jar)'{-c,--cookie-jar}'[Write cookies to FILE after running the session]: :_files' \
'--delay[Sets delay before each request]: :' \ '--curl[Export each request to a list of curl commands]: :_files' \
'--delay[Sets delay before each request (aka sleep)]: :' \
'--error-format[Control the format of error messages]: :' \ '--error-format[Control the format of error messages]: :' \
'--fail-at-end[Fail at end]' \
'--file-root[Set root directory to import files \[default: input file directory\]]: :' \ '--file-root[Set root directory to import files \[default: input file directory\]]: :' \
'(-L --location)'{-L,--location}'[Follow redirects]' \ '(-L --location)'{-L,--location}'[Follow redirects]' \
'--location-trusted[Follow redirects but allows sending the name + password to all hosts that the site may redirect to]' \ '--location-trusted[Follow redirects but allows sending the name + password to all hosts that the site may redirect to]' \
'--from-entry[Execute Hurl file from ENTRY_NUMBER (starting at 1)]: :' \ '--from-entry[Execute Hurl file from ENTRY_NUMBER (starting at 1)]: :' \
'*--glob[Specify input files that match the given GLOB. Multiple glob flags may be used]: :' \ '*--glob[Specify input files that match the given GLOB. Multiple glob flags may be used]: :' \
'(-H --header)*'{-H,--header}'[Pass custom header(s) to server]: :' \
'(-0 --http1.0)'{-0,--http1.0}'[Tell Hurl to use HTTP version 1.0]' \ '(-0 --http1.0)'{-0,--http1.0}'[Tell Hurl to use HTTP version 1.0]' \
'--http1.1[Tell Hurl to use HTTP version 1.1]' \ '--http1.1[Tell Hurl to use HTTP version 1.1]' \
'--http2[Tell Hurl to use HTTP version 2]' \ '--http2[Tell Hurl to use HTTP version 2]' \
@ -44,20 +45,27 @@ _hurl() {
'--interactive[Turn on interactive mode]' \ '--interactive[Turn on interactive mode]' \
'(-4 --ipv4)'{-4,--ipv4}'[Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6]' \ '(-4 --ipv4)'{-4,--ipv4}'[Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6]' \
'(-6 --ipv6)'{-6,--ipv6}'[Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4]' \ '(-6 --ipv6)'{-6,--ipv6}'[Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4]' \
'--jobs[Maximum number of parallel jobs]: :' \ '--jobs[Maximum number of parallel jobs, 0 to disable parallel execution]: :' \
'--json[Output each Hurl file result to JSON]' \ '--json[Output each Hurl file result to JSON]' \
'--max-filesize[Specify the maximum size (in bytes) of a file to download]: :' \ '--limit-rate[Specify the maximum transfer rate in bytes/second, for both downloads and uploads]: :' \
'--max-filesize[Specify the maximum size in bytes of a file to download]: :' \
'--max-redirs[Maximum number of redirects allowed, -1 for unlimited redirects]: :' \ '--max-redirs[Maximum number of redirects allowed, -1 for unlimited redirects]: :' \
'(-m --max-time)'{-m,--max-time}'[Maximum time allowed for the transfer]: :' \ '(-m --max-time)'{-m,--max-time}'[Maximum time allowed for the transfer]: :' \
'--negotiate[Tell Hurl to use Negotiate (SPNEGO) authentication]' \
'(-n --netrc)'{-n,--netrc}'[Must read .netrc for username and password]' \ '(-n --netrc)'{-n,--netrc}'[Must read .netrc for username and password]' \
'--netrc-file[Specify FILE for .netrc]: :_files' \ '--netrc-file[Specify FILE for .netrc]: :_files' \
'--netrc-optional[Use either .netrc or the URL]' \ '--netrc-optional[Use either .netrc or the URL]' \
'--no-color[Do not colorize output]' \ '--no-color[Do not colorize output]' \
'--no-output[Suppress output. By default, Hurl outputs the body of the last response]' \ '--no-output[Suppress output. By default, Hurl outputs the body of the last response]' \
'--no-pretty[Do not prettify response output]' \
'--noproxy[List of hosts which do not use proxy]: :' \ '--noproxy[List of hosts which do not use proxy]: :' \
'--ntlm[Tell Hurl to use NTLM authentication]' \
'(-o --output)'{-o,--output}'[Write to FILE instead of stdout]: :_files' \ '(-o --output)'{-o,--output}'[Write to FILE instead of stdout]: :_files' \
'--parallel[Run files in parallel (default in test mode)]' \ '--parallel[Run files in parallel (default in test mode)]' \
'--path-as-is[Tell Hurl to not handle sequences of /../ or /./ in the given URL path]' \ '--path-as-is[Tell Hurl to not handle sequences of /../ or /./ in the given URL path]' \
'--pinnedpubkey[Public key to verify peer against]: :' \
'--pretty[Prettify JSON response output]' \
'--progress-bar[Display a progress bar in test mode]' \
'(-x --proxy)'{-x,--proxy}'[Use proxy on given PROTOCOL/HOST/PORT]: :' \ '(-x --proxy)'{-x,--proxy}'[Use proxy on given PROTOCOL/HOST/PORT]: :' \
'--repeat[Repeat the input files sequence NUM times, -1 for infinite loop]: :' \ '--repeat[Repeat the input files sequence NUM times, -1 for infinite loop]: :' \
'--report-html[Generate HTML report to DIR]: :' \ '--report-html[Generate HTML report to DIR]: :' \
@ -67,6 +75,8 @@ _hurl() {
'*--resolve[Provide a custom address for a specific HOST and PORT pair]: :' \ '*--resolve[Provide a custom address for a specific HOST and PORT pair]: :' \
'--retry[Maximum number of retries, 0 for no retries, -1 for unlimited retries]: :' \ '--retry[Maximum number of retries, 0 for no retries, -1 for unlimited retries]: :' \
'--retry-interval[Interval in milliseconds before a retry]: :' \ '--retry-interval[Interval in milliseconds before a retry]: :' \
'*--secret[Define a variable which value is secret]: :' \
'*--secrets-file[Define a secrets file in which you define your secrets]: :_files' \
'--ssl-no-revoke[(Windows) Tell Hurl to disable certificate revocation checks]' \ '--ssl-no-revoke[(Windows) Tell Hurl to disable certificate revocation checks]' \
'--test[Activate test mode (use parallel execution)]' \ '--test[Activate test mode (use parallel execution)]' \
'--to-entry[Execute Hurl file to ENTRY_NUMBER (starting at 1)]: :' \ '--to-entry[Execute Hurl file to ENTRY_NUMBER (starting at 1)]: :' \

View File

@ -30,15 +30,16 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock {
[CompletionResult]::new('--connect-to', 'connect-to', [CompletionResultType]::ParameterName, 'For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead') [CompletionResult]::new('--connect-to', 'connect-to', [CompletionResultType]::ParameterName, 'For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead')
[CompletionResult]::new('--continue-on-error', 'continue-on-error', [CompletionResultType]::ParameterName, 'Continue executing requests even if an error occurs') [CompletionResult]::new('--continue-on-error', 'continue-on-error', [CompletionResultType]::ParameterName, 'Continue executing requests even if an error occurs')
[CompletionResult]::new('--cookie', 'cookie', [CompletionResultType]::ParameterName, 'Read cookies from FILE') [CompletionResult]::new('--cookie', 'cookie', [CompletionResultType]::ParameterName, 'Read cookies from FILE')
[CompletionResult]::new('--cookie-jar', 'cookie-jar', [CompletionResultType]::ParameterName, 'Write cookies to FILE after running the session (only for one session)') [CompletionResult]::new('--cookie-jar', 'cookie-jar', [CompletionResultType]::ParameterName, 'Write cookies to FILE after running the session')
[CompletionResult]::new('--delay', 'delay', [CompletionResultType]::ParameterName, 'Sets delay before each request') [CompletionResult]::new('--curl', 'curl', [CompletionResultType]::ParameterName, 'Export each request to a list of curl commands')
[CompletionResult]::new('--delay', 'delay', [CompletionResultType]::ParameterName, 'Sets delay before each request (aka sleep)')
[CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'Control the format of error messages') [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'Control the format of error messages')
[CompletionResult]::new('--fail-at-end', 'fail-at-end', [CompletionResultType]::ParameterName, 'Fail at end')
[CompletionResult]::new('--file-root', 'file-root', [CompletionResultType]::ParameterName, 'Set root directory to import files [default: input file directory]') [CompletionResult]::new('--file-root', 'file-root', [CompletionResultType]::ParameterName, 'Set root directory to import files [default: input file directory]')
[CompletionResult]::new('--location', 'location', [CompletionResultType]::ParameterName, 'Follow redirects') [CompletionResult]::new('--location', 'location', [CompletionResultType]::ParameterName, 'Follow redirects')
[CompletionResult]::new('--location-trusted', 'location-trusted', [CompletionResultType]::ParameterName, 'Follow redirects but allows sending the name + password to all hosts that the site may redirect to') [CompletionResult]::new('--location-trusted', 'location-trusted', [CompletionResultType]::ParameterName, 'Follow redirects but allows sending the name + password to all hosts that the site may redirect to')
[CompletionResult]::new('--from-entry', 'from-entry', [CompletionResultType]::ParameterName, 'Execute Hurl file from ENTRY_NUMBER (starting at 1)') [CompletionResult]::new('--from-entry', 'from-entry', [CompletionResultType]::ParameterName, 'Execute Hurl file from ENTRY_NUMBER (starting at 1)')
[CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Specify input files that match the given GLOB. Multiple glob flags may be used') [CompletionResult]::new('--glob', 'glob', [CompletionResultType]::ParameterName, 'Specify input files that match the given GLOB. Multiple glob flags may be used')
[CompletionResult]::new('--header', 'header', [CompletionResultType]::ParameterName, 'Pass custom header(s) to server')
[CompletionResult]::new('--http1.0', 'http1.0', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 1.0') [CompletionResult]::new('--http1.0', 'http1.0', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 1.0')
[CompletionResult]::new('--http1.1', 'http1.1', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 1.1') [CompletionResult]::new('--http1.1', 'http1.1', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 1.1')
[CompletionResult]::new('--http2', 'http2', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 2') [CompletionResult]::new('--http2', 'http2', [CompletionResultType]::ParameterName, 'Tell Hurl to use HTTP version 2')
@ -49,20 +50,27 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock {
[CompletionResult]::new('--interactive', 'interactive', [CompletionResultType]::ParameterName, 'Turn on interactive mode') [CompletionResult]::new('--interactive', 'interactive', [CompletionResultType]::ParameterName, 'Turn on interactive mode')
[CompletionResult]::new('--ipv4', 'ipv4', [CompletionResultType]::ParameterName, 'Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6') [CompletionResult]::new('--ipv4', 'ipv4', [CompletionResultType]::ParameterName, 'Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6')
[CompletionResult]::new('--ipv6', 'ipv6', [CompletionResultType]::ParameterName, 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4') [CompletionResult]::new('--ipv6', 'ipv6', [CompletionResultType]::ParameterName, 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4')
[CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'Maximum number of parallel jobs') [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'Maximum number of parallel jobs, 0 to disable parallel execution')
[CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Output each Hurl file result to JSON') [CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Output each Hurl file result to JSON')
[CompletionResult]::new('--max-filesize', 'max-filesize', [CompletionResultType]::ParameterName, 'Specify the maximum size (in bytes) of a file to download') [CompletionResult]::new('--limit-rate', 'limit-rate', [CompletionResultType]::ParameterName, 'Specify the maximum transfer rate in bytes/second, for both downloads and uploads')
[CompletionResult]::new('--max-filesize', 'max-filesize', [CompletionResultType]::ParameterName, 'Specify the maximum size in bytes of a file to download')
[CompletionResult]::new('--max-redirs', 'max-redirs', [CompletionResultType]::ParameterName, 'Maximum number of redirects allowed, -1 for unlimited redirects') [CompletionResult]::new('--max-redirs', 'max-redirs', [CompletionResultType]::ParameterName, 'Maximum number of redirects allowed, -1 for unlimited redirects')
[CompletionResult]::new('--max-time', 'max-time', [CompletionResultType]::ParameterName, 'Maximum time allowed for the transfer') [CompletionResult]::new('--max-time', 'max-time', [CompletionResultType]::ParameterName, 'Maximum time allowed for the transfer')
[CompletionResult]::new('--negotiate', 'negotiate', [CompletionResultType]::ParameterName, 'Tell Hurl to use Negotiate (SPNEGO) authentication')
[CompletionResult]::new('--netrc', 'netrc', [CompletionResultType]::ParameterName, 'Must read .netrc for username and password') [CompletionResult]::new('--netrc', 'netrc', [CompletionResultType]::ParameterName, 'Must read .netrc for username and password')
[CompletionResult]::new('--netrc-file', 'netrc-file', [CompletionResultType]::ParameterName, 'Specify FILE for .netrc') [CompletionResult]::new('--netrc-file', 'netrc-file', [CompletionResultType]::ParameterName, 'Specify FILE for .netrc')
[CompletionResult]::new('--netrc-optional', 'netrc-optional', [CompletionResultType]::ParameterName, 'Use either .netrc or the URL') [CompletionResult]::new('--netrc-optional', 'netrc-optional', [CompletionResultType]::ParameterName, 'Use either .netrc or the URL')
[CompletionResult]::new('--no-color', 'no-color', [CompletionResultType]::ParameterName, 'Do not colorize output') [CompletionResult]::new('--no-color', 'no-color', [CompletionResultType]::ParameterName, 'Do not colorize output')
[CompletionResult]::new('--no-output', 'no-output', [CompletionResultType]::ParameterName, 'Suppress output. By default, Hurl outputs the body of the last response') [CompletionResult]::new('--no-output', 'no-output', [CompletionResultType]::ParameterName, 'Suppress output. By default, Hurl outputs the body of the last response')
[CompletionResult]::new('--no-pretty', 'no-pretty', [CompletionResultType]::ParameterName, 'Do not prettify response output')
[CompletionResult]::new('--noproxy', 'noproxy', [CompletionResultType]::ParameterName, 'List of hosts which do not use proxy') [CompletionResult]::new('--noproxy', 'noproxy', [CompletionResultType]::ParameterName, 'List of hosts which do not use proxy')
[CompletionResult]::new('--ntlm', 'ntlm', [CompletionResultType]::ParameterName, 'Tell Hurl to use NTLM authentication')
[CompletionResult]::new('--output', 'output', [CompletionResultType]::ParameterName, 'Write to FILE instead of stdout') [CompletionResult]::new('--output', 'output', [CompletionResultType]::ParameterName, 'Write to FILE instead of stdout')
[CompletionResult]::new('--parallel', 'parallel', [CompletionResultType]::ParameterName, 'Run files in parallel (default in test mode)') [CompletionResult]::new('--parallel', 'parallel', [CompletionResultType]::ParameterName, 'Run files in parallel (default in test mode)')
[CompletionResult]::new('--path-as-is', 'path-as-is', [CompletionResultType]::ParameterName, 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path') [CompletionResult]::new('--path-as-is', 'path-as-is', [CompletionResultType]::ParameterName, 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path')
[CompletionResult]::new('--pinnedpubkey', 'pinnedpubkey', [CompletionResultType]::ParameterName, 'Public key to verify peer against')
[CompletionResult]::new('--pretty', 'pretty', [CompletionResultType]::ParameterName, 'Prettify JSON response output')
[CompletionResult]::new('--progress-bar', 'progress-bar', [CompletionResultType]::ParameterName, 'Display a progress bar in test mode')
[CompletionResult]::new('--proxy', 'proxy', [CompletionResultType]::ParameterName, 'Use proxy on given PROTOCOL/HOST/PORT') [CompletionResult]::new('--proxy', 'proxy', [CompletionResultType]::ParameterName, 'Use proxy on given PROTOCOL/HOST/PORT')
[CompletionResult]::new('--repeat', 'repeat', [CompletionResultType]::ParameterName, 'Repeat the input files sequence NUM times, -1 for infinite loop') [CompletionResult]::new('--repeat', 'repeat', [CompletionResultType]::ParameterName, 'Repeat the input files sequence NUM times, -1 for infinite loop')
[CompletionResult]::new('--report-html', 'report-html', [CompletionResultType]::ParameterName, 'Generate HTML report to DIR') [CompletionResult]::new('--report-html', 'report-html', [CompletionResultType]::ParameterName, 'Generate HTML report to DIR')
@ -72,6 +80,8 @@ Register-ArgumentCompleter -Native -CommandName 'hurl' -ScriptBlock {
[CompletionResult]::new('--resolve', 'resolve', [CompletionResultType]::ParameterName, 'Provide a custom address for a specific HOST and PORT pair') [CompletionResult]::new('--resolve', 'resolve', [CompletionResultType]::ParameterName, 'Provide a custom address for a specific HOST and PORT pair')
[CompletionResult]::new('--retry', 'retry', [CompletionResultType]::ParameterName, 'Maximum number of retries, 0 for no retries, -1 for unlimited retries') [CompletionResult]::new('--retry', 'retry', [CompletionResultType]::ParameterName, 'Maximum number of retries, 0 for no retries, -1 for unlimited retries')
[CompletionResult]::new('--retry-interval', 'retry-interval', [CompletionResultType]::ParameterName, 'Interval in milliseconds before a retry') [CompletionResult]::new('--retry-interval', 'retry-interval', [CompletionResultType]::ParameterName, 'Interval in milliseconds before a retry')
[CompletionResult]::new('--secret', 'secret', [CompletionResultType]::ParameterName, 'Define a variable which value is secret')
[CompletionResult]::new('--secrets-file', 'secrets-file', [CompletionResultType]::ParameterName, 'Define a secrets file in which you define your secrets')
[CompletionResult]::new('--ssl-no-revoke', 'ssl-no-revoke', [CompletionResultType]::ParameterName, '(Windows) Tell Hurl to disable certificate revocation checks') [CompletionResult]::new('--ssl-no-revoke', 'ssl-no-revoke', [CompletionResultType]::ParameterName, '(Windows) Tell Hurl to disable certificate revocation checks')
[CompletionResult]::new('--test', 'test', [CompletionResultType]::ParameterName, 'Activate test mode (use parallel execution)') [CompletionResult]::new('--test', 'test', [CompletionResultType]::ParameterName, 'Activate test mode (use parallel execution)')
[CompletionResult]::new('--to-entry', 'to-entry', [CompletionResultType]::ParameterName, 'Execute Hurl file to ENTRY_NUMBER (starting at 1)') [CompletionResult]::new('--to-entry', 'to-entry', [CompletionResultType]::ParameterName, 'Execute Hurl file to ENTRY_NUMBER (starting at 1)')

View File

@ -17,7 +17,6 @@ _hurlfmt() {
_arguments "${_arguments_options[@]}" \ _arguments "${_arguments_options[@]}" \
'--check[Run in check mode]' \ '--check[Run in check mode]' \
'--color[Colorize Output]' \ '--color[Colorize Output]' \
'--format[Specify output format: hurl, json or html]: :' \
'--in-place[Modify files in place]' \ '--in-place[Modify files in place]' \
'--in[Specify input format: hurl or curl]: :' \ '--in[Specify input format: hurl or curl]: :' \
'--no-color[Do not colorize output]' \ '--no-color[Do not colorize output]' \

View File

@ -22,7 +22,6 @@ Register-ArgumentCompleter -Native -CommandName 'hurlfmt' -ScriptBlock {
'hurlfmt' 'hurlfmt'
{[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run in check mode') {[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run in check mode')
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Colorize Output') [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Colorize Output')
[CompletionResult]::new('--format', 'format', [CompletionResultType]::ParameterName, 'Specify output format: hurl, json or html')
[CompletionResult]::new('--in-place', 'in-place', [CompletionResultType]::ParameterName, 'Modify files in place') [CompletionResult]::new('--in-place', 'in-place', [CompletionResultType]::ParameterName, 'Modify files in place')
[CompletionResult]::new('--in', 'in', [CompletionResultType]::ParameterName, 'Specify input format: hurl or curl') [CompletionResult]::new('--in', 'in', [CompletionResultType]::ParameterName, 'Specify input format: hurl or curl')
[CompletionResult]::new('--no-color', 'no-color', [CompletionResultType]::ParameterName, 'Do not colorize output') [CompletionResult]::new('--no-color', 'no-color', [CompletionResultType]::ParameterName, 'Do not colorize output')

View File

@ -1,14 +1,14 @@
# hurl(1) completion -*- shell-script -*- # hurl(1) completion -*- shell-script -*-
_hurl() _hurl()
{ {
local cur prev words cword cur="${COMP_WORDS[COMP_CWORD]}"
_init_completion || return
if [[ $cur == -* ]]; then if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --delay --error-format --fail-at-end --file-root --location --location-trusted --from-entry --glob --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --max-filesize --max-redirs --max-time --netrc --netrc-file --netrc-optional --no-color --no-output --noproxy --output --parallel --path-as-is --proxy --repeat --report-html --report-json --report-junit --report-tap --resolve --retry --retry-interval --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur")) COMPREPLY=($(compgen -W '--aws-sigv4 --cacert --cert --key --color --compressed --connect-timeout --connect-to --continue-on-error --cookie --cookie-jar --curl --delay --error-format --file-root --location --location-trusted --from-entry --glob --header --http1.0 --http1.1 --http2 --http3 --ignore-asserts --include --insecure --interactive --ipv4 --ipv6 --jobs --json --limit-rate --max-filesize --max-redirs --max-time --negotiate --netrc --netrc-file --netrc-optional --no-color --no-output --no-pretty --noproxy --ntlm --output --parallel --path-as-is --pinnedpubkey --pretty --progress-bar --proxy --repeat --report-html --report-json --report-junit --report-tap --resolve --retry --retry-interval --secret --secrets-file --ssl-no-revoke --test --to-entry --unix-socket --user --user-agent --variable --variables-file --verbose --very-verbose --help --version' -- "$cur"))
return return
fi fi
# Generate filenames by default
COMPREPLY=($(compgen -f "$cur" | sort))
} && } &&
complete -F _hurl hurl complete -F _hurl hurl
# ex: filetype=sh # ex: filetype=sh

View File

@ -8,15 +8,16 @@ complete -c hurl -l connect-timeout -d 'Maximum time allowed for connection'
complete -c hurl -l connect-to -d 'For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead' complete -c hurl -l connect-to -d 'For a request to the given HOST1:PORT1 pair, connect to HOST2:PORT2 instead'
complete -c hurl -l continue-on-error -d 'Continue executing requests even if an error occurs' complete -c hurl -l continue-on-error -d 'Continue executing requests even if an error occurs'
complete -c hurl -l cookie -d 'Read cookies from FILE' complete -c hurl -l cookie -d 'Read cookies from FILE'
complete -c hurl -l cookie-jar -d 'Write cookies to FILE after running the session (only for one session)' complete -c hurl -l cookie-jar -d 'Write cookies to FILE after running the session'
complete -c hurl -l delay -d 'Sets delay before each request' complete -c hurl -l curl -d 'Export each request to a list of curl commands'
complete -c hurl -l delay -d 'Sets delay before each request (aka sleep)'
complete -c hurl -l error-format -d 'Control the format of error messages' complete -c hurl -l error-format -d 'Control the format of error messages'
complete -c hurl -l fail-at-end -d 'Fail at end'
complete -c hurl -l file-root -d 'Set root directory to import files [default: input file directory]' complete -c hurl -l file-root -d 'Set root directory to import files [default: input file directory]'
complete -c hurl -l location -d 'Follow redirects' complete -c hurl -l location -d 'Follow redirects'
complete -c hurl -l location-trusted -d 'Follow redirects but allows sending the name + password to all hosts that the site may redirect to' complete -c hurl -l location-trusted -d 'Follow redirects but allows sending the name + password to all hosts that the site may redirect to'
complete -c hurl -l from-entry -d 'Execute Hurl file from ENTRY_NUMBER (starting at 1)' complete -c hurl -l from-entry -d 'Execute Hurl file from ENTRY_NUMBER (starting at 1)'
complete -c hurl -l glob -d 'Specify input files that match the given GLOB. Multiple glob flags may be used' complete -c hurl -l glob -d 'Specify input files that match the given GLOB. Multiple glob flags may be used'
complete -c hurl -l header -d 'Pass custom header(s) to server'
complete -c hurl -l http1.0 -d 'Tell Hurl to use HTTP version 1.0' complete -c hurl -l http1.0 -d 'Tell Hurl to use HTTP version 1.0'
complete -c hurl -l http1.1 -d 'Tell Hurl to use HTTP version 1.1' complete -c hurl -l http1.1 -d 'Tell Hurl to use HTTP version 1.1'
complete -c hurl -l http2 -d 'Tell Hurl to use HTTP version 2' complete -c hurl -l http2 -d 'Tell Hurl to use HTTP version 2'
@ -27,20 +28,27 @@ complete -c hurl -l insecure -d 'Allow insecure SSL connections'
complete -c hurl -l interactive -d 'Turn on interactive mode' complete -c hurl -l interactive -d 'Turn on interactive mode'
complete -c hurl -l ipv4 -d 'Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6' complete -c hurl -l ipv4 -d 'Tell Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6'
complete -c hurl -l ipv6 -d 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4' complete -c hurl -l ipv6 -d 'Tell Hurl to use IPv6 addresses only when resolving host names, and not for example try IPv4'
complete -c hurl -l jobs -d 'Maximum number of parallel jobs' complete -c hurl -l jobs -d 'Maximum number of parallel jobs, 0 to disable parallel execution'
complete -c hurl -l json -d 'Output each Hurl file result to JSON' complete -c hurl -l json -d 'Output each Hurl file result to JSON'
complete -c hurl -l max-filesize -d 'Specify the maximum size (in bytes) of a file to download' complete -c hurl -l limit-rate -d 'Specify the maximum transfer rate in bytes/second, for both downloads and uploads'
complete -c hurl -l max-filesize -d 'Specify the maximum size in bytes of a file to download'
complete -c hurl -l max-redirs -d 'Maximum number of redirects allowed, -1 for unlimited redirects' complete -c hurl -l max-redirs -d 'Maximum number of redirects allowed, -1 for unlimited redirects'
complete -c hurl -l max-time -d 'Maximum time allowed for the transfer' complete -c hurl -l max-time -d 'Maximum time allowed for the transfer'
complete -c hurl -l negotiate -d 'Tell Hurl to use Negotiate (SPNEGO) authentication'
complete -c hurl -l netrc -d 'Must read .netrc for username and password' complete -c hurl -l netrc -d 'Must read .netrc for username and password'
complete -c hurl -l netrc-file -d 'Specify FILE for .netrc' complete -c hurl -l netrc-file -d 'Specify FILE for .netrc'
complete -c hurl -l netrc-optional -d 'Use either .netrc or the URL' complete -c hurl -l netrc-optional -d 'Use either .netrc or the URL'
complete -c hurl -l no-color -d 'Do not colorize output' complete -c hurl -l no-color -d 'Do not colorize output'
complete -c hurl -l no-output -d 'Suppress output. By default, Hurl outputs the body of the last response' complete -c hurl -l no-output -d 'Suppress output. By default, Hurl outputs the body of the last response'
complete -c hurl -l no-pretty -d 'Do not prettify response output'
complete -c hurl -l noproxy -d 'List of hosts which do not use proxy' complete -c hurl -l noproxy -d 'List of hosts which do not use proxy'
complete -c hurl -l ntlm -d 'Tell Hurl to use NTLM authentication'
complete -c hurl -l output -d 'Write to FILE instead of stdout' complete -c hurl -l output -d 'Write to FILE instead of stdout'
complete -c hurl -l parallel -d 'Run files in parallel (default in test mode)' complete -c hurl -l parallel -d 'Run files in parallel (default in test mode)'
complete -c hurl -l path-as-is -d 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path' complete -c hurl -l path-as-is -d 'Tell Hurl to not handle sequences of /../ or /./ in the given URL path'
complete -c hurl -l pinnedpubkey -d 'Public key to verify peer against'
complete -c hurl -l pretty -d 'Prettify JSON response output'
complete -c hurl -l progress-bar -d 'Display a progress bar in test mode'
complete -c hurl -l proxy -d 'Use proxy on given PROTOCOL/HOST/PORT' complete -c hurl -l proxy -d 'Use proxy on given PROTOCOL/HOST/PORT'
complete -c hurl -l repeat -d 'Repeat the input files sequence NUM times, -1 for infinite loop' complete -c hurl -l repeat -d 'Repeat the input files sequence NUM times, -1 for infinite loop'
complete -c hurl -l report-html -d 'Generate HTML report to DIR' complete -c hurl -l report-html -d 'Generate HTML report to DIR'
@ -50,6 +58,8 @@ complete -c hurl -l report-tap -d 'Write a TAP report to FILE'
complete -c hurl -l resolve -d 'Provide a custom address for a specific HOST and PORT pair' complete -c hurl -l resolve -d 'Provide a custom address for a specific HOST and PORT pair'
complete -c hurl -l retry -d 'Maximum number of retries, 0 for no retries, -1 for unlimited retries' complete -c hurl -l retry -d 'Maximum number of retries, 0 for no retries, -1 for unlimited retries'
complete -c hurl -l retry-interval -d 'Interval in milliseconds before a retry' complete -c hurl -l retry-interval -d 'Interval in milliseconds before a retry'
complete -c hurl -l secret -d 'Define a variable which value is secret'
complete -c hurl -l secrets-file -d 'Define a secrets file in which you define your secrets'
complete -c hurl -l ssl-no-revoke -d '(Windows) Tell Hurl to disable certificate revocation checks' complete -c hurl -l ssl-no-revoke -d '(Windows) Tell Hurl to disable certificate revocation checks'
complete -c hurl -l test -d 'Activate test mode (use parallel execution)' complete -c hurl -l test -d 'Activate test mode (use parallel execution)'
complete -c hurl -l to-entry -d 'Execute Hurl file to ENTRY_NUMBER (starting at 1)' complete -c hurl -l to-entry -d 'Execute Hurl file to ENTRY_NUMBER (starting at 1)'

View File

@ -1,14 +1,14 @@
# hurlfmt(1) completion -*- shell-script -*- # hurlfmt(1) completion -*- shell-script -*-
_hurlfmt() _hurlfmt()
{ {
local cur prev words cword cur="${COMP_WORDS[COMP_CWORD]}"
_init_completion || return
if [[ $cur == -* ]]; then if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '--check --color --format --in-place --in --no-color --output --out --standalone --help --version' -- "$cur")) COMPREPLY=($(compgen -W '--check --color --in-place --in --no-color --output --out --standalone --help --version' -- "$cur"))
return return
fi fi
# Generate filenames by default
COMPREPLY=($(compgen -f "$cur" | sort))
} && } &&
complete -F _hurlfmt hurlfmt complete -F _hurlfmt hurlfmt
# ex: filetype=sh # ex: filetype=sh

View File

@ -1,6 +1,5 @@
complete -c hurlfmt -l check -d 'Run in check mode' complete -c hurlfmt -l check -d 'Run in check mode'
complete -c hurlfmt -l color -d 'Colorize Output' complete -c hurlfmt -l color -d 'Colorize Output'
complete -c hurlfmt -l format -d 'Specify output format: hurl, json or html'
complete -c hurlfmt -l in-place -d 'Modify files in place' complete -c hurlfmt -l in-place -d 'Modify files in place'
complete -c hurlfmt -l in -d 'Specify input format: hurl or curl' complete -c hurlfmt -l in -d 'Specify input format: hurl or curl'
complete -c hurlfmt -l no-color -d 'Do not colorize output' complete -c hurlfmt -l no-color -d 'Do not colorize output'

View File

@ -74,7 +74,7 @@ bin/release/create_tarball.sh linux
``` ```
bin/release/install_generic_linux_package.sh bin/release/install_generic_linux_package.sh
export PATH="/tmp/hurl-generic-linux:${PATH}" export PATH="/tmp/hurl-generic-linux:${PATH}"
bin/install_python3_venv.sh bin/activate_python3_venv.sh
export PATH=/tmp/hurl-python3-venv/bin:$PATH export PATH=/tmp/hurl-python3-venv/bin:$PATH
bin/test/test_prerequisites.sh bin/test/test_prerequisites.sh
bin/test/test_integ.sh bin/test/test_integ.sh

View File

@ -1,4 +1,4 @@
FROM --platform=$TARGETPLATFORM alpine:3.17 AS builder FROM alpine:3.22 AS builder
ARG TARGETPLATFORM ARG TARGETPLATFORM
WORKDIR /tmp/hurl-docker WORKDIR /tmp/hurl-docker
COPY . /tmp/hurl-docker COPY . /tmp/hurl-docker
@ -11,7 +11,7 @@ RUN apk add --no-cache bash git && \
bash -c "bin/install_rust.sh" && \ bash -c "bin/install_rust.sh" && \
bash -c "./bin/release/release.sh" bash -c "./bin/release/release.sh"
FROM --platform=$TARGETPLATFORM alpine:3.17 AS runner FROM alpine:3.22 AS runner
ARG docker_build_date ARG docker_build_date
ARG docker_build_tag ARG docker_build_tag
LABEL "org.opencontainers.image.source"="https://github.com/Orange-OpenSource/hurl" LABEL "org.opencontainers.image.source"="https://github.com/Orange-OpenSource/hurl"
@ -27,10 +27,14 @@ LABEL "com.orange.hurl.vendor"="Orange-OpenSource"
LABEL "com.orange.hurl.licenses"="Apache-2.0" LABEL "com.orange.hurl.licenses"="Apache-2.0"
LABEL "com.orange.hurl.title"="Hurl" LABEL "com.orange.hurl.title"="Hurl"
LABEL "com.orange.hurl.description"="Hurl is a command line tool that runs HTTP requests defined in a simple plain text format" LABEL "com.orange.hurl.description"="Hurl is a command line tool that runs HTTP requests defined in a simple plain text format"
LABEL "com.orange.hurl.base.name"="alpine:3.17" LABEL "com.orange.hurl.base.name"="alpine:3.21"
COPY --from=builder /tmp/hurl-docker/target/release/hurl /usr/bin/ COPY --from=builder /tmp/hurl-docker/target/release/hurl /usr/bin/
COPY --from=builder /tmp/hurl-docker/target/release/hurlfmt /usr/bin/ COPY --from=builder /tmp/hurl-docker/target/release/hurlfmt /usr/bin/
COPY --from=builder /usr/lib/libcurl.so.* /usr/lib/ COPY --from=builder /usr/lib/libcurl.so.* /usr/lib/
COPY --from=builder /usr/lib/libcares.so.* /usr/lib/
COPY --from=builder /usr/lib/libpsl.so.* /usr/lib/
COPY --from=builder /usr/lib/libzstd.so.* /usr/lib/
COPY --from=builder /usr/lib/libunistring.so.* /usr/lib/
COPY --from=builder /usr/lib/libnghttp2.so.* /usr/lib/ COPY --from=builder /usr/lib/libnghttp2.so.* /usr/lib/
COPY --from=builder /usr/lib/libbrotli*.so.* /usr/lib/ COPY --from=builder /usr/lib/libbrotli*.so.* /usr/lib/
COPY --from=builder /usr/lib/libxml2.so.* /usr/lib/ COPY --from=builder /usr/lib/libxml2.so.* /usr/lib/

View File

@ -7,10 +7,14 @@
<option name="HEX_PREFIX" value="" /> <option name="HEX_PREFIX" value="" />
<option name="NUM_POSTFIXES" value="" /> <option name="NUM_POSTFIXES" value="" />
</options> </options>
<!-- Most used methods -->
<keywords keywords="GET;HEAD;POST;PUT;DELETE;CONNECT;DELETE;OPTIONS;TRACE;PATCH;LINK;UNLINK;PURGE;LOCK;UNLOCK;PROPFIND;VIEW" ignore_case="false" /> <keywords keywords="GET;HEAD;POST;PUT;DELETE;CONNECT;DELETE;OPTIONS;TRACE;PATCH;LINK;UNLINK;PURGE;LOCK;UNLOCK;PROPFIND;VIEW" ignore_case="false" />
<keywords2 keywords="[Asserts];[BasicAuth];[Captures];[Cookies];[FormParams];[MultipartFormData];[QueryStringParams];[Options]" ignore_case="false" /> <!-- All sections -->
<keywords3 keywords="certificate;status;url;header;cookie;body;xpath;jsonpath;regex;variable;duration;sha256;md5;bytes;HTTP;HTTP/*;HTTP/1.0;HTTP/1.1;HTTP/2" ignore_case="false"/> <keywords2 keywords="[Asserts];[BasicAuth];[Captures];[Cookies];[Form];[FormParams];[Multipart];[MultipartFormData];[Query];[QueryStringParams];[Options]" ignore_case="false" />
<keywords4 keywords="not;&lt;;&lt;=;==;!=;&gt;;&gt;=;startsWith;endsWith;contains;includes;matches;exists;isBoolean;isCollection;isDate;isEmpty;isFloat;isInteger;isIsoDate;isNumber;isString;count;daysAfterNow;daysBeforeNow;decode;format;htmlEscape;htmlUnescape;nth;replace;split;toDate;toInt;urlEncode;urlDecode" ignore_case="false" /> <!-- Queries -->
<keywords3 keywords="body;bytes;certificate;cookie;duration;header;ip;jsonpath;md5;redirects;regex;sha256;status;url;variable;version;xpath;HTTP;HTTP/1.0;HTTP/1.1;HTTP/2" ignore_case="false"/>
<!-- Predicates and filters -->
<keywords4 keywords="not;&lt;;&lt;=;==;!=;&gt;;&gt;=;startsWith;endsWith;contains;includes;matches;exists;isBoolean;isCollection;isDate;isEmpty;isFloat;isInteger;isIsoDate;isNumber;isString;isIpv4;isIpv6;base64Decode;base64Encode;base64UrlSafeDecode;base64UrlSafeEncode;count;daysAfterNow;daysBeforeNow;decode;first;format;htmlEscape;htmlUnescape;jsonpath;last;location;nth;regex;replace;replaceRegex;split;toDate;toFloat;toHex;toInt;toString;urlDecode;urlEncode;urlQueryParam;xpath" ignore_case="false" />
</highlighting> </highlighting>
<extensionMap> <extensionMap>
<mapping ext="hurl" /> <mapping ext="hurl" />

View File

@ -3,10 +3,11 @@
Examples: Examples:
$ python3 contrib/npm/check_archive.py 1.6.1 $ python3 contrib/npm/check_archive.py 1.6.1
""" """
import sys
import json
from pathlib import Path
import hashlib import hashlib
import json
import sys
from pathlib import Path
from urllib import request from urllib import request

View File

@ -11,7 +11,6 @@ versatile, it can be used for <b>fetching data</b> and <b>testing HTTP</b> sessi
```hurl ```hurl
# Get home: # Get home:
GET https://example.net GET https://example.net
HTTP 200 HTTP 200
[Captures] [Captures]
csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)" csrf_token: xpath "string(//meta[@name='_csrf_token']/@content)"
@ -35,7 +34,6 @@ POST https://example.org/api/tests
"id": "4568", "id": "4568",
"evaluate": true "evaluate": true
} }
HTTP 200 HTTP 200
[Asserts] [Asserts]
header "X-Frame-Options" == "SAMEORIGIN" header "X-Frame-Options" == "SAMEORIGIN"
@ -48,7 +46,6 @@ jsonpath "$.id" matches /\d{4}/ # Check the format of the id
```hurl ```hurl
GET https://example.org GET https://example.org
HTTP 200 HTTP 200
[Asserts] [Asserts]
xpath "normalize-space(//head/title)" == "Hello world!" xpath "normalize-space(//head/title)" == "Hello world!"

View File

@ -19,9 +19,7 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const crypto = require("crypto"); const crypto = require("crypto");
const { Readable } = require('stream');
const rimraf = require("rimraf");
const axios = require("axios");
const tar = require("tar"); const tar = require("tar");
const extract = require("extract-zip"); const extract = require("extract-zip");
@ -37,50 +35,53 @@ function install(url, dir, checksum) {
// Install a fresh bin directory. // Install a fresh bin directory.
if (fs.existsSync(dir)) { if (fs.existsSync(dir)) {
rimraf.sync(dir); fs.rmSync(dir, {recursive: true});
}
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
} }
fs.mkdirSync(dir, {recursive: true});
axios({url: url, responseType: "stream" }) fetch(url)
.then(res => { .then(res => {
if (!res.ok) {
console.error(`Error fetching release ${url}: ${res.statusText}`);
process.exit(1);
}
// Check archive extension.
const isWindows = url.endsWith(".zip");
const isUnixLike = url.endsWith(".tar.gz");
if (!isWindows && !isUnixLike) {
console.error("Error: unsupported archive type");
process.exit(1);
}
const archive = isWindows ? "archive.zip" : "archive.tar.gz";
const archivePath = path.join(dir, archive);
const fileStream = fs.createWriteStream(archivePath);
const readable = Readable.fromWeb(res.body);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Linux, macOS archives are tar.gz files. readable.pipe(fileStream)
if (url.endsWith(".tar.gz")) { .on("finish", () => {
const archive = path.join(dir, "archive.tar.gz"); try {
const sink = res.data.pipe(fs.createWriteStream(archive)); verifyCheckSumSync(archivePath, checksum);
sink.on("finish", () => { } catch (e) {
verifyCheckSum(archive, checksum); return reject(e);
tar.x({ strip: 1, C: dir, file: archive }); }
resolve();
}); const extractor = isWindows
sink.on("error", err => reject(err)); ? extract(archivePath, { dir })
} : tar.x({ strip: 1, C: dir, file: archivePath });
// Windows archive is a zip archive.
else if (url.endsWith(".zip")) { extractor.then(resolve).catch(reject);
const archive = path.join(dir, "archive.zip"); })
const sink = res.data.pipe( .on("error", reject);
fs.createWriteStream(archive)
);
sink.on("finish", () => {
verifyCheckSum(archive, checksum);
extract(archive, {dir: dir})
.then( () => resolve())
.catch( err => reject(err));
});
sink.on("error", err => reject(err));
} else {
console.error("Error unsupported archive");
process.exit(1);
}
}); });
}) })
.then(() => { .then(() => {
console.log(`Archive has been installed to ${dir}!`); console.log(`Archive has been installed to ${dir}!`);
}) })
.catch(e => { .catch(e => {
console.error(`Error fetching release: ${e.message}`); console.error(`Installation failed: ${e.message}`);
process.exit(1); process.exit(1);
}); });
} }
@ -90,7 +91,7 @@ function install(url, dir, checksum) {
* @param file input file * @param file input file
* @param expectedChecksum expected checksum * @param expectedChecksum expected checksum
*/ */
function verifyCheckSum(file, expectedChecksum) { function verifyCheckSumSync(file, expectedChecksum) {
const checksum = sha256(file); const checksum = sha256(file);
if (expectedChecksum !== checksum) { if (expectedChecksum !== checksum) {
console.error(`Downloaded archive checksum didn't match the expected checksum (actual: ${checksum}, expected ${expectedChecksum}`); console.error(`Downloaded archive checksum didn't match the expected checksum (actual: ${checksum}, expected ${expectedChecksum}`);
@ -108,4 +109,5 @@ function sha256(file) {
return crypto.createHash("sha256").update(data).digest("hex").toLowerCase(); return crypto.createHash("sha256").update(data).digest("hex").toLowerCase();
} }
exports.install = install;
exports.install = install;

View File

@ -1,4 +1,4 @@
.TH hurl 1 "24 Apr 2024" "hurl 4.3.0" " Hurl Manual" .TH hurl 1 "18 Nov 2025" "hurl 7.1.0" " Hurl Manual"
.SH NAME .SH NAME
hurl - run and test HTTP requests. hurl - run and test HTTP requests.
@ -36,6 +36,7 @@ If no input files are specified, input is read from stdin.
"url": "http://httpbin.org/get" "url": "http://httpbin.org/get"
} }
Hurl can take files as input, or directories. In the latter case, Hurl will search files with `.hurl` extension recursively.
Output goes to stdout by default. To have output go to a file, use the \fI-o, --output\fP option: Output goes to stdout by default. To have output go to a file, use the \fI-o, --output\fP option:
@ -158,6 +159,8 @@ Request a compressed response using one of the algorithms br, gzip, deflate and
Maximum time in seconds that you allow Hurl's connection to take. Maximum time in seconds that you allow Hurl's connection to take.
You can specify time units in the connect timeout expression. Set Hurl to use a connect timeout of 20 seconds with `--connect-timeout 20s` or set it to 35,000 milliseconds with `--connect-timeout 35000ms`. No spaces allowed.
See also \fI-m, --max-time\fP. See also \fI-m, --max-time\fP.
.IP "--connect-to <HOST1:PORT1:HOST2:PORT2> " .IP "--connect-to <HOST1:PORT1:HOST2:PORT2> "
@ -187,16 +190,24 @@ This is a cli-only option.
.IP "-c, --cookie-jar <FILE> " .IP "-c, --cookie-jar <FILE> "
Write cookies to FILE after running the session (only for one session). Write cookies to FILE after running the session.
The file will be written using the Netscape cookie file format. The file will be written using the Netscape cookie file format.
Combined with \fI-b, --cookie\fP, you can simulate a cookie storage between successive Hurl runs. Combined with \fI-b, --cookie\fP, you can simulate a cookie storage between successive Hurl runs.
This is a cli-only option. This is a cli-only option.
.IP "--curl <FILE> "
Export each request to a list of curl commands.
This is a cli-only option.
.IP "--delay <MILLISECONDS> " .IP "--delay <MILLISECONDS> "
Sets delay before each request. Sets delay before each request (aka sleep). The delay is not applied to requests that have been retried because of \fI--retry\fP. See \fI--retry-interval\fP to space retried requests.
You can specify time units in the delay expression. Set Hurl to use a delay of 2 seconds with `--delay 2s` or set it to 500 milliseconds with `--delay 500ms`. Supported time units: ms, s, m, h. No spaces allowed.
.IP "--error-format <FORMAT> " .IP "--error-format <FORMAT> "
@ -226,6 +237,12 @@ However, to avoid your shell accidentally expanding glob patterns before Hurl ha
This is a cli-only option. This is a cli-only option.
.IP "-H, --header <HEADER> "
Add an extra header to include in information sent. Can be used several times in a command
Do not add newlines or carriage returns
.IP "-0, --http1.0 " .IP "-0, --http1.0 "
Tells Hurl to use HTTP version 1.0 instead of using its internally preferred HTTP version. Tells Hurl to use HTTP version 1.0 instead of using its internally preferred HTTP version.
@ -260,14 +277,6 @@ This is a cli-only option.
This option explicitly allows Hurl to perform "insecure" SSL connections and transfers. This option explicitly allows Hurl to perform "insecure" SSL connections and transfers.
.IP "--interactive "
Stop between requests.
This is similar to a break point, You can then continue (Press C) or quit (Press Q).
This is a cli-only option.
.IP "-4, --ipv4 " .IP "-4, --ipv4 "
This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6. This option tells Hurl to use IPv4 addresses only when resolving host names, and not for example try IPv6.
@ -278,7 +287,7 @@ This option tells Hurl to use IPv6 addresses only when resolving host names, and
.IP "--jobs <NUM> " .IP "--jobs <NUM> "
(Experimental) Maximum number of parallel jobs in parallel mode. Default value corresponds (in most cases) to the Maximum number of parallel jobs in parallel mode. Default value corresponds (in most cases) to the
current amount of CPUs. current amount of CPUs.
See also \fI--parallel\fP. See also \fI--parallel\fP.
@ -295,6 +304,11 @@ This is a cli-only option.
Private key file name. Private key file name.
.IP "--limit-rate <SPEED> "
Specify the maximum transfer rate you want Hurl to use, for both downloads and uploads. This feature is useful if you have a limited pipe and you would like your transfer not to use your entire bandwidth. To make it slower than it otherwise would be.
The given speed is measured in bytes/second.
.IP "-L, --location " .IP "-L, --location "
Follow redirect. To limit the amount of redirects to follow use the \fI--max-redirs\fP option Follow redirect. To limit the amount of redirects to follow use the \fI--max-redirs\fP option
@ -306,7 +320,7 @@ This may or may not introduce a security breach if the site redirects you to a s
.IP "--max-filesize <BYTES> " .IP "--max-filesize <BYTES> "
Specify the maximum size (in bytes) of a file to download. If the file requested is larger than this value, the transfer does not start. Specify the maximum size in bytes of a file to download. If the file requested is larger than this value, the transfer does not start.
This is a cli-only option. This is a cli-only option.
@ -320,9 +334,13 @@ By default, the limit is set to 50 redirections. Set this option to -1 to make i
Maximum time in seconds that you allow a request/response to take. This is the standard timeout. Maximum time in seconds that you allow a request/response to take. This is the standard timeout.
You can specify time units in the maximum time expression. Set Hurl to use a maximum time of 20 seconds with `--max-time 20s` or set it to 35,000 milliseconds with `--max-time 35000ms`. No spaces allowed.
See also \fI--connect-timeout\fP. See also \fI--connect-timeout\fP.
This is a cli-only option. .IP "--negotiate "
Tell Hurl to use Negotiate (SPNEGO) authentication.
.IP "-n, --netrc " .IP "-n, --netrc "
@ -354,21 +372,32 @@ Suppress output. By default, Hurl outputs the body of the last response.
This is a cli-only option. This is a cli-only option.
.IP "--no-pretty "
Do not prettify response output for supported content type (JSON only for the moment). By default, output is prettified if
standard output is a terminal.
This is a cli-only option.
.IP "--noproxy <HOST(S)> " .IP "--noproxy <HOST(S)> "
Comma-separated list of hosts which do not use a proxy. Comma-separated list of hosts which do not use a proxy.
Override value from Environment variable no_proxy. Override value from Environment variable no_proxy.
.IP "--ntlm "
Tell Hurl to use NTLM authentication
.IP "-o, --output <FILE> " .IP "-o, --output <FILE> "
Write output to FILE instead of stdout. Write output to FILE instead of stdout. Use '-' for stdout in [Options] sections.
.IP "--parallel " .IP "--parallel "
(Experimental) Run files in parallel. Run files in parallel.
Each Hurl file is executed in its own worker thread, without sharing anything with the other workers. The default run mode is sequential. Each Hurl file is executed in its own worker thread, without sharing anything with the other workers. The default run mode is sequential. Parallel execution is by default in \fI--test\fP mode.
See also \fI--jobs\fP. See also \fI--jobs\fP.
@ -378,10 +407,31 @@ This is a cli-only option.
Tell Hurl to not handle sequences of /../ or /./ in the given URL path. Normally Hurl will squash or merge them according to standards but with this option set you tell it not to do that. Tell Hurl to not handle sequences of /../ or /./ in the given URL path. Normally Hurl will squash or merge them according to standards but with this option set you tell it not to do that.
.IP "--pinnedpubkey <HASHES> "
When negotiating a TLS or SSL connection, the server sends a certificate indicating its identity. A public key is extracted from this certificate and if it does not exactly match the public key provided to this option, Hurl aborts the connection before sending or receiving any data.
.IP "--pretty "
Prettify response output for supported content type (JSON only for the moment). By default, JSON response is prettified if standard output is a terminal, and colorized, see\fI--no-color\fP to format without color.
This is a cli-only option.
.IP "--progress-bar "
Display a progress bar in test mode. The progress bar is displayed only in interactive TTYs. This option forces the progress bar to be displayed even in non-interactive TTYs.
This is a cli-only option.
.IP "-x, --proxy <[PROTOCOL://]HOST[:PORT]> " .IP "-x, --proxy <[PROTOCOL://]HOST[:PORT]> "
Use the specified proxy. Use the specified proxy.
.IP "--repeat <NUM> "
Repeat the input files sequence NUM times, -1 for infinite loop. Given a.hurl, b.hurl, c.hurl as input, repeat two
times will run a.hurl, b.hurl, c.hurl, a.hurl, b.hurl, c.hurl.
.IP "--report-html <DIR> " .IP "--report-html <DIR> "
Generate HTML report in DIR. Generate HTML report in DIR.
@ -390,6 +440,14 @@ If the HTML report already exists, it will be updated with the new test results.
This is a cli-only option. This is a cli-only option.
.IP "--report-json <DIR> "
Generate JSON report in DIR.
If the JSON report already exists, it will be updated with the new test results.
This is a cli-only option.
.IP "--report-junit <FILE> " .IP "--report-junit <FILE> "
Generate JUnit File. Generate JUnit File.
@ -418,6 +476,24 @@ Maximum number of retries, 0 for no retries, -1 for unlimited retries. Retry hap
Duration in milliseconds between each retry. Default is 1000 ms. Duration in milliseconds between each retry. Default is 1000 ms.
You can specify time units in the retry interval expression. Set Hurl to use a retry interval of 2 seconds with `--retry-interval 2s` or set it to 500 milliseconds with `--retry-interval 500ms`. No spaces allowed.
.IP "--secret <NAME=VALUE> "
Define secret value to be redacted from logs and report. When defined, secrets can be used as variable everywhere variables are used.
This is a cli-only option.
.IP "--secrets-file <FILE> "
Define a secrets file in which you define your secrets
Each secret is defined as name=value exactly as with \fI--secret\fP option.
Note that defining a secret twice produces an error.
This is a cli-only option.
.IP "--ssl-no-revoke " .IP "--ssl-no-revoke "
(Windows) This option tells Hurl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for exactly that. (Windows) This option tells Hurl to disable certificate revocation checks. WARNING: this option loosens the SSL security, and by using this flag you ask for exactly that.
@ -428,6 +504,10 @@ This is a cli-only option.
Activate test mode: with this, the HTTP response is not outputted anymore, progress is reported for each Hurl file tested, and a text summary is displayed when all files have been run. Activate test mode: with this, the HTTP response is not outputted anymore, progress is reported for each Hurl file tested, and a text summary is displayed when all files have been run.
In test mode, files are executed in parallel. To run test in a sequential way use `--job 1`.
See also \fI--jobs\fP.
This is a cli-only option. This is a cli-only option.
.IP "--to-entry <ENTRY_NUMBER> " .IP "--to-entry <ENTRY_NUMBER> "
@ -512,9 +592,13 @@ Sets the proxy server to use if no protocol-specific proxy is set.
List of host names that shouldn't go through any proxy. List of host names that shouldn't go through any proxy.
.IP "HURL_name value" .IP "HURL_VARIABLE_name value"
Define variable (name/value) to be used in Hurl templates. This is similar than \fI--variable\fP and \fI--variables-file\fP options. Define variable (name/value) to be used in Hurl templates. This is similar to \fI--variable\fP and \fI--variables-file\fP options.
.IP "HURL_SECRET_name value"
Define secret (name/value) to be used in Hurl templates. This is similar to \fI--secret\fP and \fI--secrets-file\fP options.
.IP "NO_COLOR" .IP "NO_COLOR"

View File

@ -1,4 +1,4 @@
.TH hurl 1 "24 Apr 2024" "hurl 4.3.0" " Hurl Manual" .TH hurl 1 "18 Nov 2025" "hurl 7.1.0" " Hurl Manual"
.SH NAME .SH NAME
hurlfmt - format Hurl files hurlfmt - format Hurl files
@ -60,7 +60,7 @@ hurlfmt can also be used to convert a curl command-line to Hurl
.IP "--check " .IP "--check "
Run in 'check' mode. Exits with 0 if input is formatted correctly, 1 otherwise. Run in check mode. Exits with 0 if input is formatted correctly, 1 otherwise.
This can not be used with \fI--output\fP. This can not be used with \fI--output\fP.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{ {
"name": "@orangeopensource/hurl", "name": "@orangeopensource/hurl",
"version": "4.3.3", "version": "7.1.0",
"hurlBinaryVersion": "4.3.0", "hurlBinaryVersion": "7.1.0",
"description": "Run and Test HTTP Requests with plain text and curl", "description": "Run and Test HTTP Requests with plain text and curl",
"author": "Jean-Christophe Amiel <jeanchristophe.amiel@orange.com>", "author": "Jean-Christophe Amiel <jeanchristophe.amiel@orange.com>",
"contributors": [ "contributors": [
@ -23,10 +23,8 @@
"postinstall": "node ./install.js" "postinstall": "node ./install.js"
}, },
"dependencies": { "dependencies": {
"axios": "1.7.4",
"extract-zip": "2.0.1", "extract-zip": "2.0.1",
"rimraf": "5.0.5", "tar": "7.5.2"
"tar": "7.4.3"
}, },
"devDependencies": {}, "devDependencies": {},
"keywords": [ "keywords": [

View File

@ -5,7 +5,7 @@
"rust_target": "x86_64-pc-windows-msvc", "rust_target": "x86_64-pc-windows-msvc",
"binary_name": "hurl.exe", "binary_name": "hurl.exe",
"archive_extension": ".zip", "archive_extension": ".zip",
"checksum": "1abd2f4d9a107cf1ed21392caf40455035741bb08f44307487e2e57ae91ec059" "checksum": "ce0fcbd889513faafe2c5d52e1051abfd9c78b927089e7a59c364d70d0ae26a7"
}, },
{ {
"type": "Linux", "type": "Linux",
@ -13,7 +13,7 @@
"rust_target": "x86_64-unknown-linux-gnu", "rust_target": "x86_64-unknown-linux-gnu",
"binary_name": "hurl", "binary_name": "hurl",
"archive_extension": ".tar.gz", "archive_extension": ".tar.gz",
"checksum": "77992838d748483924e235d3d04a1d9b33cc32f49a7c6700917e0a20b4451dcb" "checksum": "bed802fea307d330d899935e76614ae1d9bdd1b3139e5cf77cb717033260880c"
}, },
{ {
"type": "Linux", "type": "Linux",
@ -21,7 +21,7 @@
"rust_target": "aarch64-unknown-linux-gnu", "rust_target": "aarch64-unknown-linux-gnu",
"binary_name": "hurl", "binary_name": "hurl",
"archive_extension": ".tar.gz", "archive_extension": ".tar.gz",
"checksum": "d2eede6dfe633cc5a50617de8247efd38bd4d4b8c7a0bf9252d95441f686bda3" "checksum": "4c15c4fbef2aaee94d62e022623415d8148f7455c36adfa1402c645c610529b6"
}, },
{ {
"type": "Darwin", "type": "Darwin",
@ -29,7 +29,7 @@
"rust_target": "x86_64-apple-darwin", "rust_target": "x86_64-apple-darwin",
"binary_name": "hurl", "binary_name": "hurl",
"archive_extension": ".tar.gz", "archive_extension": ".tar.gz",
"checksum": "d2f3a7b751b8906f85203841069239f5a68afe3b6926d1349fc847759a081983" "checksum": "1b3f2b3893f26d186b7ec2726cbe644c3309c9abda73451b2a2e0bc07539eee8"
}, },
{ {
"type": "Darwin", "type": "Darwin",
@ -37,6 +37,6 @@
"rust_target": "aarch64-apple-darwin", "rust_target": "aarch64-apple-darwin",
"binary_name": "hurl", "binary_name": "hurl",
"archive_extension": ".tar.gz", "archive_extension": ".tar.gz",
"checksum": "8e0dacf7ba8c9c0e58feb0f0cff729da24893f782905f5a7a33a8418c5796dbb" "checksum": "bb4103efdffeed83e96e368b7deab8bfcaff5ba7c12a8e02090e968ca9800508"
} }
] ]

View File

@ -1,4 +1,6 @@
## Create the PPA # Build and push to PPA
## Create the PPA for Ubuntu focal and newer
- Go to https://launchpad.net - Go to https://launchpad.net
- Create an account - Create an account
@ -25,152 +27,283 @@ gpg --armor --export-secret-keys "${gpg_keyid}" > /tmp/myprivatekey.asc
# import public and private key # import public and private key
gpg --import /tmp/mypublickey.asc gpg --import /tmp/mypublickey.asc
gpg --import /tmp/myprivatekey.asc gpg --import /tmp/myprivatekey.asc
```
## Choose Hurl version and Ubuntu codename
```
echo -n "hurl_version=" && read -r hurl_version
echo -n "Ubuntu codename=" && read -r codename
echo -n "Gpg passphrase=" && read -r passphrase
``` ```
## Export gpg key ## Export gpg key
``` ```
mkdir -p /tmp/gpg
chmod 777 /tmp/gpg
gpg_keyid=$(gpg --list-keys | grep -E "^ " | tr -d ' ') gpg_keyid=$(gpg --list-keys | grep -E "^ " | tr -d ' ')
gpg --armor --export "${gpg_keyid}" > /tmp/mypublickey.asc gpg --batch --passphrase "${passphrase}" --pinentry-mode loopback --armor --export "${gpg_keyid}" > /tmp/gpg/mypublickey.asc
gpg --armor --export-secret-keys "${gpg_keyid}" > /tmp/myprivatekey.asc gpg --batch --passphrase "${passphrase}" --pinentry-mode loopback --armor --export-secret-keys "${gpg_keyid}" > /tmp/gpg/myprivatekey.asc
```
## Choose Hurl version
``` ```
hurl_version=<hurl tag>
``` ## Run ubuntu container
## Run ubuntu focal container
``` ```
docker run -it --rm --env GPG_KEYID=${gpg_keyid} --env HURL_VERSION=${hurl_version} --volume /tmp:/tmp ubuntu:20.04 bash docker run -it --rm --env gpg_keyid="${gpg_keyid}" --env hurl_version="${hurl_version}" --env codename="${codename}" --env passphrase="${passphrase}" --env date="$(date -u "+%a, %d %b %Y %H:%M:%S")" --volume "/tmp/gpg:/tmp/gpg" ubuntu:"${codename}" bash
``` ```
## Install user prerequisites ## Install user prerequisites and build dependencies
``` ```
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt update apt update
apt install -y \ apt install -y gpg git curl wget vim xz-utils gettext moreutils pv && \
gpg \ apt install -y pkg-config gcc libclang-dev curl libxml2-dev libssl-dev devscripts debhelper
git \
curl \
wget \
vim \
xz-utils
```
## Install build dependencies
```
apt install -y \
pkg-config gcc curl libxml2-dev libssl-dev \
devscripts debhelper
``` ```
## Import GPG key into container ## Import GPG key into container
``` ```
gpg --import /tmp/mypublickey.asc export GPG_TTY=$(tty)
gpg --import /tmp/myprivatekey.asc gpg --batch --passphrase "${passphrase}" --pinentry-mode loopback --import /tmp/gpg/mypublickey.asc
gpg --batch --passphrase "${passphrase}" --pinentry-mode loopback --import /tmp/gpg/myprivatekey.asc
``` ```
## Clone hurl ## Clone Hurl
``` ```
rm -fr /tmp/ppa || true rm -fr /tmp/ppa || true
git clone --depth 1 https://github.com/Orange-OpenSource/hurl.git --branch "${HURL_VERSION}" /tmp/ppa/hurl-"${HURL_VERSION}" git clone --depth 1 https://github.com/Orange-OpenSource/hurl.git --branch "${hurl_version}" /tmp/ppa/hurl-"${hurl_version}"
cd /tmp/ppa/hurl-"${HURL_VERSION}" cd /tmp/ppa/hurl-"${hurl_version}"
cp -r contrib/ppa/debian .
```
## Get debian conf from master
```
git clone --depth 1 https://github.com/Orange-OpenSource/hurl.git /tmp/ppa/hurl-ppa
cp -r ../hurl-ppa/contrib/ppa/debian .
```
## Minimize repo
```
rm -fr .circleci \
.github \
.git \
rustfmt.toml \
ruff.toml \
art \
contrib \
integration \
RELEASING.md \
README.md \
CONTRIBUTING.md
while read -r dir ; do
rm -fr $dir
done < <(find bin -mindepth 1 -type d | grep -v "bin/release")
while read -r file ; do
rm -fr $file
done < <(find bin -type f | grep -Ev "man\.sh|release\.sh|gen_manpage\.py")
while read -r dir ; do
rm -fr $dir
done < <(find docs -mindepth 1 -type d | grep -v "docs/manual")
while read -r file ; do
rm -fr $file
done < <(find docs -type f | grep -Ev "manual/")
```
## Create minimized offline rust and cargo installer (because ppa workers do not have internet)
```
rust_version=$(grep '^rust-version' packages/hurl/Cargo.toml | cut -f2 -d'"')
for arch in x86_64 aarch64 ; do
package="rust-${rust_version}-${arch}-unknown-linux-gnu"
packagelight="${package}-light"
wget "https://static.rust-lang.org/dist/${package}.tar.xz"
xz -T0 -vd "${package}.tar.xz"
tar -x -f "${package}.tar"
dirs_to_delete=$(find "${package}" -type d | cut --delimiter "/" --field 1,2 | grep "/" | grep -Ev "/cargo$|/rust-std-${arch}-unknown-linux-gnu$|/rustc$" | sort -u | tr '\n' ' ')
rm -fr $dirs_to_delete
grep -E "^cargo$|^rust-std-${arch}-unknown-linux-gnu$|^rustc$" "${package}/components" | sponge "${package}/components"
mv "${package}" "${packagelight}"
tar -c -f - "${packagelight}" | pv > "${packagelight}.tar"
xz -T0 -9 -v "${packagelight}.tar"
rm -fr "${package}.tar" "${packagelight}"
done
``` ```
## Install rust and cargo ## Install rust and cargo
``` ```
rust_version=$(grep '^rust-version' packages/hurl/Cargo.toml | cut -f2 -d'"') arch=$(uname -m)
for arch in x86_64 aarch64 ; do package="rust-${rust_version}-${arch}-unknown-linux-gnu"
wget "https://static.rust-lang.org/dist/rust-${rust_version}-${arch}-unknown-linux-gnu.tar.gz" packagelight="${package}-light"
done tar -x -f "${packagelight}".tar.xz
rust_architecture=$(uname -m) ./"${packagelight}"/install.sh --destdir=/tmp/rust --disable-ldconfig
package="rust-${rust_version}-${rust_architecture}-unknown-linux-gnu"
tar xfv "${package}.tar.gz"
./"${package}"/install.sh --destdir=/tmp/rust --disable-ldconfig
export PATH="/tmp/rust/usr/local/bin:$PATH" export PATH="/tmp/rust/usr/local/bin:$PATH"
rustc --version rustc --version
cargo --version cargo --version
rm -fr rust-"${rust_version}"-x86_64-unknown-linux-gnu rm -fr "${packagelight}"
``` ```
## Create vendor.tar.xz (offline cargo deps) ## Create vendor.tar.xz (offline cargo deps)
``` ```
cargo vendor cargo vendor
tar pcfJv vendor.tar.xz vendor tar -p -c -J -f - vendor | pv > vendor.tar.xz
rm -rf vendor rm -rf vendor
``` ```
## Create debian/cargo-checksum.json ## Create debian/cargo-checksum.json
``` ```
cargo package --package hurl cargo package --package hurl
sum=$(sha256sum target/package/hurl-"${HURL_VERSION}".crate | cut -d' ' -f1 | tr -d ' ') sum=$(sha256sum target/package/hurl-"${hurl_version}".crate | cut -d' ' -f1 | tr -d ' ')
echo "{\"package\": \"${sum}\",\"files\": {}}" > debian/cargo-checksum.json echo "{\"package\": \"${sum}\",\"files\": {}}" > debian/cargo-checksum.json
cat debian/cargo-checksum.json
rm -fr target
``` ```
## Create debian/cargo_home/config ## Create debian/cargo_home/config and update .cargo/config
``` ```
mkdir -p debian/cargo_home mkdir -p debian/cargo_home
cp Cargo.toml debian/cargo_home/config cp Cargo.toml debian/cargo_home/config
```
## Create .cargo/config
```
{ {
cat .cargo/config.toml cat .cargo/config.toml
echo echo
cat debian/cargo.config cat debian/cargo.config
} > .cargo/config } > .cargo/config
```
## Create debian/changelog
```
envsubst < debian/changelog.template > debian/changelog
cat debian/changelog
```
## Fix debian/control for Ubuntu <24
```
ubuntu_major_version=$(cat /etc/lsb-release | grep DISTRIB_RELEASE | cut -d'=' -f2 | cut -d'.' -f1)
if [[ $ubuntu_major_version -lt 24 ]] ; then
sed -i "s/pkgconf/pkg-config/g" debian/control
fi
``` ```
## Create deb package source ## Create deb package source
``` ```
debuild -S -sa -k"${GPG_KEYID}" hurl_long_version=$(head -1 debian/changelog | cut -d'(' -f2 | cut -d')' -f1)
cd ..
tar --exclude="hurl-${hurl_version}/debian" -c -z -f - "hurl-${hurl_version}" | pv > "hurl_${hurl_long_version}.orig.tar.gz"
cd "hurl-${hurl_version}"
lintian -i -E --profile debian --display-info --display-experimental --suppress-tags source-is-missing
yes | debuild -S -sa -k"${gpg_keyid}" -p"gpg --batch --passphrase ${passphrase} --pinentry-mode loopback"
```
## Verify deb package source
```
cd .. cd ..
ls -l hurl_* ls -l hurl_*
``` ```
## Push to PPA ## Push to PPA
``` ```
dput ppa:lepapareil/hurl hurl_*_source.changes dput ppa:lepapareil/hurl hurl_*_source.changes
``` ```
## Copy published PPA (focal) to newers ubuntu codenames ## Clean debuild packages
![image](https://github.com/user-attachments/assets/8e7d506a-d266-44eb-8d2f-48431defb890) ```
rm -fr hurl_"${hurl_version}"*
![image](https://github.com/user-attachments/assets/9304a5d9-1422-4320-915f-11b3cf3d1c27) ```
## Install and test Hurl from PPA # Test Hurl from published PPA
## Choose Hurl version and Ubuntu codename
```shell ```shell
codename=<ubuntu codename from focal to latest> echo -n "hurl_version=" && read -r hurl_version
hurl_version=<hurl tag> echo -n "Ubuntu codename=" && read -r codename
docker run -it --rm --env GPG_KEYID=${gpg_keyid} --env HURL_VERSION=${hurl_version} --env CODENAME=${codename} --volume /tmp:/tmp ubuntu:${codename} bash docker run -it --rm --env hurl_version="${hurl_version}" --env codename="${codename}" --volume "/tmp:/tmp" "ubuntu:${codename}" bash
```
## Install Hurl
```
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
apt update yes | unminimize
apt install -y git sudo curl software-properties-common
# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1550DC447B95F03B # apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1550DC447B95F03B
apt-add-repository -y ppa:lepapareil/hurl apt install -y git sudo man-db curl software-properties-common && \
apt install -y hurl apt-add-repository -y ppa:lepapareil/hurl && \
apt list --all-versions hurl && \
apt install -y hurl="${hurl_version}"*
```
## Check Hurl installed version
```
hurl --version hurl --version
hurlfmt --version hurlfmt --version
git clone --depth 1 https://github.com/Orange-OpenSource/hurl.git --branch "${HURL_VERSION}" /tmp/hurl-"${HURL_VERSION}" man hurl | head -1
cd /tmp/hurl-"${HURL_VERSION}" man hurlfmt | head -1
./bin/install_prerequisites_ubuntu.sh ```
./bin/install_python3_venv.sh
./bin/test/test_prerequisites.sh ## Run Hurl from STDIN
./bin/test/test_integ.sh
```
echo -e "GET https://hurl.dev\n\nHTTP 200" | hurl --test --color
```
## Run Hurl from FILE
```
echo -e "GET https://hurl.dev\n\nHTTP 200" > /tmp/test.hurl
hurl --test --color /tmp/test.hurl
```
# Build libxml2
If you want to build another version of libxml2 on ubuntu:
```
minimum_version="2.9.11"
libxml2_installed_version=$(apt list --installed 2>/dev/null | grep libxml2 | cut --delimiter ' ' --field 2 | cut --delimiter '+' --field 1)
if dpkg --compare-versions "${libxml2_installed_version}" ge "${minimum_version}" ; then
echo "ok"
else
tar xf libxml2-"${minimum_version}".tar.gz
cd libxml2-"${minimum_version}"
./configure --prefix=/opt/libxml2-"${minimum_version}" --with-zlib
make -j$(nproc)
make install
export PKG_CONFIG_PATH=/opt/libxml2-"${minimum_version}"/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/libxml2-"${minimum_version}"/lib:$LD_LIBRARY_PATH
export PATH=/opt/libxml2-"${minimum_version}"/bin:$PATH
fi
``` ```

View File

@ -6,14 +6,15 @@ tar pxf vendor.tar.xz
echo "## install rustc and cargo" echo "## install rustc and cargo"
rust_version=$(grep '^rust-version' packages/hurl/Cargo.toml | cut -f2 -d'"') rust_version=$(grep '^rust-version' packages/hurl/Cargo.toml | cut -f2 -d'"')
rust_arch=$(uname -m) arch=$(uname -m)
package="rust-${rust_version}-${rust_arch}-unknown-linux-gnu" package="rust-${rust_version}-${arch}-unknown-linux-gnu"
packagelight="${package}-light"
echo "rust_version=${rust_version}" echo "rust_version=${rust_version}"
echo "rust_architecture=${rust_arch}" echo "architecture=${arch}"
echo "package=${package}" echo "packagelight=${packagelight}"
tar xf "${package}.tar.gz" tar xf "${packagelight}.tar.xz"
mkdir -p /tmp/rust mkdir -p /tmp/rust
./"${package}"/install.sh --verbose --destdir=/tmp/rust --disable-ldconfig ./"${packagelight}"/install.sh --verbose --destdir=/tmp/rust --disable-ldconfig
export PATH="/tmp/rust/usr/local/bin:$PATH" export PATH="/tmp/rust/usr/local/bin:$PATH"
which rustc which rustc
which cargo which cargo

View File

@ -1,5 +0,0 @@
hurl (4.3.5-27ubuntu+focal) focal; urgency=medium
* Initial Release.
-- lepapareil <filipe.pinto@orange.com> Fri, 17 May 2024 13:30:36 +0200

View File

@ -0,0 +1,5 @@
hurl (${hurl_version}+0${codename}) ${codename}; urgency=medium
* New upstream release.
-- lepapareil <filipe.pinto@orange.com> ${date} +0200

View File

@ -2,14 +2,14 @@ Source: hurl
Section: utils Section: utils
Priority: optional Priority: optional
Maintainer: lepapareil <filipe.pinto@orange.com> Maintainer: lepapareil <filipe.pinto@orange.com>
Build-Depends: debhelper (>= 10), pkg-config, gcc, curl, libxml2-dev, libssl-dev, python3 Build-Depends: debhelper (>= 10), pkgconf, gcc, libclang-dev, curl, libxml2-dev, libssl-dev, python3
Standards-Version: 4.6.0 Standards-Version: 4.6.0
Homepage: https://hurl.dev Homepage: https://hurl.dev
Rules-Requires-Root: no Rules-Requires-Root: no
Package: hurl Package: hurl
Architecture: any Architecture: any
Depends: libc6 (>= 2.17), libcurl4, zlib1g, libxml2 Depends: ${misc:Depends}, ${shlibs:Depends}
Description: Hurl is a command line tool that runs HTTP requests defined in a simple plain text format. Description: Hurl is a command line tool that runs HTTP requests defined in a simple plain text format.
It can chain requests, capture values and evaluate queries on headers and body response. Hurl is very versatile: it can be used for both fetching data and testing HTTP sessions. It can chain requests, capture values and evaluate queries on headers and body response. Hurl is very versatile: it can be used for both fetching data and testing HTTP sessions.
Hurl makes it easy to work with HTML content, REST / SOAP / GraphQL APIs, or any other XML / JSON based APIs. Hurl makes it easy to work with HTML content, REST / SOAP / GraphQL APIs, or any other XML / JSON based APIs.

View File

@ -6,205 +6,206 @@ Source: https://github.com/Orange-OpenSource/hurl
Files: * Files: *
Copyright: 2024 Jean Christophe AMIEL, Fabrice REIX, Filipe PINTO Copyright: 2024 Jean Christophe AMIEL, Fabrice REIX, Filipe PINTO
License: Apache-2.0 License: Apache-2.0
.
Apache License Apache License
Version 2.0, January 2004 Version 2.0, January 2004
http://www.apache.org/licenses/ http://www.apache.org/licenses/
.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
.
1. Definitions. 1. Definitions.
.
"License" shall mean the terms and conditions for use, reproduction, "License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document. and distribution as defined by Sections 1 through 9 of this document.
.
"Licensor" shall mean the copyright owner or entity authorized by "Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License. the copyright owner that is granting the License.
.
"Legal Entity" shall mean the union of the acting entity and all "Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition, control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the "control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity. outstanding shares, or (iii) beneficial ownership of such entity.
.
"You" (or "Your") shall mean an individual or Legal Entity "You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License. exercising permissions granted by this License.
.
"Source" form shall mean the preferred form for making modifications, "Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation including but not limited to software source code, documentation
source, and configuration files. source, and configuration files.
.
"Object" form shall mean any form resulting from mechanical "Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation, not limited to compiled object code, generated documentation,
and conversions to other media types. and conversions to other media types.
.
"Work" shall mean the work of authorship, whether in Source or "Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work copyright notice that is included in or attached to the work
(an example is provided in the Appendix below). (an example is provided in the Appendix below).
.
"Derivative Works" shall mean any work, whether in Source or Object "Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of, separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof. the Work and Derivative Works thereof.
.
"Contribution" shall mean any work of authorship, including "Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted" the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution." designated in writing by the copyright owner as "Not a Contribution."
.
"Contributor" shall mean Licensor and any individual or Legal Entity "Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work. subsequently incorporated within the Work.
.
2. Grant of Copyright License. Subject to the terms and conditions of 2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual, this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of, copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form. Work and such Derivative Works in Source or Object form.
.
3. Grant of Patent License. Subject to the terms and conditions of 3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual, this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made, (except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work, use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s) Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate granted to You under this License for that Work shall terminate
as of the date such litigation is filed. as of the date such litigation is filed.
.
4. Redistribution. You may reproduce and distribute copies of the 4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You modifications, and in Source or Object form, provided that You
meet the following conditions: meet the following conditions:
.
(a) You must give any other recipients of the Work or (a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and Derivative Works a copy of this License; and
.
(b) You must cause any modified files to carry prominent notices (b) You must cause any modified files to carry prominent notices
stating that You changed the files; and stating that You changed the files; and
.
(c) You must retain, in the Source form of any Derivative Works (c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work, attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of excluding those notices that do not pertain to any part of
the Derivative Works; and the Derivative Works; and
.
(d) If the Work includes a "NOTICE" text file as part of its (d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or, documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed that such additional attribution notices cannot be construed
as modifying the License. as modifying the License.
.
You may add Your own copyright statement to Your modifications and You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use, for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License. the conditions stated in this License.
.
5. Submission of Contributions. Unless You explicitly state otherwise, 5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions. this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions. with Licensor regarding such Contributions.
.
6. Trademarks. This License does not grant permission to use the trade 6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor, names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file. origin of the Work and reproducing the content of the NOTICE file.
.
7. Disclaimer of Warranty. Unless required by applicable law or 7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS, Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License. risks associated with Your exercise of permissions under this License.
.
8. Limitation of Liability. In no event and under no legal theory, 8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise, whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill, Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages. has been advised of the possibility of such damages.
.
9. Accepting Warranty or Additional Liability. While redistributing 9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer, the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity, and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify, of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability. of your accepting any such warranty or additional liability.
.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
.
APPENDIX: How to apply the Apache License to your work. APPENDIX: How to apply the Apache License to your work.
.
To apply the Apache License to your work, attach the following To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]" boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
.
Copyright 2017 fd developers Copyright 2017 fd developers
.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.

View File

@ -5,6 +5,7 @@
override_dh_clean: override_dh_clean:
./debian/bin/clean.sh ./debian/bin/clean.sh
dh_clean
override_dh_auto_build: override_dh_auto_build:
./debian/bin/prerequisites.sh ./debian/bin/prerequisites.sh

View File

@ -1 +1 @@
3.0 (native) 3.0 (quilt)

Some files were not shown because too many files have changed in this diff Show More