diff --git a/.github/workflows/create-meeting-artifacts-manual.yml b/.github/workflows/create-meeting-artifacts-manual.yml deleted file mode 100644 index d819e7a..0000000 --- a/.github/workflows/create-meeting-artifacts-manual.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Create Meeting Artifacts (Manual) - -on: - workflow_dispatch: - inputs: - meeting_group: - description: 'Meeting group to create artifacts for' - required: true - type: choice - options: - - benchmarking - - build - - cross_project_council - - diag - - diag_deepdive - - ecosystem_report - - loaders - - modules - - next-10 - - outreach - - package-maintenance - - package_metadata_interop - - Release - - security-wg - - security_collab - - standards - - sustainability_collab - - tsc - - tooling - - typescript - - uvwasi - - userfeedback - - web-server-frameworks - -jobs: - create-artifacts: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 - with: - node-version-file: '.nvmrc' - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Read Meeting Variables - id: read-vars - run: | - meeting_group="${{ github.event.inputs.meeting_group }}" - user=$(grep '^USER=' "templates/meeting_base_${meeting_group}" | cut -d'=' -f2 | xargs) - echo "user=$user" >> $GITHUB_OUTPUT - - - name: Create GitHub App Token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 - id: app-token - with: - app-id: ${{ secrets.BOT_ID }} - private-key: ${{ secrets.BOT_PRIVATE_KEY }} - owner: ${{ steps.read-vars.outputs.user }} - - - name: Create meeting artifacts - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - HACKMD_API_TOKEN: ${{ secrets.HACKMD_API_TOKEN }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - run: node create-node-meeting-artifacts.mjs ${{ github.event.inputs.meeting_group }} - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 - with: - name: meeting-artifacts-${{ github.event.inputs.meeting_group || 'tsc' }} - path: | - ~/.make-node-meeting/ - *.md - retention-days: 7 - if-no-files-found: ignore diff --git a/.github/workflows/create-meeting-artifacts-scheduled.yml b/.github/workflows/create-meeting-artifacts-scheduled.yml deleted file mode 100644 index 2cc8a0b..0000000 --- a/.github/workflows/create-meeting-artifacts-scheduled.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: Create Meeting Artifacts (Scheduled) - -on: - workflow_dispatch: - schedule: - - cron: '0 10 * * 1' - -jobs: - create-artifacts: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - meeting_group: - - benchmarking - - build - - cross_project_council - - diag - - diag_deepdive - - ecosystem_report - - loaders - - modules - - next-10 - - outreach - - package-maintenance - - package_metadata_interop - - Release - - security-wg - - security_collab - - standards - - sustainability_collab - - tsc - - tooling - - typescript - - uvwasi - - userfeedback - - web-server-frameworks - steps: - - name: Checkout repository - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: Setup Node.js - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 - with: - node-version-file: '.nvmrc' - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Read Meeting Variables - id: read-vars - run: | - meeting_group="${{ matrix.meeting_group }}" - user=$(grep '^USER=' "templates/meeting_base_${meeting_group}" | cut -d'=' -f2 | xargs) - echo "user=$user" >> $GITHUB_OUTPUT - - - name: Create GitHub App Token - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 - id: app-token - with: - app-id: ${{ secrets.BOT_ID }} - private-key: ${{ secrets.BOT_PRIVATE_KEY }} - owner: ${{ steps.read-vars.outputs.user }} - - - name: Create meeting artifacts - env: - GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} - HACKMD_API_TOKEN: ${{ secrets.HACKMD_API_TOKEN }} - GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} - run: node create-node-meeting-artifacts.mjs ${{ matrix.meeting_group }} - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 - with: - name: meeting-artifacts-${{ matrix.meeting_group }} - path: | - ~/.make-node-meeting/ - *.md - retention-days: 7 - if-no-files-found: ignore diff --git a/.github/workflows/create-meeting-artifacts.yml b/.github/workflows/create-meeting-artifacts.yml new file mode 100644 index 0000000..992a66b --- /dev/null +++ b/.github/workflows/create-meeting-artifacts.yml @@ -0,0 +1,63 @@ +name: Create Meeting Artifacts + +on: + workflow_dispatch: + inputs: + meeting_group: + description: 'Meeting group to create artifacts for' + required: true + type: string + dry_run: + type: boolean + description: 'Dry run?' + default: false + required: true + workflow_call: + inputs: + meeting_group: + description: 'Meeting group to create artifacts for' + required: true + type: string + dry_run: + type: boolean + description: 'Dry run?' + default: false + required: true + +env: + GROUP: ${{ github.event.inputs.meeting_group }} + +jobs: + create-artifacts: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Setup Node.js + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Read Meeting Variables + id: read-vars + run: echo "user=$(jq -r '.github.owner' "configs/$GROUP.json")" >> $GITHUB_OUTPUT + + - name: Create GitHub App Token + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 + id: app-token + with: + app-id: ${{ secrets.BOT_ID }} + private-key: ${{ secrets.BOT_PRIVATE_KEY }} + owner: ${{ steps.read-vars.outputs.user }} + + - name: Create meeting artifacts + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + HACKMD_API_TOKEN: ${{ secrets.HACKMD_API_TOKEN }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + run: npx . $GROUP ${{ github.event.inputs.dry_run && '--dry-run' }} diff --git a/.github/workflows/scheduled-create-meeting-artifacts.yml b/.github/workflows/scheduled-create-meeting-artifacts.yml new file mode 100644 index 0000000..0611595 --- /dev/null +++ b/.github/workflows/scheduled-create-meeting-artifacts.yml @@ -0,0 +1,38 @@ +name: Create Meeting Artifacts (Scheduled) + +on: + workflow_dispatch: + inputs: + dry_run: + type: boolean + description: 'Dry run?' + default: false + required: true + schedule: + - cron: '0 10 * * 1' + +jobs: + create-matrix: + runs-on: ubuntu-latest + outputs: + groups: ${{ steps.set-matrix.outputs.configs }} + steps: + - name: Checkout repository + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Get config basenames + id: set-matrix + run: | + CONFIGS=$(find configs/ -maxdepth 1 -type f -name '*.json' -exec basename {} .json \; | jq -R -s -c 'split("\n")[:-1]') + echo "configs=$CONFIGS" >> $GITHUB_OUTPUT + + create-artifacts: + needs: create-matrix + strategy: + fail-fast: false + matrix: + groups: ${{ fromJson(needs.create-matrix.outputs.groups) }} + uses: ./.github/workflows/create-meeting-artifacts.yml + with: + meeting_group: ${{ matrix.groups }} + dry_run: ${{ github.event.inputs.dry_run }} diff --git a/.prettierignore b/.prettierignore index 0350652..bd6e3ee 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1 @@ -templates/ +template.mustache \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 2886933..dfd3827 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,3 @@ Michael Dawson Claudio Wunder +Aviv Keller \ No newline at end of file diff --git a/README.md b/README.md index c9ae205..a0884b2 100644 --- a/README.md +++ b/README.md @@ -39,31 +39,6 @@ A modern Node.js application that creates GitHub issues and HackMD documents for **Note:** API Keys provide simplified authentication and are sufficient for read-only calendar access. They don't require complex OAuth flows or service account setup. -## 🎯 Available Meeting Commands - -| Meeting Group | Production Command | Development Command | -| ------------------------ | ------------------------------------------ | ---------------------------------------------- | -| UVWASI | `npm run uvwasi-meeting` | `npm run uvwasi-meeting:dev` | -| TSC | `npm run tsc-meeting` | `npm run tsc-meeting:dev` | -| Build | `npm run build-meeting` | `npm run build-meeting:dev` | -| Diagnostics | `npm run diag-meeting` | `npm run diag-meeting:dev` | -| Diagnostics Deep Dive | `npm run diag-deepdive-meeting` | `npm run diag-deepdive-meeting:dev` | -| TypeScript | `npm run typescript-meeting` | `npm run typescript-meeting:dev` | -| Release | `npm run release-meeting` | `npm run release-meeting:dev` | -| Cross Project Council | `npm run cross-project-council-meeting` | `npm run cross-project-council-meeting:dev` | -| Modules | `npm run modules-meeting` | `npm run modules-meeting:dev` | -| Tooling | `npm run tooling-meeting` | `npm run tooling-meeting:dev` | -| Security WG | `npm run security-wg-meeting` | `npm run security-wg-meeting:dev` | -| Next-10 | `npm run next-10-meeting` | `npm run next-10-meeting:dev` | -| Package Maintenance | `npm run package-maintenance-meeting` | `npm run package-maintenance-meeting:dev` | -| Package Metadata Interop | `npm run package-metadata-interop-meeting` | `npm run package-metadata-interop-meeting:dev` | -| Ecosystem Report | `npm run ecosystem-report-meeting` | `npm run ecosystem-report-meeting:dev` | -| Sustainability Collab | `npm run sustainability-collab-meeting` | `npm run sustainability-collab-meeting:dev` | -| Standards | `npm run standards-meeting` | `npm run standards-meeting:dev` | -| Security Collab | `npm run security-collab-meeting` | `npm run security-collab-meeting:dev` | -| Loaders | `npm run loaders-meeting` | `npm run loaders-meeting:dev` | -| Web Server Frameworks | `npm run web-server-frameworks-meeting` | `npm run web-server-frameworks-meeting:dev` | - ## πŸ“ Project Structure ``` @@ -74,112 +49,46 @@ create-node-meeting-artifacts/ β”‚ β”œβ”€β”€ github.mjs # GitHub API integration β”‚ β”œβ”€β”€ google.mjs # Google APIs integration β”‚ β”œβ”€β”€ meeting.mjs # Meeting operations +| β”œβ”€β”€ index.mjs # Main application β”‚ └── utils.mjs # Utility functions β”œβ”€β”€ templates/ # Meeting templates β”œβ”€β”€ .nvmrc # Node.js version -β”œβ”€β”€ .env.example # Environment variables example -β”œβ”€β”€ create-node-meeting-artifacts.mjs # Main application -β”œβ”€β”€ TEMPLATES_DOCUMENTATION.md # Template creation guide +β”œβ”€β”€ .env.example # Environment variables example └── README.md # This file ``` -## πŸ“ Meeting Templates - -Meeting configurations are stored in the `templates/` directory. Each meeting group requires four template files: - -- `invited_`: List of invited attendees (GitHub team mentions) -- `observers_`: List of observers with their details -- `meeting_base_`: Base meeting configuration (calendar ID, GitHub repo, etc.) -- `minutes_base_`: Template for meeting minutes document - -For detailed information about creating new templates, see [TEMPLATES_DOCUMENTATION.md](./TEMPLATES_DOCUMENTATION.md). - -### Template Variables - -Templates support the following replacement variables: - -- `$TITLE$`: Meeting title -- `$AGENDA_CONTENT$`: Auto-generated agenda items -- `$INVITED$`: Invited attendees list -- `$OBSERVERS$`: Observers list -- `$GITHUB_ISSUE$`: GitHub issue URL -- `$MINUTES_DOC$`: Google Doc URL - ## βž• Adding New Meeting Groups -To add a new meeting group to the system, you need to create templates and update configuration in three places: - -### 1. Create Template Files - -Create four template files in the `templates/` directory following the naming convention: - -```bash -# Replace with your meeting group identifier -templates/invited_ -templates/observers_ -templates/meeting_base_ -templates/minutes_base_ -``` - -See [TEMPLATES_DOCUMENTATION.md](./TEMPLATES_DOCUMENTATION.md) for detailed template examples and variable explanations. - -### 2. Update GitHub Actions Workflows - -Add your meeting group to both workflow files: - -- `.github/workflows/create-meeting-artifacts-manual.yml` -- `.github/workflows/create-meeting-artifacts-scheduled.yml` - -For manual workflow, add your group to the `options` list under `workflow_dispatch.inputs.meeting_group`: - -```yaml -workflow_dispatch: - inputs: - meeting_group: - description: 'Meeting group to create artifacts for' - required: true - type: choice - options: - - uvwasi - - tsc - - build - # ... existing groups ... - - your-new-group # Add your group here -``` - -For scheduled workflow, add your group to the `matrix.meeting_group` list: - -```yaml -strategy: - matrix: - meeting_group: - - uvwasi - - tsc - - build - # ... existing groups ... - - your-new-group # Add your group here -``` - -### 3. Update Package.json Scripts - -Add npm scripts to `package.json` following this pattern: +To add a new meeting group to the system, you need to create a configuration file in `configs`. These configuration files should +follow the following design: ```json { - "scripts": { - "your-meeting-group-meeting": "node create-node-meeting-artifacts.mjs your_meeting_group", - "your-meeting-group-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs your_meeting_group" + "github": { + "owner": "Organization (i.e. nodejs, openjs-foundation)", + "repo": "Repository (i.e. build)", + "agendaTag?": "If the label isn't [filename]-agenda, put it here" + }, + "meeting": { + "displayName": "Who is meeting?", + "labels?": ["If the meeting issue should be labeled, what?"], + "calendar": { + "id": "This is the Google Calendar ID, without the \"@...\" part.", + "filter": "What's the meeting called?" + }, + "links": { + "participant": "Where do I go to participate?", + "observer": "Where do I go to watch?" + }, + "invitees": ["Who is invited?"], + "observers?": ["Who is watching?"] + }, + "hackmd": { + "team": "Where in HackMD should the notes be generated?" } } ``` -**Important Notes:** - -- Use **kebab-case** for script names: `your-meeting-group-meeting` -- Use **snake_case** for the actual group parameter: `your_meeting_group` -- Always create both production and development (`:dev`) versions -- The development version uses `--env-file=.env` for local testing - ## πŸ—οΈ Development ### Environment Setup @@ -187,7 +96,7 @@ Add npm scripts to `package.json` following this pattern: 1. Clone the repository 2. Install dependencies: `npm install` 3. Copy `.env.example` to `.env` and configure your credentials -4. Create meeting artifacts: `npm run -meeting:dev` +4. Create meeting artifacts: `npm run dev ` ### Code Quality @@ -204,11 +113,11 @@ npm run check # Run both linting and formatting checks ### Local Development ```bash -# Using npm scripts (recommended) -npm run tsc-meeting:dev +# Using npm scripts +npm run dev tsc # Direct execution -node --env-file=.env create-node-meeting-artifacts.mjs tsc +npx . tsc ``` ## πŸ“‚ Output @@ -228,19 +137,3 @@ The application creates: - `GITHUB_TOKEN`: GitHub Personal Access Token - `HACKMD_API_TOKEN`: HackMD API token for creating and managing documents - `GOOGLE_API_KEY`: Google Calendar API Key for read-only calendar access - -### Meeting Base Configuration - -Each `meeting_base_` file contains: - -```bash -CALENDAR_FILTER="Meeting Name in Calendar" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" -USER="nodejs" -REPO="repository-name" -GROUP_NAME="Full Group Name" -AGENDA_TAG="agenda-label" -ISSUE_LABEL="optional-issue-label" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS="Meeting join instructions" -``` diff --git a/TEMPLATES_DOCUMENTATION.md b/TEMPLATES_DOCUMENTATION.md deleted file mode 100644 index 279950f..0000000 --- a/TEMPLATES_DOCUMENTATION.md +++ /dev/null @@ -1,193 +0,0 @@ -This document contains empty versions of each template needed to successfully create meeting artifacts for a Committee, Working Group, Initiative, or Team. These documents need to go in the [/templates](./templates) directory in this repository. - -## Template Variables - -There are several variables in the documents that need to be configured: - -- **``:** The name of the Committee, Working Group, Initiative, or Team that meeting artifacts are being created for. -- **``:** The abbreviated or shortened name for a group, used in each filename to connect associated files together. -- **``:** The name of the GitHub team in the Node.js org. -- **``:** The name of calendar events that mark the group's meeting date/time. -- **``:** The repository of the group. -- **``:** The label for which to search the Node.js GitHub organization, to add items to the group's agenda. -- **``:** an optional label for the created issue itself. -- **``:** Name of an observer in a group's meetings. - -## Meeting Properties Reference - -The following properties are available in meeting base templates and can be used in meeting issue generation: - -- **`CALENDAR_FILTER`:** The name of calendar events that mark the group's meeting date/time -- **`CALENDAR_ID`:** The Google Calendar ID for the Node.js calendar (typically `nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com`) -- **`USER`:** The GitHub username/organization (typically `nodejs`) -- **`REPO`:** The repository name where meeting issues are created -- **`GROUP_NAME`:** The full name of the Committee, Working Group, Initiative, or Team -- **`AGENDA_TAG`:** The label used to search for agenda items in GitHub issues and PRs -- **`HOST`:** Meeting host information -- **`JOINING_INSTRUCTIONS`:** Instructions for joining the meeting (Zoom links, YouTube streams, etc.) -- **`ISSUE_LABEL`:** Optional label to apply to the created meeting issue - -These properties are defined in the `meeting_base_` template files and are substituted when generating meeting issues. - -# Invited - -The [GitHub Team](https://help.github.com/articles/about-teams/) to invite. The @mention should be a GitHub Team whose members are all invidiuals who are always invited. - -**File:** `invited_` - -``` -* Members: @nodejs/ -``` - -## Invited Example - -**File:** `invited_commcomm` - -``` -* CommComm Members: @nodejs/community-committee -``` - -# Meeting Base - -A base of metadata and some content for the issue to be created on time, with agenda items automatically created. - -**File:** `meeting_base_` - -``` -CALENDAR_FILTER="" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" -USER="nodejs" -REPO="" -GROUP_NAME="" -AGENDA_TAG= -JOINING_INSTRUCTIONS=" - -* link for participants: Will be added a few minutes before meeting starts -* For those who just want to watch: https://www.youtube.com/channel/UCQPYJluYC_sn_Qz_XE-YbTQ/live" -``` - -## Meeting Base Example - -**File:** `meeting_base_commcomm` - -``` -CALENDAR_FILTER="Node.js Community Committee" -CALENDAR_ID="nodejs.org_nr77ama8p7d7f9ajrpnu506c98@group.calendar.google.com" -USER="nodejs" -REPO="community-committee" -GROUP_NAME="Community Committee" -AGENDA_TAG=cc-agenda -JOINING_INSTRUCTIONS=" - -* link for participants: Will be added a few minutes before meeting starts -* For those who just want to watch: https://www.youtube.com/channel/UCQPYJluYC_sn_Qz_XE-YbTQ/live" -``` - -# Minutes Base - -A basic outline for the meeting minutes to be autogenerated in Google Docs. The only basic change from the default template is the message about what label agenda items are extracted from. - -**File:** `minutes_base_` - -``` -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Foundation Calendar**: https://nodejs.org/calendar - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. - -``` - -## Minutes Base Example - -**File:** `minutes_base_commcomm` - -``` - - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **cc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Foundation Calendar**: https://nodejs.org/calendar - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. -``` - -# Observers - -List meeting observers who will consistently attend meetings _as observers_. -**File:** `observers_` - -``` -* -* -* -(...) -``` - -## Observers Example - -**File:** `observers_commcomm` - -``` -* @therebelrobot (Oz Haven - observer) -* @ParidelPooya (Pooya Paridel - observer) -* @rykerrumsey (Ryker Rumsey - observer) -* @baez (Behzad Karim - observer) -* @BinarySo1o (Therese Stirling - observer) -* @amiller-gh (Adam Miller - observer) -* @yosuke-furukawa (Yosuke Furukawa - observer) -* @Maurice-Hayward (Maurice Hayward - observer) -* @mikehostetler (Mike Hostetler - observer) -* @sarahkconway (Sarah Conway - observer) -* @Tiriel (Benjamin Zaslavsky - observer) -* @DiegoZoracKy (Diego ZoracKy - observer) -* @ZibbyKeaton (Zibby Keaton - observer) -* @tobyfarley (Toby Farley - observer) -* @Bamieh (Ahmad Bamieh - observer) -* @pchrysa (Chrysa - observer) -* @foadlab (observer) -* @codeekage (Abraham Agiri - observer) -* @Voskan (Voskan Voskanyan - observer) -``` diff --git a/configs/build.json b/configs/build.json new file mode 100644 index 0000000..fc0e29d --- /dev/null +++ b/configs/build.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "build" + }, + "meeting": { + "displayName": "Node.js Build Working Group", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Build WG Meeting" + }, + "links": { + "participant": "https://zoom.us/j/715960833", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/build"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/cpc.json b/configs/cpc.json new file mode 100644 index 0000000..d0f65d2 --- /dev/null +++ b/configs/cpc.json @@ -0,0 +1,59 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "cross-project-council", + "agendaTag": "cross-project-council-agenda" + }, + "meeting": { + "displayName": "OpenJS Cross Project Council", + "labels": ["cpc-meeting"], + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Cross Project Council Meeting" + }, + "links": { + "participant": "https://zoom-lfx.platform.linuxfoundation.org/meeting/99526225088?password=2d77485b-e041-4015-ae9a-f5342009d310", + "observer": "https://livestream.openjsf.org" + }, + "invitees": [ + "OpenJS Foundation Cross Project Council", + "OpenJS Foundation Project Maintainers", + "OpenJS Board of Directors" + ] + }, + "hackmd": { + "team": "openjs-nodejs" + }, + "agenda": [ + { + "title": "Board Meeting Updates", + "items": [ + "https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-board" + ] + }, + { + "title": "Staff Updates", + "items": [ + "https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-legal-info", + "https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-staff-update", + "https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-website-update" + ] + }, + { + "title": "Next Week's Working Session", + "description": "Are there any initiatives or agenda items that we should use a working session to further progress on?", + "items": [ + "https://github.com/openjs-foundation/cross-project-council/labels/cpc-working-session" + ] + }, + { + "title": "Regular Reviews", + "description": "Please review regularly our list of dates and reminders, our quarterly review issues, and check the list of issues that can be closed:", + "items": [ + "https://github.com/openjs-foundation/cross-project-council/blob/main/Dates-and-Reminders.md", + "https://github.com/openjs-foundation/cross-project-council/labels/cpc-quartely-review", + "https://github.com/openjs-foundation/cross-project-council/labels/cpc-can-issue-be-closed" + ] + } + ] +} diff --git a/configs/diagnostics-deep-dive.json b/configs/diagnostics-deep-dive.json new file mode 100644 index 0000000..15deecd --- /dev/null +++ b/configs/diagnostics-deep-dive.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "nodejs", + "repo": "diagnostics", + "agendaTag": "diag-deepdive-agenda" + }, + "meeting": { + "displayName": "Node.js Diagnostics Deep Dive", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Diagnostics Deep Dive Meeting" + }, + "links": { + "participant": "https://zoom.us/j/466707925", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/diagnostics"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/diagnostics.json b/configs/diagnostics.json new file mode 100644 index 0000000..6b11508 --- /dev/null +++ b/configs/diagnostics.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "nodejs", + "repo": "diagnostics", + "agendaTag": "diag-agenda" + }, + "meeting": { + "displayName": "Node.js Diagnostics Working Group", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Diagnostics WG Meeting" + }, + "links": { + "participant": "https://zoom.us/j/466707925", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/diagnostics"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/ecosystem-report.json b/configs/ecosystem-report.json new file mode 100644 index 0000000..c99e319 --- /dev/null +++ b/configs/ecosystem-report.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "ecosystem-report-collab-space", + "agendaTag": "ecosystem-report-agenda" + }, + "meeting": { + "displayName": "OpenJS Ecosystem Report Collab Space", + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Ecosystem Report Collab Space" + }, + "links": { + "participant": "https://zoom-lfx.platform.linuxfoundation.org/meeting/93477817392?password=d91f112c-4840-48a6-8c30-1ce94cc0e418", + "observer": "https://livestream.openjsf.org" + }, + "invitees": ["@openjs-foundation/ecosystem-report"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/loaders.json b/configs/loaders.json new file mode 100644 index 0000000..925e254 --- /dev/null +++ b/configs/loaders.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "loaders" + }, + "meeting": { + "displayName": "Node.js Loaders Team", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Loaders Team Meeting" + }, + "links": { + "participant": "https://zoom.us/j/97506450082", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/loaders"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/next-10.json b/configs/next-10.json new file mode 100644 index 0000000..38893d5 --- /dev/null +++ b/configs/next-10.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "next-10" + }, + "meeting": { + "displayName": "Node.js Next 10 Years team", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Node.js Next 10 years" + }, + "links": { + "participant": "https://zoom.us/j/99950131676", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/next-10"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/package-maintenance.json b/configs/package-maintenance.json new file mode 100644 index 0000000..ab89430 --- /dev/null +++ b/configs/package-maintenance.json @@ -0,0 +1,28 @@ +{ + "github": { + "owner": "nodejs", + "repo": "package-maintenance" + }, + "meeting": { + "displayName": "Node.js Package Maintenance Team", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Package Maintenance" + }, + "links": { + "participant": "https://zoom.us/j/431077278", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/package-maintenance"] + }, + "hackmd": { + "team": "openjs-nodejs" + }, + "agenda": [ + { + "title": "Project Board Review", + "description": "Ask participants about the state of the Project Board and necessary changes", + "items": ["https://github.com/nodejs/package-maintenance/projects/1"] + } + ] +} diff --git a/configs/package-metadata-interop.json b/configs/package-metadata-interop.json new file mode 100644 index 0000000..2051f00 --- /dev/null +++ b/configs/package-metadata-interop.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "package-metadata-interoperability-collab-space", + "agendaTag": "package-metadata-agenda" + }, + "meeting": { + "displayName": "OpenJS Package Metadata Interoperability Collab Space", + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Package Metadata Interoperability" + }, + "links": { + "participant": "<>", + "observer": "https://livestream.openjsf.org" + }, + "invitees": ["@openjs-foundation/package-metadata-interop"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/release-wg.json b/configs/release-wg.json new file mode 100644 index 0000000..a554462 --- /dev/null +++ b/configs/release-wg.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "Release" + }, + "meeting": { + "displayName": "Node.js Release Working Group", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Release Working Group Meeting" + }, + "links": { + "participant": "https://zoom.us/j/157618869", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/release", "@nodejs/lts"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/security-collab.json b/configs/security-collab.json new file mode 100644 index 0000000..5e20a64 --- /dev/null +++ b/configs/security-collab.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "security-collab-space", + "agendaTag": "security-agenda" + }, + "meeting": { + "displayName": "OpenJS Security Collab Space", + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Security Collab Space meeting" + }, + "links": { + "participant": "https://zoom.us/j/94497273832", + "observer": "https://livestream.openjsf.org" + }, + "invitees": ["All are welcome"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/security-wg.json b/configs/security-wg.json new file mode 100644 index 0000000..46eb1f9 --- /dev/null +++ b/configs/security-wg.json @@ -0,0 +1,30 @@ +{ + "github": { + "owner": "nodejs", + "repo": "security-wg" + }, + "meeting": { + "displayName": "Node.js Security Working Group", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Security-WG Meeting" + }, + "links": { + "participant": "https://zoom.us/j/92309450775", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/security-wg"] + }, + "hackmd": { + "team": "openjs-nodejs" + }, + "agenda": [ + { + "title": "Reviews", + "items": [ + "Vulnerability Review - https://github.com/nodejs/nodejs-dependency-vuln-assessments/issues", + "OpenSSF Scorecard Monitor Review - https://github.com/nodejs/security-wg/issues?q=is%3Aissue+OpenSSF+Scorecard+Report+Updated%21+" + ] + } + ] +} diff --git a/configs/standards.json b/configs/standards.json new file mode 100644 index 0000000..8eac349 --- /dev/null +++ b/configs/standards.json @@ -0,0 +1,25 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "standards" + }, + "meeting": { + "displayName": "OpenJS Standards Working Group", + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Standards Working Group Meeting" + }, + "links": { + "participant": "https://zoom.us/j/599005386", + "observer": "https://livestream.openjsf.org" + }, + "invitees": [ + "OpenJS Foundation Cross Project Council", + "OpenJS Foundation Project Maintainers", + "OpenJS Foundation Board of Directors" + ] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/sustainability-collab.json b/configs/sustainability-collab.json new file mode 100644 index 0000000..4590419 --- /dev/null +++ b/configs/sustainability-collab.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "openjs-foundation", + "repo": "sustainability-collab-space", + "agendaTag": "sustainability-agenda" + }, + "meeting": { + "displayName": "OpenJS Sustainability Collab Space", + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Sustainability Collaboration Space" + }, + "links": { + "participant": "https://zoom-lfx.platform.linuxfoundation.org/meeting/97342926119?password=39c25254-e7a3-4830-be8e-d54d63234bfb", + "observer": "https://livestream.openjsf.org" + }, + "invitees": ["@openjs-foundation/sustainability-collaboration-space"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/tooling.json b/configs/tooling.json new file mode 100644 index 0000000..eccda61 --- /dev/null +++ b/configs/tooling.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "tooling" + }, + "meeting": { + "displayName": "Node.js Tooling Group", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Node.js Tooling" + }, + "links": { + "participant": "https://zoom.us/j/113867470", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/tooling"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/tsc.json b/configs/tsc.json new file mode 100644 index 0000000..f4eba0c --- /dev/null +++ b/configs/tsc.json @@ -0,0 +1,57 @@ +{ + "github": { + "owner": "nodejs", + "repo": "tsc" + }, + "meeting": { + "displayName": "Node.js Technical Steering Committee (TSC)", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Node.js TSC Meeting" + }, + "links": { + "participant": "https://zoom.us/j/611357642", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": [ + "Antoine du Hamel @aduh95 (voting member)", + "Yagiz Nizipli @anonrig (voting member)", + "Benjamin Gruenbaum @benjamingr (voting member)", + "Ruben Bridgewater @BridgeAR (voting member)", + "Gireesh Punathil @gireeshpunathil (voting member)", + "James Snell @jasnell (voting member)", + "Joyee Cheung @joyeecheung (voting member)", + "Chengzhong Wu @legendecas (voting member)", + "Marco Ippolito @marco-ippolito (voting member)", + "Matteo Collina @mcollina (voting member)", + "Filip Skokan @panva (voting member)", + "Rafael Gonzaga @RafaelGSS (voting member)", + "Darshan Sen @RaisinTen (voting member)", + "Richard Lau @richardlau (voting member)", + "Robert Nagy @ronag (voting member)", + "Ruy Adorno @ruyadorno (voting member)", + "Paolo Insogna @ShogunPanda (voting member)", + "MichaΓ«l Zasso @targos (voting member)", + "Tobias Nießen @tniessen (voting member)", + "Beth Griggs @BethGriggs (regular member)", + "Ben Noordhuis @bnoordhuis (regular member)", + "Colin Ihrig @cjihrig (regular member)", + "Geoffrey Booth @GeoffreyBooth (regular member)", + "Moshe Atlow @MoLow (regular member)", + "Shelley Vohr @codebytere (regular member)", + "Rich Trott @Trott (regular member)", + "Joe Sepi @joesepi (Guest - Node.js CPC rep)" + ] + }, + "hackmd": { + "team": "openjs-nodejs" + }, + "agenda": [ + { + "title": "Reminders", + "items": [ + "Remember to nominate people for the [contributor spotlight](https://github.com/nodejs/node/blob/main/doc/contributing/reconizing-contributors.md#bi-monthly-contributor-spotlight)" + ] + } + ] +} diff --git a/configs/typescript.json b/configs/typescript.json new file mode 100644 index 0000000..299c285 --- /dev/null +++ b/configs/typescript.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "typescript" + }, + "meeting": { + "displayName": "Node.js TypeScript Team", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "TypeScript team Meeting" + }, + "links": { + "participant": "https://zoom.us/j/95749675148", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/typescript"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/uvwasi.json b/configs/uvwasi.json new file mode 100644 index 0000000..753fafc --- /dev/null +++ b/configs/uvwasi.json @@ -0,0 +1,21 @@ +{ + "github": { + "owner": "nodejs", + "repo": "uvwasi" + }, + "meeting": { + "displayName": "Node.js uvwasi Team", + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Node.js uvwasi team meeting" + }, + "links": { + "participant": "https://zoom.us/j/91612484369", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/wasi"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/web-server-frameworks.json b/configs/web-server-frameworks.json new file mode 100644 index 0000000..46a041a --- /dev/null +++ b/configs/web-server-frameworks.json @@ -0,0 +1,22 @@ +{ + "github": { + "owner": "nodejs", + "repo": "web-server-frameworks" + }, + "meeting": { + "displayName": "Node.js Web Server Frameworks", + "labels": ["meeting"], + "calendar": { + "id": "c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8", + "filter": "Web Server Frameworks" + }, + "links": { + "participant": "https://zoom.us/j/96287211361", + "observer": "https://www.youtube.com/c/nodejs+foundation/live" + }, + "invitees": ["@nodejs/web-server-frameworks"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/configs/web.json b/configs/web.json new file mode 100644 index 0000000..4384144 --- /dev/null +++ b/configs/web.json @@ -0,0 +1,23 @@ +{ + "github": { + "owner": "nodejs", + "repo": "web-team", + "agendaTag": "web-agenda" + }, + "meeting": { + "displayName": "Node.js Web Team", + "labels": ["meeting"], + "calendar": { + "id": "linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g", + "filter": "Web Team Monthly Meeting" + }, + "links": { + "participant": "https://zoom-lfx.platform.linuxfoundation.org/meeting/91972207331?password=419d8029-a3c7-4536-9666-d9e97c0f0f93", + "observer": "https://livestream.openjsf.org" + }, + "invitees": ["@nodejs/web"] + }, + "hackmd": { + "team": "openjs-nodejs" + } +} diff --git a/create-node-meeting-artifacts.mjs b/create-node-meeting-artifacts.mjs deleted file mode 100644 index 70a0bd1..0000000 --- a/create-node-meeting-artifacts.mjs +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env node - -/** - * Node.js Meeting Artifacts Creator - * - * Usage: - * node create-node-meeting-artifacts.mjs [meetingGroup] - * npm run tsc-meeting - * npm run dev -- tsc - */ - -import { getConfig } from './src/config.mjs'; -import * as github from './src/github.mjs'; -import * as google from './src/google.mjs'; -import * as hackmd from './src/hackmd.mjs'; -import * as meetings from './src/meeting.mjs'; - -// Step 1: Application configuration -const config = getConfig(); - -// Step 2: Initialize Google Calendar client with API Key -const calendarClient = google.createCalendarClient(config.google); - -// Step 3: Initialize GitHub client -const githubClient = github.createGitHubClient(config); - -// Step 4: Read meeting configuration from templates -const meetingConfig = await meetings.readMeetingConfig(config); - -// Step 5: Initialize HackMD client with meeting configuration -const hackmdClient = hackmd.createHackMDClient(config, meetingConfig); - -// Step 6: Find next meeting event in calendar -const event = await google.findNextMeetingEvent(calendarClient, meetingConfig); - -// Step 7: Extract meeting date from event -const meetingDate = new Date(event.start.dateTime); - -// Step 8: Get Meeting Title -const meetingTitle = meetings.generateMeetingTitle( - config, - meetingConfig, - meetingDate -); - -// Step 9: Get agenda information using native implementation -const gitHubAgendaIssues = await github.getAgendaIssues( - githubClient, - config, - meetingConfig -); - -// Step 10: Parse meeting agenda from GitHub issues -const meetingAgenda = meetings.generateMeetingAgenda(gitHubAgendaIssues); - -// Step 11: Create HackMD document with meeting notes and tags -const hackmdNote = await hackmd.createMeetingNotesDocument( - hackmdClient, - meetingTitle, - '' -); - -// Step 12: Get the HackMD document link -const minutesDocLink = - hackmdNote.publishLink || `https://hackmd.io/${hackmdNote.id}`; - -// Step 13: Generate meeting issue content using native implementation -const issueContent = await meetings.generateMeetingIssue( - config, - meetingConfig, - meetingDate, - meetingAgenda, - minutesDocLink -); - -// Step 14: Create GitHub issue with HackMD link -const githubIssue = await github.createGitHubIssue( - githubClient, - meetingConfig, - meetingTitle, - issueContent -); - -// Step 15: Update the minutes content with the HackMD link -const minutesContent = await meetings.generateMeetingMinutes( - config, - meetingConfig, - meetingTitle, - meetingAgenda, - minutesDocLink, - githubIssue.html_url -); - -// Step 16: Update the HackMD document with the self-referencing link -await hackmd.updateMeetingNotesDocument( - hackmdClient, - hackmdNote.id, - minutesContent -); - -// Output success information with links -console.log(`Created GitHub issue: ${githubIssue.html_url}`); -console.log(`Created HackMD document: ${minutesDocLink}`); diff --git a/global.d.ts b/global.d.ts deleted file mode 100644 index dfc2a0c..0000000 --- a/global.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Global TypeScript definitions for JSDoc usage - * This file makes types from third-party libraries available globally without imports in JSDoc comments - */ - -import type { calendar_v3 } from '@googleapis/calendar'; -import type { RestEndpointMethodTypes } from '@octokit/rest'; -import type { API } from '@hackmd/api'; -import type { SingleNote } from '@hackmd/api/dist/type.d.ts'; - -declare global { - // Google API type aliases - type CalendarEvent = calendar_v3.Schema$Event; - type CalendarClient = calendar_v3.Calendar; - type HackMDClient = API; - type HackMDNote = SingleNote; - - // GitHub API type aliases - type GitHubIssue = - RestEndpointMethodTypes['issues']['create']['response']['data']; -} diff --git a/templates/observers_Release b/output.txt similarity index 100% rename from templates/observers_Release rename to output.txt diff --git a/package-lock.json b/package-lock.json index e6462f1..d22ae6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,15 +12,14 @@ "@googleapis/calendar": "^11.0.1", "@hackmd/api": "^2.5.0", "@octokit/rest": "^22.0.0", - "dedent": "^1.6.0", - "dotenv": "^17.2.2" + "commander": "^14.0.1", + "mustache": "^4.2.0" }, "bin": { - "create-meeting": "create-node-meeting-artifacts.mjs" + "create-node-meeting-artifacts": "src/index.mjs" }, "devDependencies": { "@eslint/js": "^9.33.0", - "@types/properties-parser": "^0.3.3", "eslint": "^9.33.0", "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-jsdoc": "^54.0.0", @@ -571,26 +570,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/node": { - "version": "24.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.1.tgz", - "integrity": "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.10.0" - } - }, - "node_modules/@types/properties-parser": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@types/properties-parser/-/properties-parser-0.3.3.tgz", - "integrity": "sha512-VZhGpE+QQ2JNbaY4B4Y2iM/jdUsq3HO75uBKLk07VT6P2Kg1aifeYL6I3RosFniSdAb4PtuH5UaY8jXU7JeIYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/types": { "version": "8.39.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.1.tgz", @@ -1120,6 +1099,15 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", + "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/comment-parser": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", @@ -1178,20 +1166,6 @@ } } }, - "node_modules/dedent": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", - "integrity": "sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==", - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1208,18 +1182,6 @@ "node": ">=0.4.0" } }, - "node_modules/dotenv": { - "version": "17.2.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.2.tgz", - "integrity": "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2204,6 +2166,15 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/napi-postinstall": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", @@ -2662,13 +2633,6 @@ "node": ">= 0.8.0" } }, - "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", - "dev": true, - "license": "MIT" - }, "node_modules/universal-user-agent": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", diff --git a/package.json b/package.json index e5dc8fd..9c10de5 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "0.0.1", "description": "Creates issue and minutes doc for node meeting", "type": "module", - "main": "create-node-meeting-artifacts.mjs", + "main": "src/index.mjs", "bin": { - "create-meeting": "./create-node-meeting-artifacts.mjs" + "create-node-meeting-artifacts": "./src/index.mjs" }, "engines": { "node": ">=22.0.0" @@ -14,12 +14,11 @@ "@googleapis/calendar": "^11.0.1", "@hackmd/api": "^2.5.0", "@octokit/rest": "^22.0.0", - "dedent": "^1.6.0", - "dotenv": "^17.2.2" + "commander": "^14.0.1", + "mustache": "^4.2.0" }, "devDependencies": { "@eslint/js": "^9.33.0", - "@types/properties-parser": "^0.3.3", "eslint": "^9.33.0", "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-jsdoc": "^54.0.0", @@ -27,57 +26,14 @@ "prettier": "^3.6.2" }, "scripts": { - "dev": "node --env-file=.env create-node-meeting-artifacts.mjs", + "dev": "node --env-file=.env src/index.mjs", "lint": "eslint .", "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", "check": "npm run lint && npm run format:check", "test": "node --test test/**/*.test.mjs", - "test:watch": "node --test --watch test/**/*.test.mjs", - "test:coverage": "node --test --experimental-test-coverage test/**/*.test.mjs", - "uvwasi-meeting": "create-meeting uvwasi", - "uvwasi-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs uvwasi", - "tsc-meeting": "create-meeting tsc", - "tsc-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs tsc", - "build-meeting": "create-meeting build", - "build-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs build", - "diag-meeting": "create-meeting diag", - "diag-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs diag", - "diag-deepdive-meeting": "create-meeting diag_deepdive", - "diag-deepdive-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs diag_deepdive", - "typescript-meeting": "create-meeting typescript", - "typescript-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs typescript", - "release-meeting": "create-meeting Release", - "release-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs Release", - "cross-project-council-meeting": "create-meeting cross_project_council", - "cross-project-council-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs cross_project_council", - "modules-meeting": "create-meeting modules", - "modules-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs modules", - "tooling-meeting": "create-meeting tooling", - "tooling-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs tooling", - "security-wg-meeting": "create-meeting security-wg", - "security-wg-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs security-wg", - "next-10-meeting": "create-meeting next-10", - "next-10-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs next-10", - "package-maintenance-meeting": "create-meeting package-maintenance", - "package-maintenance-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs package-maintenance", - "package-metadata-interop-meeting": "create-meeting package_metadata_interop", - "package-metadata-interop-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs package_metadata_interop", - "ecosystem-report-meeting": "create-meeting ecosystem_report", - "ecosystem-report-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs ecosystem_report", - "sustainability-collab-meeting": "create-meeting sustainability_collab", - "sustainability-collab-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs sustainability_collab", - "standards-meeting": "create-meeting standards", - "standards-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs standards", - "security-collab-meeting": "create-meeting security_collab", - "security-collab-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs security_collab", - "loaders-meeting": "create-meeting loaders", - "loaders-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs loaders", - "web": "create-meeting web", - "web:dev": "node --env-file=.env create-node-meeting-artifacts.mjs web", - "web-server-frameworks-meeting": "create-meeting web-server-frameworks", - "web-server-frameworks-meeting:dev": "node --env-file=.env create-node-meeting-artifacts.mjs web-server-frameworks" + "test:watch": "node --test --watch test/**/*.test.mjs" }, "author": "", "license": "MIT" diff --git a/src/config.mjs b/src/config.mjs index 38ad883..e1ffd4e 100644 --- a/src/config.mjs +++ b/src/config.mjs @@ -1,13 +1,8 @@ -import { homedir } from 'node:os'; -import { join, dirname } from 'node:path'; - -const defaultMeetingsDirectory = join(homedir(), '.make-node-meeting'); - /** * Gets the application configuration from environment variables and arguments - * @returns {import('./types.d.ts').AppConfig} Application configuration object + * @type {import('./types.d.ts').AppConfig} Application configuration object */ -export const getConfig = () => ({ +export default { // Meeting group from command line argument, defaults to 'tsc' meetingGroup: process.argv[2], @@ -25,11 +20,4 @@ export const getConfig = () => ({ // HackMD API token for authentication apiToken: process.env.HACKMD_API_TOKEN, }, - - // Directory paths for templates, output, and configuration - directories: { - config: process.env.MEETINGS_CONFIG_DIR || './', - output: process.env.MEETINGS_OUTPUT_DIR || defaultMeetingsDirectory, - templates: join(dirname(import.meta.dirname), 'templates'), - }, -}); +}; diff --git a/src/constants.mjs b/src/constants.mjs index 897a892..c75e231 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -1,11 +1,3 @@ -// Default configuration values -export const DEFAULT_CONFIG = { - // Default GitHub organization name - githubOrg: 'nodejs', - // Default Host of the Meeting - host: 'Node.js', -}; - // Time constants for date calculations export const TIME_CONSTANTS = { // Week in milliseconds for calendar search diff --git a/src/github.mjs b/src/github.mjs index ec828b9..37e5490 100644 --- a/src/github.mjs +++ b/src/github.mjs @@ -1,7 +1,5 @@ import { Octokit } from '@octokit/rest'; -import { DEFAULT_CONFIG } from './constants.mjs'; - /** * Creates a GitHub API client * @param {import('./types.d.ts').AppConfig} config - Application configuration @@ -20,23 +18,17 @@ export const createGitHubClient = ({ githubToken: auth }) => */ export const createGitHubIssue = async ( { rest }, - { properties }, + { github, meeting }, title, content ) => { - const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg; - - const issueLabel = properties.ISSUE_LABEL - ? [properties.ISSUE_LABEL] - : undefined; - // Create the GitHub issue with meeting information const response = await rest.issues.create({ - owner: githubOrg, - repo: properties.REPO, + owner: github.owner, + repo: github.repo, title, body: content, - labels: issueLabel, + labels: meeting.labels, }); return response.data; @@ -48,31 +40,25 @@ export const createGitHubIssue = async ( * @returns {Promise<{ [key: string]: Array }>} Sorted issues */ export const sortIssuesByRepo = issues => - issues.reduce((obj, issue) => { - (obj[issue.repository_url.split('/').slice(-2).join('/')] ||= []).push( - issue - ); - return obj; - }, {}); + Object.entries( + issues.reduce((obj, issue) => { + (obj[issue.repository_url.split('/').slice(-2).join('/')] ||= []).push( + issue + ); + return obj; + }, {}) + ).map(entry => ({ repo: entry[0], issues: entry[1] })); /** * Fetches GitHub issues from all repositories in an organization with a specific label * @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client - * @param {import('./types.d.ts').AppConfig} config - Application configuration * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration * @returns {Promise<{ [key: string]: Array }>} Meeting agenda */ -export const getAgendaIssues = async ( - githubClient, - { meetingGroup }, - { properties } -) => { - const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg; - const agendaTag = properties.AGENDA_TAG ?? `${meetingGroup}-agenda`; - +export const getAgendaIssues = async (githubClient, { github }) => { // Get all issues/PRs in the organization const issues = await githubClient.paginate('GET /search/issues', { - q: `is:open label:${agendaTag} org:${githubOrg}`, + q: `is:open label:${github.agendaTag} owner:${github.owner}`, advanced_search: true, }); diff --git a/src/google.mjs b/src/google.mjs index 27b5400..1d749cc 100644 --- a/src/google.mjs +++ b/src/google.mjs @@ -14,7 +14,10 @@ export const createCalendarClient = ({ apiKey: auth }) => * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration object * @returns {Promise} Calendar event object */ -export const findNextMeetingEvent = async (calendarClient, meetingConfig) => { +export const findNextMeetingEvent = async ( + calendarClient, + { meeting: { calendar } } +) => { const now = new Date(); // Calculate the start of the current week (Saturday 00:00:00 UTC) @@ -33,21 +36,18 @@ export const findNextMeetingEvent = async (calendarClient, meetingConfig) => { // Search for events in the specified calendar using the filter text const response = await calendarClient.events.list({ - calendarId: meetingConfig.properties.CALENDAR_ID?.replace(/"/g, ''), + calendarId: `${calendar.id}@group.calendar.google.com`, timeMin: weekStart.toISOString(), timeMax: weekEnd.toISOString(), singleEvents: true, // Replace spaces with dots for Google Calendar search compatibility - q: meetingConfig.properties.CALENDAR_FILTER?.replace(/"/g, '').replace( - / /g, - '.' - ), + q: calendar.filter.replace(/"/g, '').replace(/ /g, '.'), }); // Ensure we found at least one event if (!response.data.items || response.data.items.length === 0) { throw new Error( - `No meeting found for ${meetingConfig?.properties?.GROUP_NAME || 'this group'} ` + + `No meeting found for ${calendar.filter} ` + `in the current week (${weekStart.toISOString().split('T')[0]} to ${weekEnd.toISOString().split('T')[0]}). ` + `This is expected for bi-weekly meetings or meetings that don't occur every week.` ); diff --git a/src/hackmd.mjs b/src/hackmd.mjs index 96096cf..a3c9063 100644 --- a/src/hackmd.mjs +++ b/src/hackmd.mjs @@ -8,12 +8,12 @@ import { HACKMD_DEFAULT_PERMISSIONS } from './constants.mjs'; * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration * @returns {HackMDClient} Configured HackMD API client */ -export const createHackMDClient = ({ hackmd: { apiToken } }, meetingConfig) => { - // Use team-specific API endpoint if teamName is provided in meeting config - const teamName = meetingConfig.properties.HACKMD_TEAM_NAME; - - const baseURL = teamName - ? `https://api.hackmd.io/v1/teams/${teamName}` +export const createHackMDClient = ( + { hackmd: { apiToken } }, + { hackmd: { team } } +) => { + const baseURL = team + ? `https://api.hackmd.io/v1/teams/${team}` : 'https://api.hackmd.io/v1'; return new HackMDAPI(apiToken, baseURL); diff --git a/src/index.mjs b/src/index.mjs new file mode 100644 index 0000000..fb4913c --- /dev/null +++ b/src/index.mjs @@ -0,0 +1,133 @@ +#!/usr/bin/env node + +import { readFile } from 'node:fs/promises'; + +import { Command } from 'commander'; +import mustache from 'mustache'; + +import envConfig from './config.mjs'; +import * as github from './github.mjs'; +import * as google from './google.mjs'; +import * as hackmd from './hackmd.mjs'; +import * as meetings from './meeting.mjs'; + +const program = new Command(); +program + .argument('[group]', 'Meeting group', 'tsc') + .option('--dry-run', 'Show output without creating/updating anything', false) + .parse(process.argv); + +/** @type {import('./types.d.ts').AppConfig} */ +const config = { + ...envConfig, + ...program.opts(), + meetingGroup: program.args[0], +}; + +// Initialize Google Calendar client with API Key +const calendarClient = google.createCalendarClient(config.google); + +// Initialize GitHub client +const githubClient = github.createGitHubClient(config); + +// Read meeting configuration from templates +const meetingConfig = await meetings.load(config.meetingGroup); + +// Initialize HackMD client with meeting configuration +const hackmdClient = hackmd.createHackMDClient(config, meetingConfig); + +// Find next meeting event in calendar +const event = await google.findNextMeetingEvent(calendarClient, meetingConfig); + +// Extract meeting date from event +const meetingDate = new Date(event.start.dateTime); + +// Get Meeting Title +const meetingTitle = meetings.generateMeetingTitle(meetingConfig, meetingDate); + +// Get agenda information using native implementation +const gitHubAgendaIssues = await github.getAgendaIssues( + githubClient, + meetingConfig +); + +// Create HackMD document with meeting notes and tags +let hackmdNote; +if (config.dryRun) { + hackmdNote = { id: 'dry-run', publishLink: 'https://hackmd.io/dry-run' }; + console.log('[dry-run] Would create HackMD meeting notes document.'); +} else { + hackmdNote = await hackmd.createMeetingNotesDocument( + hackmdClient, + meetingTitle, + '' + ); +} + +// Get the HackMD document link +const minutesDocLink = + hackmdNote.publishLink || `https://hackmd.io/${hackmdNote.id}`; + +// Create the template context +const templateContext = meetings.createTemplateContext( + meetingConfig, + meetingDate, + gitHubAgendaIssues, + [{ title: 'Minutes', url: minutesDocLink }] +); + +// Generate meeting issue content +const template = await readFile( + new URL(import.meta.resolve('../template.mustache')), + 'utf-8' +); +const issueContent = mustache.render(template, templateContext); + +// Create the actual issue +let githubIssue; +if (config.dryRun) { + githubIssue = { html_url: 'https://github.com/dry-run/issue' }; + console.log('[dry-run] Would create GitHub issue with title:', meetingTitle); + console.log('[dry-run] Would use the following content:\n', issueContent); +} else { + githubIssue = await github.createGitHubIssue( + githubClient, + meetingConfig, + meetingTitle, + issueContent + ); +} + +// Add the issue URL to the context +templateContext.externalURLs.push({ + title: 'GitHub Issue', + url: githubIssue.html_url, +}); + +// Create the notes +const minutesContent = mustache.render(template, templateContext); + +// Update the HackMD document with the self-referencing link +if (config.dryRun) { + console.log( + '[dry-run] Would update HackMD document with self-referencing link.' + ); + console.log( + '[dry-run] Would use the following notes content:\n', + minutesContent + ); +} else { + await hackmd.updateMeetingNotesDocument( + hackmdClient, + hackmdNote.id, + minutesContent + ); +} + +// Output success information with links +if (config.dryRun) { + console.log('Dry run mode: no data was created or updated.'); +} else { + console.log(`Created GitHub issue: ${githubIssue.html_url}`); + console.log(`Created HackMD document: ${minutesDocLink}`); +} diff --git a/src/meeting.mjs b/src/meeting.mjs index 09bd62c..5781094 100644 --- a/src/meeting.mjs +++ b/src/meeting.mjs @@ -1,179 +1,53 @@ -import { readFile } from 'node:fs/promises'; -import { join } from 'node:path'; - -import { parse } from 'dotenv'; - -import { DEFAULT_CONFIG } from './constants.mjs'; -import * as dates from './utils/dates.mjs'; -import * as templates from './utils/templates.mjs'; -import * as urls from './utils/urls.mjs'; +import { formatTimezones } from './utils/dates.mjs'; +import { + generateTimeAndDateLink, + generateWolframAlphaLink, +} from './utils/urls.mjs'; /** - * Reads and parses meeting configuration from template files - * @param {import('./types.d.ts').AppConfig} config - Application configuration - * @returns {Promise} Meeting configuration object + * Loads a meeting configuration file + * @param {string} meetingGroup + * @returns {import('./types.d.ts').MeetingConfig} */ -export const readMeetingConfig = async config => { - // Read all template files asynchronously - const invited = await readFile( - join(config.directories.templates, `invited_${config.meetingGroup}`), - 'utf8' - ); - - const observers = await readFile( - join(config.directories.templates, `observers_${config.meetingGroup}`), - 'utf8' - ); +export const load = async meetingGroup => { + /** @type {import('./types.d.ts').MeetingConfig} */ + const { default: config } = await import(`../configs/${meetingGroup}.json`, { + with: { type: 'json' }, + }); - const baseMeetingInfo = await readFile( - join(config.directories.templates, `meeting_base_${config.meetingGroup}`), - 'utf8' - ); + config.github.agendaTag ??= `${meetingGroup}-agenda`; - return { - invited, - observers, - baseMeetingInfo, - properties: parse(baseMeetingInfo), - }; + return config; }; /** * Generates the meeting title based on the meeting configuration - * @param {import('./types.d.ts').AppConfig} config - Application configuration * @param {import('./types.d.ts').MeetingConfig} meetingConfig - * @param {Date} meetingDate - Date of the meeting - * @returns {Promise} Generated meeting title + * @param {Date} date - Date of the meeting + * @returns {string} Generated meeting title */ -export const generateMeetingTitle = (config, meetingConfig, meetingDate) => { - const props = meetingConfig.properties; - - const host = props.HOST ?? DEFAULT_CONFIG.host; - const groupName = props.GROUP_NAME ?? config.meetingGroup; - - const utcShort = meetingDate.toISOString().split('T')[0]; - - return `${host} ${groupName} Meeting ${utcShort}`; -}; +export const generateMeetingTitle = ({ meeting }, date) => + `${meeting.displayName} Meeting ${date.toISOString().split('T')[0]}`; /** - * Generates the meeting agenda from the list of agenda issues - * @param {Array<{ [key: string]: Array }>} agendaIssues - List of agenda issues - * @returns {Promise} Formatted meeting agenda + * Creates template context for rendering + * @param {import('./types.d.ts').MeetingConfig} config - Meeting configuration + * @param {Date} date - Meeting date + * @param {Object} agenda - Issues grouped by repository + * @param {Array<{ title: string, url: string }>} externalURLs - HackMD document URL */ -export const generateMeetingAgenda = agendaIssues => { - // Format issues as markdown - let agendaMarkdown = ''; +export const createTemplateContext = (config, date, agenda, externalURLs) => { + const { utc, timezones } = formatTimezones(date); - Object.entries(agendaIssues).forEach(([repoName, issues]) => { - if (issues.length > 0) { - agendaMarkdown += `### ${repoName}\n\n`; - - issues.forEach(issue => { - // Escape markdown characters in title - const cleanTitle = issue.title.replace(/([[\]])/g, '\\$1'); - - agendaMarkdown += `* ${cleanTitle} [#${issue.number}](${issue.html_url})\n`; - }); - - agendaMarkdown += '\n'; - } - }); - - return agendaMarkdown.trim(); -}; - -/** - * Generates meeting issue content directly (replaces make-node-meeting.sh) - * @param {import('./types.d.ts').AppConfig} config - Application configuration - * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration - * @param {string} meetingAgenda - Meeting agenda (optional) - * @param {string} minutesDocLink - Minutes document link (optional) - * @param {Date} meetingDate - Date of the meeting - */ -export const generateMeetingIssue = async ( - config, - meetingConfig, - meetingDate, - meetingAgenda, - minutesDocLink -) => { - const props = meetingConfig.properties; - - const joiningInstructions = props.JOINING_INSTRUCTIONS ?? ''; - const githubOrg = props.USER ?? DEFAULT_CONFIG.githubOrg; - - const groupName = props.GROUP_NAME ?? config.meetingGroup; - const agendaTag = props.AGENDA_TAG ?? `${config.meetingGroup}-agenda`; - - // Format the meeting date and timezones - const { utc, timezones } = dates.formatTimezones(meetingDate); - - // Generate timezone conversion links - const timeAndDateLink = urls.generateTimeAndDateLink(meetingDate, groupName); - const wolframLink = urls.generateWolframAlphaLink(meetingDate); - - // Generate timezone table - const timezoneTable = timezones - .map(({ label, time }) => `| ${label.padEnd(13)} | ${time} |`) - .join('\n'); - - // Read and process the meeting issue template - const templatePath = join(config.directories.templates, 'meeting_issue.md'); - - const template = await readFile(templatePath, 'utf8'); - - const templateVariables = { - UTC_TIME: utc, - TIMEZONE_TABLE: timezoneTable, - TIME_AND_DATE_LINK: timeAndDateLink, - WOLFRAM_ALPHA_LINK: wolframLink, - AGENDA_LABEL: agendaTag, - GITHUB_ORG: githubOrg, - AGENDA_CONTENT: meetingAgenda ?? '*No agenda items found.*', - INVITEES: meetingConfig.invited, - JOINING_INSTRUCTIONS: joiningInstructions, - MINUTES_DOC: minutesDocLink, - OBSERVERS: meetingConfig.observers ?? '', - }; - - return templates.parseVariables(template, templateVariables); -}; - -/** - * Creates meeting minutes document content by processing template - * @param {import('./types.d.ts').AppConfig} config - Application configuration - * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration - * @param {string} meetingTitle - Meeting title - * @param {string} meetingAgenda - Meeting agenda (optional) - * @param {string} minutesDocLink - Minutes document link (optional) - * @param {string} githubIssueLink - GitHub issue link (optional) - * @returns {Promise} Processed minutes document content - */ -export const generateMeetingMinutes = async ( - config, - meetingConfig, - meetingTitle, - meetingAgenda, - minutesDocLink, - githubIssueLink -) => { - // Read and process the meeting minutes template - const templatePath = join( - config.directories.templates, - `minutes_base_${config.meetingGroup}` - ); - - const template = await readFile(templatePath, 'utf8'); - - const templateVariables = { - TITLE: meetingTitle, - AGENDA_CONTENT: meetingAgenda, - INVITED: meetingConfig.invited, - OBSERVERS: meetingConfig.observers, - MINUTES_DOC: minutesDocLink, - GITHUB_ISSUE: githubIssueLink, + return { + config, + utc, + timezones, + agenda, + externalURLs, + timeLinks: [ + generateTimeAndDateLink(date, config.meeting.displayName), + generateWolframAlphaLink(date), + ], }; - - return templates.parseVariables(template, templateVariables); }; diff --git a/src/types.d.ts b/src/types.d.ts index e7a2d94..a8a089a 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -10,8 +10,6 @@ export interface AppConfig { google: GoogleConfig; /** HackMD API configuration */ hackmd: HackMDConfig; - /** Directory paths configuration */ - directories: DirectoryConfig; } /** @@ -30,50 +28,31 @@ export interface HackMDConfig { apiToken: string; } -/** - * Directory paths configuration - */ -export interface DirectoryConfig { - /** Templates directory path */ - templates: string; -} - -/** - * Meeting configuration object parsed from templates - */ export interface MeetingConfig { - /** Invited attendees list */ - invited: string; - /** Observers list */ - observers: string; - /** Base meeting information */ - baseMeetingInfo: string; - /** Parsed meeting properties */ - properties: MeetingProperties; -} - -/** - * Meeting properties parsed from template file - */ -export interface MeetingProperties { - /** Calendar ID to search for events */ - CALENDAR_ID?: string; - /** Text filter for calendar events */ - CALENDAR_FILTER?: string; - /** GitHub repository owner/user */ - USER?: string; - /** GitHub repository name */ - REPO?: string; - /** Host organization name (e.g. "Node.js", "OpenJS Foundation") */ - HOST?: string; - /** Display name for the meeting group */ - GROUP_NAME?: string; - /** Meeting agenda tag for labeling issues */ - AGENDA_TAG?: string; - /** Optional GitHub issue label */ - ISSUE_LABEL?: string; - /** HackMD team name for creating documents */ - HACKMD_TEAM_NAME?: string; - /** Meeting joining instructions */ - JOINING_INSTRUCTIONS?: string; + github: { + owner: string; + repo: string; + agendaTag: string; + }; + meeting: { + displayName: string; + labels?: string[]; + calendar: { + id: string; + filter: string; + }; + links: { + participant: string; + observer: string; + }; + invitees: string[]; + }; + hackmd: { + team: string; + }; + agenda: { + title: string; + description?: string; + items: string[]; + }[]; } diff --git a/src/utils/templates.mjs b/src/utils/templates.mjs deleted file mode 100644 index 78a997e..0000000 --- a/src/utils/templates.mjs +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Process template with variables - * @param {string} template - The template content - * @param {Object} variables - Object with template variables - * @returns {string} Processed template - */ -export const parseVariables = (template, variables) => { - let processed = template; - - for (const [key, value] of Object.entries(variables)) { - const placeholder = `$${key}$`; - - processed = processed.replace( - new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), - value || '' - ); - } - - // Replace any remaining placeholders with empty strings - processed = processed.replace(/\$[A-Z_]+\$/g, ''); - - return processed; -}; diff --git a/template.mustache b/template.mustache new file mode 100644 index 0000000..100d614 --- /dev/null +++ b/template.mustache @@ -0,0 +1,94 @@ +## Time + +**UTC {{utc}}**: + +| Timezone | Date/Time | +| -------- | --------- | +{{#timezones}} +| {{{label}}} | {{{time}}} | +{{/timezones}} + +Or in your local time: + +{{#timeLinks}} +* {{{.}}} +{{/timeLinks}} + +## Links + +{{#externalURLs}} +* {{{title}}}: {{{url}}} +{{/externalURLs}} + +## {{#isMinutes}}Present{{/isMinutes}}{{^isMinutes}}Invited{{/isMinutes}} + +{{#config.meeting.invitees}} +* {{{.}}} +{{/config.meeting.invitees}} + +### Observers/Guests + +{{#config.meeting.observers}} +* {{{.}}} +{{/config.meeting.observers}} + +## Agenda + +{{#isMinutes}} +### Announcements + +*No announcements.* +{{/isMinutes}} +{{#config.agenda}} +### {{{title}}} +{{#description}} + +{{{.}}} +{{/description}} + +{{#items}} +* {{{.}}} +{{/items}} + +{{/config.agenda}} +### Issues and Pull Requests + +Extracted from **{{{config.github.agendaTag}}}** labelled issues and pull requests from @{{{config.github.owner}}} prior to the meeting. + +{{#agenda}} +#### {{{repo}}} + +{{#issues}} +* {{{title}}} [#{{{number}}}]({{{html_url}}}) +{{/issues}} + +{{/agenda}} +{{^agenda}} +*No agenda items found.* + +{{/agenda}} +{{#isMinutes}} +### Other + +*No other items.* + +## Upcoming Meetings + +* **Calendar**: https://calendar.google.com/calendar/embed?src={{{config.meeting.calendarId}}} + +Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. +{{/isMinutes}} +{{^isMinutes}} +## Joining the meeting + +* To join this meeting, visit <{{{config.meeting.links.participant}}}>. +* To observe this meeting, visit <{{{config.meeting.links.observer}}}>. + +**Invitees** + +Please use the following emoji reactions in this post to indicate your availability. + +* :+1: - Attending +* :-1: - Not attending +* :confused: - Not sure +{{/isMinutes}} \ No newline at end of file diff --git a/templates/invited_Release b/templates/invited_Release deleted file mode 100644 index c52e9be..0000000 --- a/templates/invited_Release +++ /dev/null @@ -1,2 +0,0 @@ -* Release team: @nodejs/release -* LTS team: @nodejs/lts diff --git a/templates/invited_benchmarking b/templates/invited_benchmarking deleted file mode 100644 index 27bd766..0000000 --- a/templates/invited_benchmarking +++ /dev/null @@ -1 +0,0 @@ -* Benchmarking team: @nodejs/benchmarking diff --git a/templates/invited_build b/templates/invited_build deleted file mode 100644 index 832f6f8..0000000 --- a/templates/invited_build +++ /dev/null @@ -1 +0,0 @@ -* Build team: @nodejs/build diff --git a/templates/invited_cross_project_council b/templates/invited_cross_project_council deleted file mode 100644 index 382ca62..0000000 --- a/templates/invited_cross_project_council +++ /dev/null @@ -1,3 +0,0 @@ -* OpenJS Foundation Cross Project Council -* OpenJS Foundation Project Maintainers -* OpenJS Foundation Board of Directors diff --git a/templates/invited_diag b/templates/invited_diag deleted file mode 100644 index f9ef3c9..0000000 --- a/templates/invited_diag +++ /dev/null @@ -1 +0,0 @@ -* Diagnostics team: @nodejs/diagnostics diff --git a/templates/invited_diag_deepdive b/templates/invited_diag_deepdive deleted file mode 100644 index 85934a4..0000000 --- a/templates/invited_diag_deepdive +++ /dev/null @@ -1 +0,0 @@ -* Diagnostics deep dive meetings: @nodejs/diagnostics diff --git a/templates/invited_ecosystem_report b/templates/invited_ecosystem_report deleted file mode 100644 index 7e5a86a..0000000 --- a/templates/invited_ecosystem_report +++ /dev/null @@ -1 +0,0 @@ -* Ecosystem Report Collab Space Members: @openjs/ecosystem-report diff --git a/templates/invited_loaders b/templates/invited_loaders deleted file mode 100644 index 19a79ae..0000000 --- a/templates/invited_loaders +++ /dev/null @@ -1 +0,0 @@ -* Loaders team: @nodejs/loaders diff --git a/templates/invited_modules b/templates/invited_modules deleted file mode 100644 index c21b093..0000000 --- a/templates/invited_modules +++ /dev/null @@ -1 +0,0 @@ -* Modules team: @nodejs/modules diff --git a/templates/invited_next-10 b/templates/invited_next-10 deleted file mode 100644 index 853831a..0000000 --- a/templates/invited_next-10 +++ /dev/null @@ -1 +0,0 @@ -* Next 10 years team: @nodejs/next-10 diff --git a/templates/invited_outreach b/templates/invited_outreach deleted file mode 100644 index 311fcd5..0000000 --- a/templates/invited_outreach +++ /dev/null @@ -1 +0,0 @@ -* Outreach Members: @nodejs/outreach diff --git a/templates/invited_package-maintenance b/templates/invited_package-maintenance deleted file mode 100644 index f8d1b58..0000000 --- a/templates/invited_package-maintenance +++ /dev/null @@ -1 +0,0 @@ -* Package Maintenance team: @nodejs/package-maintenance diff --git a/templates/invited_package_metadata_interop b/templates/invited_package_metadata_interop deleted file mode 100644 index 74a9010..0000000 --- a/templates/invited_package_metadata_interop +++ /dev/null @@ -1 +0,0 @@ -* Package Metadata Interoperability Collab Space Members: @openjs/package-metadata-interop diff --git a/templates/invited_security-wg b/templates/invited_security-wg deleted file mode 100644 index 3b2c8b6..0000000 --- a/templates/invited_security-wg +++ /dev/null @@ -1 +0,0 @@ -* Security wg team: @nodejs/security-wg diff --git a/templates/invited_security_collab b/templates/invited_security_collab deleted file mode 100644 index 08196d7..0000000 --- a/templates/invited_security_collab +++ /dev/null @@ -1,5 +0,0 @@ -* OpenJS Foundation Security Collab Space Members -* OpenJS Foundation Cross Project Council -* OpenJS Foundation Project Maintainers -* OpenJS Foundation Board of Directors -* All are welcome diff --git a/templates/invited_standards b/templates/invited_standards deleted file mode 100644 index 382ca62..0000000 --- a/templates/invited_standards +++ /dev/null @@ -1,3 +0,0 @@ -* OpenJS Foundation Cross Project Council -* OpenJS Foundation Project Maintainers -* OpenJS Foundation Board of Directors diff --git a/templates/invited_sustainability_collab b/templates/invited_sustainability_collab deleted file mode 100644 index 2a94766..0000000 --- a/templates/invited_sustainability_collab +++ /dev/null @@ -1 +0,0 @@ -* Ecosystem Report Collab Space Members: @openjs-foundation/sustainability-collaboration-space \ No newline at end of file diff --git a/templates/invited_tooling b/templates/invited_tooling deleted file mode 100644 index 84eb25f..0000000 --- a/templates/invited_tooling +++ /dev/null @@ -1 +0,0 @@ -* Tooling team: @nodejs/tooling diff --git a/templates/invited_tsc b/templates/invited_tsc deleted file mode 100644 index 27d09bf..0000000 --- a/templates/invited_tsc +++ /dev/null @@ -1,27 +0,0 @@ -* Antoine du Hamel @aduh95 (voting member) -* Yagiz Nizipli @anonrig (voting member) -* Benjamin Gruenbaum @benjamingr (voting member) -* Ruben Bridgewater @BridgeAR (voting member) -* Gireesh Punathil @gireeshpunathil (voting member) -* James Snell @jasnell (voting member) -* Joyee Cheung @joyeecheung (voting member) -* Chengzhong Wu @legendecas (voting member) -* Marco Ippolito @marco-ippolito (voting member) -* Matteo Collina @mcollina (voting member) -* Filip Skokan @panva (voting member) -* Rafael Gonzaga @RafaelGSS (voting member) -* Darshan Sen @RaisinTen (voting member) -* Richard Lau @richardlau (voting member) -* Robert Nagy @ronag (voting member) -* Ruy Adorno @ruyadorno (voting member) -* Paolo Insogna @ShogunPanda (voting member) -* MichaΓ«l Zasso @targos (voting member) -* Tobias Nießen @tniessen (voting member) -* Beth Griggs @BethGriggs (regular member) -* Ben Noordhuis @bnoordhuis (regular member) -* Colin Ihrig @cjihrig (regular member) -* Geoffrey Booth @GeoffreyBooth (regular member) -* Moshe Atlow @MoLow (regular member) -* Shelley Vohr @codebytere (regular member) -* Rich Trott @Trott (regular member) -* Joe Sepi @joesepi (Guest - Node.js CPC rep) diff --git a/templates/invited_typescript b/templates/invited_typescript deleted file mode 100644 index fc6fbe7..0000000 --- a/templates/invited_typescript +++ /dev/null @@ -1 +0,0 @@ -* Typescript team: @nodejs/typescript diff --git a/templates/invited_userfeedback b/templates/invited_userfeedback deleted file mode 100644 index f591342..0000000 --- a/templates/invited_userfeedback +++ /dev/null @@ -1 +0,0 @@ -* User Feedback Members: @nodejs/user-feedback diff --git a/templates/invited_uvwasi b/templates/invited_uvwasi deleted file mode 100644 index 09020b2..0000000 --- a/templates/invited_uvwasi +++ /dev/null @@ -1 +0,0 @@ -* uvwasi team: @nodejs/wasi diff --git a/templates/invited_web b/templates/invited_web deleted file mode 100644 index aa32a46..0000000 --- a/templates/invited_web +++ /dev/null @@ -1 +0,0 @@ -* @nodejs/web \ No newline at end of file diff --git a/templates/invited_web-server-frameworks b/templates/invited_web-server-frameworks deleted file mode 100644 index e68363b..0000000 --- a/templates/invited_web-server-frameworks +++ /dev/null @@ -1 +0,0 @@ -* Web Server Frameworks team: @nodejs/web-server-frameworks diff --git a/templates/meeting_base_Release b/templates/meeting_base_Release deleted file mode 100644 index a528f10..0000000 --- a/templates/meeting_base_Release +++ /dev/null @@ -1,19 +0,0 @@ -CALENDAR_FILTER="Node.js Release Working Group Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="Release" -GROUP_NAME="Release WorkGroup" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -Join URL: - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure -" diff --git a/templates/meeting_base_benchmarking b/templates/meeting_base_benchmarking deleted file mode 100644 index cd777eb..0000000 --- a/templates/meeting_base_benchmarking +++ /dev/null @@ -1,11 +0,0 @@ -CALENDAR_FILTER="Benchmarking WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="benchmarking" -GROUP_NAME="Benchmarking WorkGroup" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: -* youtube admin page: " diff --git a/templates/meeting_base_build b/templates/meeting_base_build deleted file mode 100644 index 02b2067..0000000 --- a/templates/meeting_base_build +++ /dev/null @@ -1,24 +0,0 @@ -CALENDAR_FILTER="Build WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="build" -AGENDA_TAG=build-agenda -GROUP_NAME="Build WorkGroup" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. -* youtube admin page: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure -" diff --git a/templates/meeting_base_cross_project_council b/templates/meeting_base_cross_project_council deleted file mode 100644 index cd5c3de..0000000 --- a/templates/meeting_base_cross_project_council +++ /dev/null @@ -1,27 +0,0 @@ -CALENDAR_FILTER="Cross Project Council Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="cross-project-council" -GROUP_NAME="Cross Project Council" -AGENDA_TAG=cross-project-council-agenda -ISSUE_LABEL=cpc-meeting -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: Please refer to for meeting link - -* For those who just want to watch: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_diag b/templates/meeting_base_diag deleted file mode 100644 index ca9025b..0000000 --- a/templates/meeting_base_diag +++ /dev/null @@ -1,12 +0,0 @@ -CALENDAR_FILTER="Diagnostics WG Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="diagnostics" -GROUP_NAME="Diagnostics WorkGroup" -AGENDA_TAG=diag-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: -* youtube admin page: " diff --git a/templates/meeting_base_diag_deepdive b/templates/meeting_base_diag_deepdive deleted file mode 100644 index b985171..0000000 --- a/templates/meeting_base_diag_deepdive +++ /dev/null @@ -1,11 +0,0 @@ -CALENDAR_FILTER="Diagnostics Deep Dive Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="diagnostics" -GROUP_NAME="Diagnostics Deep Dive" -AGENDA_TAG=diag-deepdive-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: youtube admin page: " diff --git a/templates/meeting_base_ecosystem_report b/templates/meeting_base_ecosystem_report deleted file mode 100644 index 1125ebf..0000000 --- a/templates/meeting_base_ecosystem_report +++ /dev/null @@ -1,23 +0,0 @@ -CALENDAR_FILTER="Ecosystem Report Collab Space" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="ecosystem-report-collab-space" -GROUP_NAME="Ecosystem Report Collab Space" -AGENDA_TAG=ecosystem-report-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_loaders b/templates/meeting_base_loaders deleted file mode 100644 index 9ab34aa..0000000 --- a/templates/meeting_base_loaders +++ /dev/null @@ -1,9 +0,0 @@ -CALENDAR_FILTER="Loaders Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="loaders" -GROUP_NAME="Loaders Team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS="* link for participants: - -* For those who just want to watch: " diff --git a/templates/meeting_base_modules b/templates/meeting_base_modules deleted file mode 100644 index f77b4e4..0000000 --- a/templates/meeting_base_modules +++ /dev/null @@ -1,9 +0,0 @@ -CALENDAR_FILTER="Modules Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="modules" -GROUP_NAME="Modules Team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS="* link for participants: - -* For those who just want to watch: " diff --git a/templates/meeting_base_next-10 b/templates/meeting_base_next-10 deleted file mode 100644 index 74dbc77..0000000 --- a/templates/meeting_base_next-10 +++ /dev/null @@ -1,12 +0,0 @@ -CALENDAR_FILTER="Node.js Next 10 years" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="next-10" -GROUP_NAME="Next 10 Years team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: - -* For those who just want to watch: We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. -* youtube admin page: " diff --git a/templates/meeting_base_outreach b/templates/meeting_base_outreach deleted file mode 100644 index 26204dc..0000000 --- a/templates/meeting_base_outreach +++ /dev/null @@ -1,11 +0,0 @@ -CALENDAR_FILTER="Node.js Outreach Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="outreach" -GROUP_NAME="Outreach" -AGENDA_TAG=outreach-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* Link for participants: -* For those who just want to watch: " diff --git a/templates/meeting_base_package-maintenance b/templates/meeting_base_package-maintenance deleted file mode 100644 index de127ff..0000000 --- a/templates/meeting_base_package-maintenance +++ /dev/null @@ -1,11 +0,0 @@ -CALENDAR_FILTER="Package Maintenance" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="package-maintenance" -GROUP_NAME="Package Maintenance Team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: -* youtube admin page: " diff --git a/templates/meeting_base_package_metadata_interop b/templates/meeting_base_package_metadata_interop deleted file mode 100644 index 5905b1a..0000000 --- a/templates/meeting_base_package_metadata_interop +++ /dev/null @@ -1,25 +0,0 @@ -CALENDAR_FILTER="Package Metadata Interoperability" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="package-metadata-interoperability-collab-space" -GROUP_NAME="Package Metadata Interoperability Collab Space" -AGENDA_TAG=package-metadata-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: Zoom link: <> - -* For those who just want to watch: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_security-wg b/templates/meeting_base_security-wg deleted file mode 100644 index c70cd8d..0000000 --- a/templates/meeting_base_security-wg +++ /dev/null @@ -1,23 +0,0 @@ -CALENDAR_FILTER="Security-WG meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="security-wg" -GROUP_NAME="Security team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS="https://zoom.us/j/92309450775 - -* link for participants: <> -* For those who just want to watch We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. -* youtube admin page: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_security_collab b/templates/meeting_base_security_collab deleted file mode 100644 index e54b14d..0000000 --- a/templates/meeting_base_security_collab +++ /dev/null @@ -1,25 +0,0 @@ -CALENDAR_FILTER="Security Collab Space meeting" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="security-collab-space" -GROUP_NAME="Security Collab Space" -AGENDA_TAG=security-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: Zoom link: - -* For those who just want to watch: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_standards b/templates/meeting_base_standards deleted file mode 100644 index 107dbdc..0000000 --- a/templates/meeting_base_standards +++ /dev/null @@ -1,25 +0,0 @@ -CALENDAR_FILTER="Standards Working Group Meeting" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="standards" -GROUP_NAME="Standards Working Group" -AGENDA_TAG=standards-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: Zoom link: - -* For those who just want to watch: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_sustainability_collab b/templates/meeting_base_sustainability_collab deleted file mode 100644 index 1c5767c..0000000 --- a/templates/meeting_base_sustainability_collab +++ /dev/null @@ -1,23 +0,0 @@ -CALENDAR_FILTER="Sustainability Collaboration Space" -CALENDAR_ID="linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com" -USER="openjs-foundation" -HOST="OpenJS Foundation" -REPO="sustainability-collab-space" -GROUP_NAME="Sustainability Collaboration Space" -AGENDA_TAG=sustainability-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -link for participants: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_tooling b/templates/meeting_base_tooling deleted file mode 100644 index 0028923..0000000 --- a/templates/meeting_base_tooling +++ /dev/null @@ -1,11 +0,0 @@ -CALENDAR_FILTER="Node.js Tooling" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="tooling" -GROUP_NAME="Tooling Group" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: -* youtube admin page: " diff --git a/templates/meeting_base_tsc b/templates/meeting_base_tsc deleted file mode 100644 index 7b41a64..0000000 --- a/templates/meeting_base_tsc +++ /dev/null @@ -1,28 +0,0 @@ -CALENDAR_FILTER="Node.js TSC Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="TSC" -HOST="Node.js" -GROUP_NAME="Technical Steering Committee (TSC)" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -Zoom link: -Regular password - -## Public participation - -We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at **** when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. - - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_typescript b/templates/meeting_base_typescript deleted file mode 100644 index b2919d6..0000000 --- a/templates/meeting_base_typescript +++ /dev/null @@ -1,23 +0,0 @@ -CALENDAR_FILTER="TypeScript team meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="typescript" -GROUP_NAME="TypeScript team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS="https://zoom.us/j/95749675148 - -* link for participants: <> -* For those who just want to watch We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. -* youtube admin page: - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure yet -" diff --git a/templates/meeting_base_userfeedback b/templates/meeting_base_userfeedback deleted file mode 100644 index ee46718..0000000 --- a/templates/meeting_base_userfeedback +++ /dev/null @@ -1,16 +0,0 @@ -CALENDAR_FILTER="Node.js User Feedback Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="user-feedback" -GROUP_NAME="User Feedback" -AGENDA_TAG=user-feedback-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* We stream our conference call straight to YouTube so anyone can listen to it live. - It should start playing at when we turn it on. - There's usually a short cat-herding time at the start of the meeting and then occasionally we - have some quick private business to attend to before we can start recording & streaming. - So be patient and it should show up. -* youtube admin page: " diff --git a/templates/meeting_base_uvwasi b/templates/meeting_base_uvwasi deleted file mode 100644 index ec3880a..0000000 --- a/templates/meeting_base_uvwasi +++ /dev/null @@ -1,12 +0,0 @@ -CALENDAR_FILTER="Node.js uvwasi team meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="uvwasi" -GROUP_NAME="uvwasi team" -AGENDA_TAG=uvwasi-agenda -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: -* For those who just want to watch: -* youtube admin page: " diff --git a/templates/meeting_base_web b/templates/meeting_base_web deleted file mode 100644 index fffa791..0000000 --- a/templates/meeting_base_web +++ /dev/null @@ -1,22 +0,0 @@ -CALENDAR_FILTER="Web Team Meeting" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="web-team" -AGENDA_TAG=web-agenda -GROUP_NAME="Web Team" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* Check LFX for your invite link. If you are having issues, reach out to @avivkeller. - ---- - -**Invitees** - -Please use the following emoji reactions in this post to indicate your -availability. - -* :+1: - Attending -* :-1: - Not attending -* :confused: - Not sure -" diff --git a/templates/meeting_base_web-server-frameworks b/templates/meeting_base_web-server-frameworks deleted file mode 100644 index d69a14a..0000000 --- a/templates/meeting_base_web-server-frameworks +++ /dev/null @@ -1,12 +0,0 @@ -CALENDAR_FILTER="Web Server Frameworks" -CALENDAR_ID="c_16f0ae5d3a22625175d199dbdb1cac84c2d09eab7f173e94f558417cb5cdbfd8@group.calendar.google.com" -USER="nodejs" -REPO="web-server-frameworks" -GROUP_NAME="Web Server Frameworks" -HACKMD_TEAM_NAME="openjs-nodejs" -JOINING_INSTRUCTIONS=" - -* link for participants: - -* For those who just want to watch: We stream our conference call straight to YouTube so anyone can listen to it live, it should start playing at when we turn it on. There's usually a short cat-herding time at the start of the meeting and then occasionally we have some quick private business to attend to before we can start recording & streaming. So be patient and it should show up. -* youtube admin page: " diff --git a/templates/meeting_issue.md b/templates/meeting_issue.md deleted file mode 100644 index 15716c1..0000000 --- a/templates/meeting_issue.md +++ /dev/null @@ -1,38 +0,0 @@ -## Time - -**UTC $UTC_TIME$**: - -| Timezone | Date/Time | -| -------- | --------- | -$TIMEZONE_TABLE$ - -Or in your local time: - -* $TIME_AND_DATE_LINK$ -* or $WOLFRAM_ALPHA_LINK$ - -## Links - -* Minutes: <$MINUTES_DOC$> - -## Agenda - -Extracted from **$AGENDA_LABEL$** labelled issues and pull requests from the **$GITHUB_ORG$ org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Invited - -$INVITEES$ - -### Observers/Guests - -$OBSERVERS$ - -## Notes - -The agenda comes from issues labelled with `$AGENDA_LABEL$` across **all of the repositories in the $GITHUB_ORG$ org**. Please label any additional issues that should be on the agenda before the meeting starts. - -## Joining the meeting - -$JOINING_INSTRUCTIONS$ diff --git a/templates/minutes_base_Release b/templates/minutes_base_Release deleted file mode 100644 index 1b4cfaf..0000000 --- a/templates/minutes_base_Release +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **Release-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_benchmarking b/templates/minutes_base_benchmarking deleted file mode 100644 index 1dc1c92..0000000 --- a/templates/minutes_base_benchmarking +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **benchmarking-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_build b/templates/minutes_base_build deleted file mode 100644 index e0f6d88..0000000 --- a/templates/minutes_base_build +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **build-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_cross_project_council b/templates/minutes_base_cross_project_council deleted file mode 100644 index 5768faa..0000000 --- a/templates/minutes_base_cross_project_council +++ /dev/null @@ -1,50 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -### Announcements - -### Board Meeting Updates - -- https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-board - -### Staff Updates - -- https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-legal-info -- https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-staff-update -- https://github.com/openjs-foundation/cross-project-council/labels/waiting-on-website-update - -_Extracted from **cross-project-council-agenda** labeled issues and pull requests from the **openjs-foundation org** prior to the meeting._ - -$AGENDA_CONTENT$ - -### Next week's working session - -Are there any initiatives or agenda items that we should use a working session to further progress on? -- https://github.com/openjs-foundation/cross-project-council/labels/cpc-working-session - -### Regular reviews - -Please review regularly our list of dates and reminders, our quarterly review issues, and check the list of issues that can be closed: - -- https://github.com/openjs-foundation/cross-project-council/blob/main/Dates-and-Reminders.md -- https://github.com/openjs-foundation/cross-project-council/labels/cpc-quartely-review -- https://github.com/openjs-foundation/cross-project-council/labels/cpc-can-issue-be-closed - -### Q&A, Other - -## Upcoming Meetings - -- **Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_diag b/templates/minutes_base_diag deleted file mode 100644 index 7a3f340..0000000 --- a/templates/minutes_base_diag +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **diag-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_diag_deepdive b/templates/minutes_base_diag_deepdive deleted file mode 100644 index 34c294b..0000000 --- a/templates/minutes_base_diag_deepdive +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **diag-deepdive-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_ecosystem_report b/templates/minutes_base_ecosystem_report deleted file mode 100644 index 280bbc7..0000000 --- a/templates/minutes_base_ecosystem_report +++ /dev/null @@ -1,24 +0,0 @@ -## Links - -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ - -## Agenda - -## Announcements - -*Extracted from **** labelled issues and pull requests from the **Ecosystem report collab space** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **OpenJS Foundation Calendar**: https://calendar.google.com/calendar/u/0/embed?src=linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_loaders b/templates/minutes_base_loaders deleted file mode 100644 index 3673ea9..0000000 --- a/templates/minutes_base_loaders +++ /dev/null @@ -1,18 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ - -## Agenda - -## Announcements - -*Extracted from **loaders-agenda** labeled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ diff --git a/templates/minutes_base_modules b/templates/minutes_base_modules deleted file mode 100644 index a44377c..0000000 --- a/templates/minutes_base_modules +++ /dev/null @@ -1,19 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ - -## Agenda - -## Announcements - -*Extracted from **modules-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ diff --git a/templates/minutes_base_next-10 b/templates/minutes_base_next-10 deleted file mode 100644 index 2fbd845..0000000 --- a/templates/minutes_base_next-10 +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -* Extracted from **next10-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_outreach b/templates/minutes_base_outreach deleted file mode 100644 index 02b3fd4..0000000 --- a/templates/minutes_base_outreach +++ /dev/null @@ -1,29 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ -*Members and Observers: In order to facilitate attendance tracking, don't hesitate do add yourselves to the minutes doc* - -## Agenda - -## Announcements - -*Extracted from **outreach-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_package-maintenance b/templates/minutes_base_package-maintenance deleted file mode 100644 index 6711896..0000000 --- a/templates/minutes_base_package-maintenance +++ /dev/null @@ -1,32 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **package-maintenance-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Project Board Review (maybe, if time permits) - -Ask participants about the state of [Project Board](https://github.com/nodejs/package-maintenance/projects/1) and necessary changes if time permits. - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_package_metadata_interop b/templates/minutes_base_package_metadata_interop deleted file mode 100644 index 06796a9..0000000 --- a/templates/minutes_base_package_metadata_interop +++ /dev/null @@ -1,26 +0,0 @@ -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **** labelled issues and pull requests from the **package metadata interoperability collab space** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Foundation Calendar**: https://nodejs.org/calendar - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_security-wg b/templates/minutes_base_security-wg deleted file mode 100644 index 3161b36..0000000 --- a/templates/minutes_base_security-wg +++ /dev/null @@ -1,31 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **security-wg-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -- [ ] Vulnerability Review - https://github.com/nodejs/nodejs-dependency-vuln-assessments/issues -- [ ] OpenSSF Scorecard Monitor Review - https://github.com/nodejs/security-wg/issues?q=is%3Aissue+OpenSSF+Scorecard+Report+Updated%21+ - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_security_collab b/templates/minutes_base_security_collab deleted file mode 100644 index 9a17a99..0000000 --- a/templates/minutes_base_security_collab +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -### Announcements - -*Extracted from **security-agenda** labeled issues and pull requests from the **openjs-foundation org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_standards b/templates/minutes_base_standards deleted file mode 100644 index 6ed2dae..0000000 --- a/templates/minutes_base_standards +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -### Announcements - -*Extracted from **cross-project-council-agenda** labeled issues and pull requests from the **openjs-foundation org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_sustainability_collab b/templates/minutes_base_sustainability_collab deleted file mode 100644 index 26c9ac8..0000000 --- a/templates/minutes_base_sustainability_collab +++ /dev/null @@ -1,24 +0,0 @@ -## Links - -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ - -## Agenda - -## Announcements - -*Extracted from **** labelled issues and pull requests from the **Ecosystem report collab space** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **OpenJS Foundation Calendar**: https://calendar.google.com/calendar/u/0/embed?src=linuxfoundation.org_fuop4ufv766f9avc517ujs4i0g@group.calendar.google.com - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. \ No newline at end of file diff --git a/templates/minutes_base_tooling b/templates/minutes_base_tooling deleted file mode 100644 index bd1dbd9..0000000 --- a/templates/minutes_base_tooling +++ /dev/null @@ -1,28 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **tooling-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_tsc b/templates/minutes_base_tsc deleted file mode 100644 index faaeab0..0000000 --- a/templates/minutes_base_tsc +++ /dev/null @@ -1,34 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -### Announcements - -### Reminders - -* Remember to nominate people for the [contributor spotlight](https://github.com/nodejs/node/blob/main/doc/contributing/reconizing-contributors.md#bi-monthly-contributor-spotlight) - -### CPC and Board Meeting Updates - -*Extracted from **tsc-agenda** labeled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Strategic Initiatives - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_typescript b/templates/minutes_base_typescript deleted file mode 100644 index f921f8e..0000000 --- a/templates/minutes_base_typescript +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -* Extracted from **typescript-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_userfeedback b/templates/minutes_base_userfeedback deleted file mode 100644 index afc8f2a..0000000 --- a/templates/minutes_base_userfeedback +++ /dev/null @@ -1,26 +0,0 @@ -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ -* **Minutes**: $MINUTES_DOC$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **user-feedback-meeting** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_uvwasi b/templates/minutes_base_uvwasi deleted file mode 100644 index f61e7de..0000000 --- a/templates/minutes_base_uvwasi +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -*Extracted from **uvwasi-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_web b/templates/minutes_base_web deleted file mode 100644 index 00467bd..0000000 --- a/templates/minutes_base_web +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -* Extracted from **web-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/minutes_base_web-server-frameworks b/templates/minutes_base_web-server-frameworks deleted file mode 100644 index 14fa35e..0000000 --- a/templates/minutes_base_web-server-frameworks +++ /dev/null @@ -1,27 +0,0 @@ -# $TITLE$ - -## Links - -* **Recording**: -* **GitHub Issue**: $GITHUB_ISSUE$ - -## Present - -$INVITED$ -$OBSERVERS$ - -## Agenda - -## Announcements - -* Extracted from **web-server-frameworks-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. - -$AGENDA_CONTENT$ - -## Q&A, Other - -## Upcoming Meetings - -* **Node.js Project Calendar**: - -Click `Add to Google Calendar` at the bottom left to add to your own Google calendar. diff --git a/templates/observers_benchmarking b/templates/observers_benchmarking deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_build b/templates/observers_build deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_cross_project_council b/templates/observers_cross_project_council deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_diag b/templates/observers_diag deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_diag_deepdive b/templates/observers_diag_deepdive deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_ecosystem_report b/templates/observers_ecosystem_report deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_loaders b/templates/observers_loaders deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_modules b/templates/observers_modules deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_next-10 b/templates/observers_next-10 deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_outreach b/templates/observers_outreach deleted file mode 100644 index 891f3ca..0000000 --- a/templates/observers_outreach +++ /dev/null @@ -1,3 +0,0 @@ -Feel free to follow along on the YouTube live stream, or attend meeting as a guest -by calling in to Zoom, using the links below. If you will be attending as a guest, -please comment on this issue to let us know you'll be joining. diff --git a/templates/observers_package-maintenance b/templates/observers_package-maintenance deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_package_metadata_interop b/templates/observers_package_metadata_interop deleted file mode 100644 index 8b13789..0000000 --- a/templates/observers_package_metadata_interop +++ /dev/null @@ -1 +0,0 @@ - diff --git a/templates/observers_security-wg b/templates/observers_security-wg deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_security_collab b/templates/observers_security_collab deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_standards b/templates/observers_standards deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_sustainability_collab b/templates/observers_sustainability_collab deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_tooling b/templates/observers_tooling deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_tsc b/templates/observers_tsc deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_typescript b/templates/observers_typescript deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_userfeedback b/templates/observers_userfeedback deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_uvwasi b/templates/observers_uvwasi deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_web b/templates/observers_web deleted file mode 100644 index e69de29..0000000 diff --git a/templates/observers_web-server-frameworks b/templates/observers_web-server-frameworks deleted file mode 100644 index e69de29..0000000 diff --git a/test/config.test.mjs b/test/config.test.mjs deleted file mode 100644 index 6dc92a3..0000000 --- a/test/config.test.mjs +++ /dev/null @@ -1,103 +0,0 @@ -import assert from 'node:assert'; -import process from 'node:process'; -import { describe, it, beforeEach, afterEach } from 'node:test'; - -import { getConfig } from '../src/config.mjs'; - -describe('Config', () => { - let originalEnv; - let originalArgv; - - beforeEach(() => { - // Save original environment and argv - originalEnv = { ...process.env }; - originalArgv = [...process.argv]; - }); - - afterEach(() => { - // Restore original environment and argv - process.env = originalEnv; - process.argv = originalArgv; - }); - - describe('getConfig', () => { - it('should return empty meeting group when no argument provided', () => { - process.argv = ['node', 'script.mjs']; - - const config = getConfig(); - - assert.strictEqual(config.meetingGroup, undefined); - }); - - it('should use command line argument for meeting group', () => { - process.argv = ['node', 'script.mjs', 'build']; - - const config = getConfig(); - - assert.strictEqual(config.meetingGroup, 'build'); - }); - - it('should read GitHub token from environment', () => { - process.env.GITHUB_TOKEN = 'test_token'; - - const config = getConfig(); - - assert.strictEqual(config.githubToken, 'test_token'); - }); - - it('should read Google API Key config from environment', () => { - process.env.GOOGLE_API_KEY = 'test_google_api_key_123'; - - const config = getConfig(); - - assert.strictEqual(config.google.apiKey, 'test_google_api_key_123'); - }); - - it('should handle missing Google API Key gracefully', () => { - delete process.env.GOOGLE_API_KEY; - - const config = getConfig(); - - assert.strictEqual(config.google.apiKey, undefined); - }); - - it('should read HackMD config from environment', () => { - process.env.HACKMD_API_TOKEN = 'hackmd_token'; - - const config = getConfig(); - - assert.strictEqual(config.hackmd.apiToken, 'hackmd_token'); - }); - - it('should handle undefined environment variables gracefully', () => { - // Clear all relevant env vars - delete process.env.GITHUB_TOKEN; - delete process.env.HACKMD_API_TOKEN; - delete process.env.GOOGLE_CLIENT_ID; - - const config = getConfig(); - - assert.strictEqual(config.githubToken, undefined); - assert.strictEqual(config.hackmd.apiToken, undefined); - assert.strictEqual(config.google.clientId, undefined); - }); - - it('should contain all required config sections', () => { - const config = getConfig(); - - assert.ok('meetingGroup' in config); - assert.ok('githubToken' in config); - assert.ok('google' in config); - assert.ok('hackmd' in config); - assert.ok('directories' in config); - }); - - it('should contain all required directory paths', () => { - const config = getConfig(); - - assert.ok('config' in config.directories); - assert.ok('output' in config.directories); - assert.ok('templates' in config.directories); - }); - }); -}); diff --git a/test/meeting.test.mjs b/test/meeting.test.mjs deleted file mode 100644 index 9163cae..0000000 --- a/test/meeting.test.mjs +++ /dev/null @@ -1,164 +0,0 @@ -import assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import { generateMeetingTitle } from '../src/meeting.mjs'; - -describe('Meeting', () => { - describe('generateMeetingTitle', () => { - it('should generate meeting title with default values', () => { - const config = { meetingGroup: 'tsc' }; - const meetingConfig = { properties: {} }; - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual(result, 'Node.js tsc Meeting 2023-10-15'); - }); - - it('should use HOST from properties', () => { - const config = { meetingGroup: 'tsc' }; - - const meetingConfig = { - properties: { - HOST: 'OpenJS Foundation', - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual(result, 'OpenJS Foundation tsc Meeting 2023-10-15'); - }); - - it('should use GROUP_NAME from properties', () => { - const config = { meetingGroup: 'tsc' }; - - const meetingConfig = { - properties: { - GROUP_NAME: 'Technical Steering Committee', - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual( - result, - 'Node.js Technical Steering Committee Meeting 2023-10-15' - ); - }); - - it('should use both custom HOST and GROUP_NAME', () => { - const config = { meetingGroup: 'tsc' }; - - const meetingConfig = { - properties: { - HOST: 'OpenJS Foundation', - GROUP_NAME: 'Technical Steering Committee', - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual( - result, - 'OpenJS Foundation Technical Steering Committee Meeting 2023-10-15' - ); - }); - - it('should handle different date formats correctly', () => { - const config = { meetingGroup: 'build' }; - const meetingConfig = { properties: {} }; - const meetingDate = new Date('2023-12-31T23:59:59Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual(result, 'Node.js build Meeting 2023-12-31'); - }); - - it('should handle different meeting groups', () => { - const config = { meetingGroup: 'security-wg' }; - - const meetingConfig = { - properties: { - GROUP_NAME: 'Security Working Group', - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual( - result, - 'Node.js Security Working Group Meeting 2023-10-15' - ); - }); - - it('should handle edge case dates', () => { - const config = { meetingGroup: 'tsc' }; - const meetingConfig = { properties: {} }; - const meetingDate = new Date('2024-02-29T12:00:00Z'); // Leap year - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual(result, 'Node.js tsc Meeting 2024-02-29'); - }); - - it('should handle null/undefined properties gracefully', () => { - const config = { meetingGroup: 'tsc' }; - - const meetingConfig = { - properties: { - HOST: null, - GROUP_NAME: undefined, - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - // Should fall back to defaults - assert.strictEqual(result, 'Node.js tsc Meeting 2023-10-15'); - }); - - it('should handle empty string properties', () => { - const config = { meetingGroup: 'tsc' }; - - const meetingConfig = { - properties: { - HOST: '', - GROUP_NAME: '', - }, - }; - - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - // Empty strings are used as-is (nullish coalescing doesn't catch empty strings) - assert.strictEqual(result, ' Meeting 2023-10-15'); - }); - - it('should handle very long meeting group names', () => { - const config = { - meetingGroup: 'very-long-working-group-name-for-testing-purposes', - }; - - const meetingConfig = { properties: {} }; - const meetingDate = new Date('2023-10-15T14:30:00Z'); - - const result = generateMeetingTitle(config, meetingConfig, meetingDate); - - assert.strictEqual( - result, - 'Node.js very-long-working-group-name-for-testing-purposes Meeting 2023-10-15' - ); - }); - }); -}); diff --git a/test/utils/templates.test.mjs b/test/utils/templates.test.mjs deleted file mode 100644 index 7e05127..0000000 --- a/test/utils/templates.test.mjs +++ /dev/null @@ -1,118 +0,0 @@ -import assert from 'node:assert'; -import { describe, it } from 'node:test'; - -import { parseVariables } from '../../src/utils/templates.mjs'; - -describe('Utils - Templates', () => { - describe('parseVariables', () => { - it('should replace single variable in template', () => { - const template = 'Hello $NAME$, welcome!'; - const variables = { NAME: 'John' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Hello John, welcome!'); - }); - - it('should replace multiple variables in template', () => { - const template = 'Meeting: $TITLE$ on $DATE$ at $TIME$'; - const variables = { - TITLE: 'TSC Meeting', - DATE: '2023-10-15', - TIME: '14:30', - }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Meeting: TSC Meeting on 2023-10-15 at 14:30'); - }); - - it('should replace same variable multiple times', () => { - const template = "$NAME$ loves $NAME$'s work"; - const variables = { NAME: 'Alice' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, "Alice loves Alice's work"); - }); - - it('should handle empty string values', () => { - const template = 'Value: $EMPTY$'; - const variables = { EMPTY: '' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Value: '); - }); - - it('should handle null/undefined values', () => { - const template = 'Value: $NULL$ and $UNDEFINED$'; - const variables = { NULL: null, UNDEFINED: undefined }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Value: and '); - }); - - it('should remove unmatched placeholders', () => { - const template = 'Hello $NAME$, your $UNMATCHED$ is ready'; - const variables = { NAME: 'Bob' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Hello Bob, your is ready'); - }); - - it('should handle template with no placeholders', () => { - const template = 'No placeholders here'; - const variables = { NAME: 'Alice' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'No placeholders here'); - }); - - it('should handle empty template', () => { - const template = ''; - const variables = { NAME: 'Alice' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, ''); - }); - - it('should handle special characters in values', () => { - const template = 'Pattern: $PATTERN$'; - const variables = { PATTERN: '$.*+?^{}()|[]\\' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'Pattern: $.*+?^{}()|[]\\'); - }); - - it('should handle variables with underscores and numbers', () => { - const template = '$VAR_1$ and $VAR_2_TEST$'; - const variables = { VAR_1: 'first', VAR_2_TEST: 'second' }; - - const result = parseVariables(template, variables); - - assert.strictEqual(result, 'first and second'); - }); - - it('should handle multiline templates', () => { - const template = `Line 1: $VAR1$ -Line 2: $VAR2$ -Line 3: $VAR1$ again`; - const variables = { VAR1: 'Hello', VAR2: 'World' }; - - const result = parseVariables(template, variables); - - assert.strictEqual( - result, - `Line 1: Hello -Line 2: World -Line 3: Hello again` - ); - }); - }); -});