diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..9eea07e --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,33 @@ +name: release-please + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + release-please: + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.release.outputs.release_created }} + steps: + - uses: googleapis/release-please-action@v4 + id: release + with: + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + + npm-publish: + needs: release-please + if: ${{ needs.release-please.outputs.release_created }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + registry-url: 'https://registry.npmjs.org' + - run: npm publish --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/sync-headers.yml b/.github/workflows/sync-headers.yml index 7fc4732..df34857 100644 --- a/.github/workflows/sync-headers.yml +++ b/.github/workflows/sync-headers.yml @@ -39,15 +39,28 @@ jobs: echo "Branch does not exists." echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT echo "COMMIT_MESSAGE=$COMMIT_MESSAGE" >> $GITHUB_OUTPUT + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT fi fi - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 + id: cpr + uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5 if: ${{ steps.check-changes.outputs.BRANCH_NAME }} with: branch: ${{ steps.check-changes.outputs.BRANCH_NAME }} commit-message: ${{ steps.check-changes.outputs.COMMIT_MESSAGE }} title: ${{ steps.check-changes.outputs.COMMIT_MESSAGE }} author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> - body: null + body: Automated sync of headers with Node.js ${{ steps.check-changes.outputs.VERSION }} + labels: headers delete-branch: true + - name: Close existing PRs + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: ${{ steps.cpr.outputs.pull-request-number }} + run: | + gh pr list --json number,author,title,labels --jq '[ .[] | select(.author.login == "app/github-actions" and .number != ${{ steps.cpr.outputs.pull-request-number }} and (.labels[]| select(.name =="headers" )))]' | jq -c '.[]' | + while IFS=$"\n" read -r c; do + pr_number=$(echo "$c" | jq -r '.number') + gh pr close $pr_number --delete-branch --comment "Closing in favor of [#${{ steps.cpr.outputs.pull-request-number }}](${{ steps.cpr.outputs.pull-request-url }})." + done diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..09a2522 --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "1.2.0" +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 438fe9e..4b0a7ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # node-api-headers Changelog +## [1.2.0](https://github.com/nodejs/node-api-headers/compare/node-api-headers-v1.1.0...node-api-headers-v1.2.0) (2024-07-09) + + +### Features + +* update headers from nodejs/node tag v22.1.0 ([d5cfe19](https://github.com/nodejs/node-api-headers/commit/d5cfe19da8b974ca35764dd1c73b91d57cd3c4ce)) + ## 2023-08-05 Version 1.1.0, @NickNaso ### Notable changes diff --git a/CREATING_A_RELEASE.md b/CREATING_A_RELEASE.md index f96aa7f..abc1a37 100644 --- a/CREATING_A_RELEASE.md +++ b/CREATING_A_RELEASE.md @@ -5,7 +5,17 @@ want to be able to do releases ask one of the existing collaborators to add you. If necessary you can ask the build Working Group who manages the Node.js npm user to add you if there are no other active collaborators. -## Prerequisites +Generally, the release is handled by the +[release-please](https://github.com/nodejs/node-api-headers/blob/main/.github/workflows/release-please.yml) +GitHub action. It will bump the version in `package.json` and publish +node-api-headers to npm. + +In cases that the release-please action is not working, please follow the steps +below to publish node-api-headers manually. + +## Publish new release manually + +### Prerequisites Before to start creating a new release check if you have installed the following tools: @@ -15,7 +25,7 @@ tools: If not please follow the instruction reported in the tool's documentation to install it. -## Publish new release +### Steps These are the steps to follow to create a new release: diff --git a/include/js_native_api.h b/include/js_native_api.h index e06bdc8..65584ac 100644 --- a/include/js_native_api.h +++ b/include/js_native_api.h @@ -24,7 +24,7 @@ #ifndef NAPI_EXTERN #ifdef _WIN32 #define NAPI_EXTERN __declspec(dllexport) -#elif defined(__wasm32__) +#elif defined(__wasm__) #define NAPI_EXTERN \ __attribute__((visibility("default"))) \ __attribute__((__import_module__("napi"))) @@ -45,8 +45,8 @@ EXTERN_C_START -NAPI_EXTERN napi_status NAPI_CDECL -napi_get_last_error_info(napi_env env, const napi_extended_error_info** result); +NAPI_EXTERN napi_status NAPI_CDECL napi_get_last_error_info( + node_api_nogc_env env, const napi_extended_error_info** result); // Getters for defined singletons NAPI_EXTERN napi_status NAPI_CDECL napi_get_undefined(napi_env env, @@ -88,6 +88,8 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_string_utf16(napi_env env, const char16_t* str, size_t length, napi_value* result); + + NAPI_EXTERN napi_status NAPI_CDECL napi_create_symbol(napi_env env, napi_value description, napi_value* result); @@ -267,7 +269,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_instanceof(napi_env env, // Gets all callback info in a single call. (Ugly, but faster.) NAPI_EXTERN napi_status NAPI_CDECL napi_get_cb_info( - napi_env env, // [in] NAPI environment handle + napi_env env, // [in] Node-API environment handle napi_callback_info cbinfo, // [in] Opaque callback-info handle size_t* argc, // [in-out] Specifies the size of the provided argv array // and receives the actual count of args. @@ -291,7 +293,7 @@ napi_define_class(napi_env env, NAPI_EXTERN napi_status NAPI_CDECL napi_wrap(napi_env env, napi_value js_object, void* native_object, - napi_finalize finalize_cb, + node_api_nogc_finalize finalize_cb, void* finalize_hint, napi_ref* result); NAPI_EXTERN napi_status NAPI_CDECL napi_unwrap(napi_env env, @@ -303,7 +305,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_remove_wrap(napi_env env, NAPI_EXTERN napi_status NAPI_CDECL napi_create_external(napi_env env, void* data, - napi_finalize finalize_cb, + node_api_nogc_finalize finalize_cb, void* finalize_hint, napi_value* result); NAPI_EXTERN napi_status NAPI_CDECL napi_get_value_external(napi_env env, @@ -402,7 +404,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_arraybuffer(napi_env env, void* external_data, size_t byte_length, - napi_finalize finalize_cb, + node_api_nogc_finalize finalize_cb, void* finalize_hint, napi_value* result); #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED @@ -444,7 +446,7 @@ napi_get_dataview_info(napi_env env, size_t* byte_offset); // version management -NAPI_EXTERN napi_status NAPI_CDECL napi_get_version(napi_env env, +NAPI_EXTERN napi_status NAPI_CDECL napi_get_version(node_api_nogc_env env, uint32_t* result); // Promises @@ -468,7 +470,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_run_script(napi_env env, // Memory management NAPI_EXTERN napi_status NAPI_CDECL napi_adjust_external_memory( - napi_env env, int64_t change_in_bytes, int64_t* adjusted_value); + node_api_nogc_env env, int64_t change_in_bytes, int64_t* adjusted_value); #if NAPI_VERSION >= 5 @@ -486,15 +488,17 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_get_date_value(napi_env env, double* result); // Add finalizer for pointer -NAPI_EXTERN napi_status NAPI_CDECL napi_add_finalizer(napi_env env, - napi_value js_object, - void* finalize_data, - napi_finalize finalize_cb, - void* finalize_hint, - napi_ref* result); +NAPI_EXTERN napi_status NAPI_CDECL +napi_add_finalizer(napi_env env, + napi_value js_object, + void* finalize_data, + node_api_nogc_finalize finalize_cb, + void* finalize_hint, + napi_ref* result); #endif // NAPI_VERSION >= 5 + #if NAPI_VERSION >= 6 // BigInt @@ -532,10 +536,13 @@ napi_get_all_property_names(napi_env env, napi_value* result); // Instance data -NAPI_EXTERN napi_status NAPI_CDECL napi_set_instance_data( - napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint); +NAPI_EXTERN napi_status NAPI_CDECL +napi_set_instance_data(node_api_nogc_env env, + void* data, + napi_finalize finalize_cb, + void* finalize_hint); -NAPI_EXTERN napi_status NAPI_CDECL napi_get_instance_data(napi_env env, +NAPI_EXTERN napi_status NAPI_CDECL napi_get_instance_data(node_api_nogc_env env, void** data); #endif // NAPI_VERSION >= 6 diff --git a/include/js_native_api_types.h b/include/js_native_api_types.h index 005382f..7cb5b08 100644 --- a/include/js_native_api_types.h +++ b/include/js_native_api_types.h @@ -22,6 +22,35 @@ typedef uint16_t char16_t; // JSVM API types are all opaque pointers for ABI stability // typedef undefined structs instead of void* for compile time type safety typedef struct napi_env__* napi_env; + +// We need to mark APIs which can be called during garbage collection (GC), +// meaning that they do not affect the state of the JS engine, and can +// therefore be called synchronously from a finalizer that itself runs +// synchronously during GC. Such APIs can receive either a `napi_env` or a +// `node_api_nogc_env` as their first parameter, because we should be able to +// also call them during normal, non-garbage-collecting operations, whereas +// APIs that affect the state of the JS engine can only receive a `napi_env` as +// their first parameter, because we must not call them during GC. In lieu of +// inheritance, we use the properties of the const qualifier to accomplish +// this, because both a const and a non-const value can be passed to an API +// expecting a const value, but only a non-const value can be passed to an API +// expecting a non-const value. +// +// In conjunction with appropriate CFLAGS to warn us if we're passing a const +// (nogc) environment into an API that expects a non-const environment, and the +// definition of nogc finalizer function pointer types below, which receive a +// nogc environment as their first parameter, and can thus only call nogc APIs +// (unless the user explicitly casts the environment), we achieve the ability +// to ensure at compile time that we do not call APIs that affect the state of +// the JS engine from a synchronous (nogc) finalizer. +#if !defined(NAPI_EXPERIMENTAL) || \ + (defined(NAPI_EXPERIMENTAL) && \ + defined(NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT)) +typedef struct napi_env__* node_api_nogc_env; +#else +typedef const struct napi_env__* node_api_nogc_env; +#endif + typedef struct napi_value__* napi_value; typedef struct napi_ref__* napi_ref; typedef struct napi_handle_scope__* napi_handle_scope; @@ -116,6 +145,16 @@ typedef void(NAPI_CDECL* napi_finalize)(napi_env env, void* finalize_data, void* finalize_hint); +#if !defined(NAPI_EXPERIMENTAL) || \ + (defined(NAPI_EXPERIMENTAL) && \ + defined(NODE_API_EXPERIMENTAL_NOGC_ENV_OPT_OUT)) +typedef napi_finalize node_api_nogc_finalize; +#else +typedef void(NAPI_CDECL* node_api_nogc_finalize)(node_api_nogc_env env, + void* finalize_data, + void* finalize_hint); +#endif + typedef struct { // One of utf8name or name should be NULL. const char* utf8name; diff --git a/include/node_api.h b/include/node_api.h index 0345468..e94ee48 100644 --- a/include/node_api.h +++ b/include/node_api.h @@ -1,11 +1,11 @@ #ifndef SRC_NODE_API_H_ #define SRC_NODE_API_H_ -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) && !defined(NAPI_EXTERN) #ifdef _WIN32 // Building native addon against node #define NAPI_EXTERN __declspec(dllimport) -#elif defined(__wasm32__) +#elif defined(__wasm__) #define NAPI_EXTERN __attribute__((__import_module__("napi"))) #endif #endif @@ -17,8 +17,13 @@ struct uv_loop_s; // Forward declaration. #ifdef _WIN32 #define NAPI_MODULE_EXPORT __declspec(dllexport) #else +#ifdef __EMSCRIPTEN__ +#define NAPI_MODULE_EXPORT \ + __attribute__((visibility("default"))) __attribute__((used)) +#else #define NAPI_MODULE_EXPORT __attribute__((visibility("default"))) #endif +#endif #if defined(__GNUC__) #define NAPI_NO_RETURN __attribute__((noreturn)) @@ -30,7 +35,7 @@ struct uv_loop_s; // Forward declaration. typedef napi_value(NAPI_CDECL* napi_addon_register_func)(napi_env env, napi_value exports); -typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(); +typedef int32_t(NAPI_CDECL* node_api_addon_get_api_version_func)(void); // Used by deprecated registration method napi_module_register. typedef struct napi_module { @@ -49,7 +54,7 @@ typedef struct napi_module { NAPI_MODULE_INITIALIZER_X_HELPER(base, version) #define NAPI_MODULE_INITIALIZER_X_HELPER(base, version) base##version -#ifdef __wasm32__ +#ifdef __wasm__ #define NAPI_MODULE_INITIALIZER_BASE napi_register_wasm_v #else #define NAPI_MODULE_INITIALIZER_BASE napi_register_module_v @@ -66,7 +71,7 @@ typedef struct napi_module { #define NAPI_MODULE_INIT() \ EXTERN_C_START \ - NAPI_MODULE_EXPORT int32_t NODE_API_MODULE_GET_API_VERSION() { \ + NAPI_MODULE_EXPORT int32_t NODE_API_MODULE_GET_API_VERSION(void) { \ return NAPI_VERSION; \ } \ NAPI_MODULE_EXPORT napi_value NAPI_MODULE_INITIALIZER(napi_env env, \ @@ -126,7 +131,7 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_create_external_buffer(napi_env env, size_t length, void* data, - napi_finalize finalize_cb, + node_api_nogc_finalize finalize_cb, void* finalize_hint, napi_value* result); #endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED @@ -143,7 +148,6 @@ NAPI_EXTERN napi_status NAPI_CDECL napi_get_buffer_info(napi_env env, void** data, size_t* length); -#ifndef __wasm32__ // Methods to manage simple async operations NAPI_EXTERN napi_status NAPI_CDECL napi_create_async_work(napi_env env, @@ -155,21 +159,20 @@ napi_create_async_work(napi_env env, napi_async_work* result); NAPI_EXTERN napi_status NAPI_CDECL napi_delete_async_work(napi_env env, napi_async_work work); -NAPI_EXTERN napi_status NAPI_CDECL napi_queue_async_work(napi_env env, +NAPI_EXTERN napi_status NAPI_CDECL napi_queue_async_work(node_api_nogc_env env, napi_async_work work); -NAPI_EXTERN napi_status NAPI_CDECL napi_cancel_async_work(napi_env env, +NAPI_EXTERN napi_status NAPI_CDECL napi_cancel_async_work(node_api_nogc_env env, napi_async_work work); -#endif // __wasm32__ // version management NAPI_EXTERN napi_status NAPI_CDECL -napi_get_node_version(napi_env env, const napi_node_version** version); +napi_get_node_version(node_api_nogc_env env, const napi_node_version** version); #if NAPI_VERSION >= 2 // Return the current libuv event loop for a given environment NAPI_EXTERN napi_status NAPI_CDECL -napi_get_uv_event_loop(napi_env env, struct uv_loop_s** loop); +napi_get_uv_event_loop(node_api_nogc_env env, struct uv_loop_s** loop); #endif // NAPI_VERSION >= 2 @@ -178,11 +181,11 @@ napi_get_uv_event_loop(napi_env env, struct uv_loop_s** loop); NAPI_EXTERN napi_status NAPI_CDECL napi_fatal_exception(napi_env env, napi_value err); -NAPI_EXTERN napi_status NAPI_CDECL -napi_add_env_cleanup_hook(napi_env env, napi_cleanup_hook fun, void* arg); +NAPI_EXTERN napi_status NAPI_CDECL napi_add_env_cleanup_hook( + node_api_nogc_env env, napi_cleanup_hook fun, void* arg); -NAPI_EXTERN napi_status NAPI_CDECL -napi_remove_env_cleanup_hook(napi_env env, napi_cleanup_hook fun, void* arg); +NAPI_EXTERN napi_status NAPI_CDECL napi_remove_env_cleanup_hook( + node_api_nogc_env env, napi_cleanup_hook fun, void* arg); NAPI_EXTERN napi_status NAPI_CDECL napi_open_callback_scope(napi_env env, @@ -197,7 +200,6 @@ napi_close_callback_scope(napi_env env, napi_callback_scope scope); #if NAPI_VERSION >= 4 -#ifndef __wasm32__ // Calling into JS from other threads NAPI_EXTERN napi_status NAPI_CDECL napi_create_threadsafe_function(napi_env env, @@ -226,19 +228,18 @@ napi_acquire_threadsafe_function(napi_threadsafe_function func); NAPI_EXTERN napi_status NAPI_CDECL napi_release_threadsafe_function( napi_threadsafe_function func, napi_threadsafe_function_release_mode mode); -NAPI_EXTERN napi_status NAPI_CDECL -napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func); +NAPI_EXTERN napi_status NAPI_CDECL napi_unref_threadsafe_function( + node_api_nogc_env env, napi_threadsafe_function func); -NAPI_EXTERN napi_status NAPI_CDECL -napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func); -#endif // __wasm32__ +NAPI_EXTERN napi_status NAPI_CDECL napi_ref_threadsafe_function( + node_api_nogc_env env, napi_threadsafe_function func); #endif // NAPI_VERSION >= 4 #if NAPI_VERSION >= 8 NAPI_EXTERN napi_status NAPI_CDECL -napi_add_async_cleanup_hook(napi_env env, +napi_add_async_cleanup_hook(node_api_nogc_env env, napi_async_cleanup_hook hook, void* arg, napi_async_cleanup_hook_handle* remove_handle); @@ -251,7 +252,7 @@ napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle); #if NAPI_VERSION >= 9 NAPI_EXTERN napi_status NAPI_CDECL -node_api_get_module_file_name(napi_env env, const char** result); +node_api_get_module_file_name(node_api_nogc_env env, const char** result); #endif // NAPI_VERSION >= 9 diff --git a/package.json b/package.json index fa44e84..117fc3e 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,7 @@ "directories": {}, "gypfile": false, "homepage": "https://github.com/nodejs/node-api-headers", - "keywords": [ - ], + "keywords": [], "license": "MIT", "main": "index.js", "name": "node-api-headers", @@ -54,6 +53,6 @@ "write-symbols": "node --no-warnings scripts/write-symbols.js", "write-win32-def": "node --no-warnings scripts/write-win32-def.js" }, - "version": "1.1.0", + "version": "1.2.0", "support": true } diff --git a/release-please-config.json b/release-please-config.json new file mode 100644 index 0000000..a67f6a4 --- /dev/null +++ b/release-please-config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "pull-request-title-pattern": "chore: release v${version}", + "bootstrap-sha": "186e04b5e40e54d7fd1655bc67081cc483f12488", + "packages": { + ".": { + "changelog-path": "CHANGELOG.md" + } + } +} diff --git a/scripts/update-headers.js b/scripts/update-headers.js index 03e7c1f..fc9b406 100644 --- a/scripts/update-headers.js +++ b/scripts/update-headers.js @@ -160,7 +160,7 @@ async function main() { }, }); - console.log(`Update headers from nodejs/node tag ${tag}`); + console.log(`feat: update headers from nodejs/node tag ${tag}`); const files = ['js_native_api_types.h', 'js_native_api.h', 'node_api_types.h', 'node_api.h'];