Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
7149320
new assign syntax
Slashek Feb 24, 2026
c9c012c
Module fixes
wgrzeszczak Mar 3, 2026
4c3e761
Refactor lint workflow to use pos-cli check command
rafal-k Mar 9, 2026
c6f1ace
Configure lint workflow for manual testing with single module
rafal-k Mar 9, 2026
4639952
Wrap matrix module value in array brackets for valid YAML syntax
rafal-k Mar 9, 2026
ba8946c
fix: add pos-module- prefix to check command module path
rafal-k Mar 9, 2026
6f240ef
Update summary generation for new pos-cli check JSON format
rafal-k Mar 9, 2026
adb488a
fix: capture and use pos-cli check exit code to properly fail workflo…
rafal-k Mar 9, 2026
e4033ed
Re-enable automatic triggers and dynamic module detection in lint wor…
rafal-k Mar 9, 2026
0916376
Add manual module selection for lint workflow
rafal-k Mar 9, 2026
7b2df9e
Add custom run names to lint workflow for better identification
rafal-k Mar 9, 2026
56ccf7b
fix: add parentheses to run-name expression for proper precedence
rafal-k Mar 9, 2026
4cb35ca
fix: remove # character from run-name expression to fix YAML syntax e…
rafal-k Mar 9, 2026
84f3dbb
fix: simplify run-name expression to resolve YAML syntax error
rafal-k Mar 9, 2026
c9080be
Replace flat offense table with structured format grouped by file.
rafal-k Mar 9, 2026
99f4016
Show commit message for automatic lint triggers, module name for manual
rafal-k Mar 9, 2026
d0889b1
fix: respect should_skip in run-linter to prevent empty JSON parse error
rafal-k Mar 9, 2026
4340a6b
fix: prevent duplicate workflow runs on PR push events
rafal-k Mar 9, 2026
c383dc3
Revert "fix: prevent duplicate workflow runs on PR push events"
rafal-k Mar 9, 2026
cf0ad3a
Use whitespace fallback for default run-name on automatic triggers
rafal-k Mar 9, 2026
fc9b82c
Merge pull request #3 from Platform-OS/pos-cli-check-as-linter
Slashek Mar 10, 2026
41770f9
update fetch to dig
Slashek Mar 10, 2026
9f331fc
Bug fixes
wgrzeszczak Mar 10, 2026
ba928d3
Install modules before running pos-cli check
rafal-k Mar 10, 2026
60397f4
Create app/ directory before installing modules
rafal-k Mar 10, 2026
98d9798
Add -p flag so mkdir doesn't throw when app directory exists
rafal-k Mar 10, 2026
0439868
Module version bump
wgrzeszczak Mar 10, 2026
d6ebfb7
Merge branch 'new-syntax-for-modules' of github.com:Platform-OS/pos-m…
wgrzeszczak Mar 10, 2026
d14938b
feat: improve lint summary readability for large codebases
rafal-k Mar 10, 2026
ed1ebad
Module versions
wgrzeszczak Mar 11, 2026
a08bf74
Version
wgrzeszczak Mar 11, 2026
308a2cc
Cleanup
wgrzeszczak Mar 11, 2026
e42f75c
Cleanup
wgrzeszczak Mar 11, 2026
604d734
Cleanup
wgrzeszczak Mar 11, 2026
80d8ab4
Cleanup
wgrzeszczak Mar 12, 2026
8928333
Cleanup core module
wgrzeszczak Mar 13, 2026
ecdb93c
Core module bump in user
wgrzeszczak Mar 13, 2026
c6a91cb
Cleanup
wgrzeszczak Mar 13, 2026
f49e830
Fix linter errors
wgrzeszczak Mar 13, 2026
5566009
oauth-github
wgrzeszczak Mar 13, 2026
4d3ec19
oauth modules
wgrzeszczak Mar 13, 2026
f4ed2df
Tests module cleanup
wgrzeszczak Mar 16, 2026
0e249ee
Tests module cleanup
wgrzeszczak Mar 16, 2026
789426d
Cleanup common-styling
wgrzeszczak Mar 16, 2026
0d3a1fa
Versions
wgrzeszczak Mar 16, 2026
f0155d9
User module cleanup
wgrzeszczak Mar 16, 2026
56e9d5f
Fix user module
wgrzeszczak Mar 17, 2026
2edd6e3
Remove TestCafe, as it's no longer in use
rafal-k Mar 17, 2026
11d1ad0
chore: add Playwright as devDependency and auto-install browsers via …
rafal-k Mar 17, 2026
eb452f6
fix: correct password validation assertions in E2E tests
rafal-k Mar 17, 2026
78728f5
Fix style-guide Playwright test failures
rafal-k Mar 17, 2026
98e5f6e
openai module
wgrzeszczak Mar 18, 2026
3265485
Merge branch 'new-syntax-for-modules' of github.com:Platform-OS/pos-m…
wgrzeszczak Mar 18, 2026
31f4bf3
Docs for reports module
wgrzeszczak Mar 19, 2026
5629963
Report module version
wgrzeszczak Mar 24, 2026
7c2b457
Merge branch 'master' into new-syntax-for-modules
wgrzeszczak Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
171 changes: 131 additions & 40 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name: Lint modules
run-name: ${{ inputs.module && format('Lint {0}', inputs.module) || ' ' }}

on:
pull_request:
Expand All @@ -9,6 +10,26 @@ on:
paths-ignore:
- "**/README.md"
workflow_dispatch:
inputs:
module:
description: 'Module to lint (e.g., common-styling, user, chat)'
required: true
type: choice
options:
- chat
- common-styling
- core
- data-export-api
- oauth-facebook
- oauth-github
- oauth-google
- openai
- payments
- payments-example-gateway
- payments-stripe
- reports
- tests
- user

jobs:
pre_job:
Expand All @@ -25,7 +46,7 @@ jobs:

detect-changes:
needs: pre_job
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
if: ${{ github.event_name != 'workflow_dispatch' && needs.pre_job.outputs.should_skip != 'true' }}
runs-on: ubuntu-latest
outputs:
changed-modules: ${{ steps.set-matrix.outputs.matrix }}
Expand Down Expand Up @@ -74,63 +95,66 @@ jobs:
echo "matrix=$modules" >> $GITHUB_OUTPUT
echo "Changed modules for linting: $modules"

lint-platformos-check:
needs: detect-changes
if: needs.detect-changes.outputs.changed-modules != '[]'
run-linter:
needs: [pre_job, detect-changes]
if: |
always() &&
needs.pre_job.outputs.should_skip != 'true' &&
(github.event_name == 'workflow_dispatch' ||
needs.detect-changes.outputs.changed-modules != '[]')
runs-on: ubuntu-latest
strategy:
matrix:
module: ${{ fromJSON(needs.detect-changes.outputs.changed-modules) }}
module: ${{ github.event_name == 'workflow_dispatch' && fromJSON(format('["{0}"]', inputs.module)) || fromJSON(needs.detect-changes.outputs.changed-modules) }}
fail-fast: false
env:
CI: true
PLATFORMOS_CHECK_DEBUG: true
DOCKER_WORKSPACE: ${{ github.workspace }}/pos-module-${{ matrix.module }}
LOGS_DIR: ${{ github.workspace }}/pos-module-${{ matrix.module }}/logs
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '22'

- name: Install pos-cli
id: install_pos_cli
run: npm install -g @platformos/pos-cli@latest

- name: Set up logs directory
if: steps.install_pos_cli.outcome == 'success'
run: |
mkdir -p ${{ env.LOGS_DIR }}
chmod -R 777 ${{ env.LOGS_DIR }}

- name: Start PlatformOS LSP
id: start_lsp
- name: Install modules
if: steps.install_pos_cli.outcome == 'success'
run: |
docker run -i \
-v ${{ env.DOCKER_WORKSPACE }}:${{ env.DOCKER_WORKSPACE }} \
-w ${{ env.DOCKER_WORKSPACE }} \
-e PLATFORMOS_CHECK_DEBUG=${{ env.PLATFORMOS_CHECK_DEBUG }} \
-e PLATFORMOS_CHECK_DEBUG_LOG_FILE=${{ env.LOGS_DIR }}/platformos-lsp.log \
platformos/platformos-lsp:latest

- name: Run platformos-check
if: steps.start_lsp.outcome == 'success'
cd pos-module-${{ matrix.module }}
mkdir -p app
pos-cli modules install

- name: Run pos-cli check
if: steps.install_pos_cli.outcome == 'success'
id: run_check
run: |
set +e # Disable exit on error
docker run -i \
-v ${{ env.DOCKER_WORKSPACE }}:${{ env.DOCKER_WORKSPACE }} \
-w ${{ env.DOCKER_WORKSPACE }} \
-e PLATFORMOS_CHECK_DEBUG=${{ env.PLATFORMOS_CHECK_DEBUG }} \
-e PLATFORMOS_CHECK_DEBUG_LOG_FILE=${{ env.LOGS_DIR }}/platformos-check.log \
platformos/platformos-check:latest -o json > ${{ env.LOGS_DIR }}/platformos-check-raw.json
docker_exit_code=$?
pos-cli check run pos-module-${{ matrix.module }} -f json > ${{ env.LOGS_DIR }}/platformos-check-raw.json
check_exit_code=$? # Capture the exit code
set -e # Re-enable exit on error

jq . ${{ env.LOGS_DIR }}/platformos-check-raw.json | tee ${{ env.LOGS_DIR }}/platformos-check.json

exit $docker_exit_code
exit $check_exit_code

- name: Upload logs
if: always() && steps.run_check.outcome != 'skipped'
uses: actions/upload-artifact@v4
with:
name: platformos_check_logs_${{ matrix.module }}_${{ github.run_id }}
path: |
${{ env.LOGS_DIR }}/platformos-lsp.log
${{ env.LOGS_DIR }}/platformos-check.json
${{ env.LOGS_DIR }}/platformos-check-raw.json

Expand All @@ -142,19 +166,86 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY

if [ -f "${{ env.LOGS_DIR }}/platformos-check.json" ]; then
echo "## Issues Found" >> $GITHUB_STEP_SUMMARY
echo "| File | Line | Column | Severity | Check | Message |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|--------|----------|-------|---------|" >> $GITHUB_STEP_SUMMARY

# Try to parse and add issues
if jq -r '.[] | .path as $file | .offenses[] | "| \($file) | \(.start_row) | \(.start_column) | \(.severity) | \(.check) | \(.message) |"' ${{ env.LOGS_DIR }}/platformos-check.json >> $GITHUB_STEP_SUMMARY 2>&1; then
echo "Issues table generated successfully"
else
echo "| N/A | N/A | N/A | N/A | N/A | Failed to parse JSON - see logs for details |" >> $GITHUB_STEP_SUMMARY
echo "JSON parse error. File contents:" >> $GITHUB_STEP_SUMMARY
echo '```json' >> $GITHUB_STEP_SUMMARY
cat ${{ env.LOGS_DIR }}/platformos-check.json >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
JSON="${{ env.LOGS_DIR }}/platformos-check.json"

# Summary statistics
echo "## Summary" >> $GITHUB_STEP_SUMMARY
echo "| Metric | Count |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
jq -r '"| Total Offenses | \(.offenseCount) |", "| Files with Issues | \(.fileCount) |", "| Errors | \(.errorCount) |", "| Warnings | \(.warningCount) |", "| Info | \(.infoCount) |"' "$JSON" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# Offenses by check type
echo "## Offenses by Check Type" >> $GITHUB_STEP_SUMMARY
echo "| Check | Total | Errors | Warnings |" >> $GITHUB_STEP_SUMMARY
echo "|-------|-------|--------|----------|" >> $GITHUB_STEP_SUMMARY
jq -r '
[.files[].offenses[]] | group_by(.check)
| map({
check: .[0].check,
total: length,
errors: map(select(.severity == "error")) | length,
warnings: map(select(.severity == "warning")) | length
})
| sort_by(-.total)
| .[]
| "| `\(.check)` | \(.total) | \(.errors) | \(.warnings) |"
' "$JSON" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# Errors section — full detail for files with errors
ERROR_FILE_COUNT=$(jq '[.files[] | select(.errorCount > 0)] | length' "$JSON")
if [ "$ERROR_FILE_COUNT" -gt 0 ]; then
echo "## Errors ($ERROR_FILE_COUNT files)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
jq -r '
[.files[] | select(.errorCount > 0)]
| sort_by(-.errorCount)
| .[]
| "### \u274c `\(.path)`",
"",
"**Errors:** \(.errorCount) | **Warnings:** \(.warningCount)",
"",
"| Line | Col | Severity | Check | Message |",
"|------|-----|----------|-------|---------|",
(.offenses | sort_by(
(if .severity == "error" then 0 elif .severity == "warning" then 1 else 2 end),
.start_row
) | .[] | "| \(.start_row) | \(.start_column) | \(.severity) | `\(.check)` | \(.message | gsub("\n"; " ")) |"),
""
' "$JSON" >> $GITHUB_STEP_SUMMARY
fi

# Warnings section — collapsed, only top files shown
WARNING_ONLY_COUNT=$(jq '[.files[] | select(.errorCount == 0 and .warningCount > 0)] | length' "$JSON")
if [ "$WARNING_ONLY_COUNT" -gt 0 ]; then
TOTAL_WARNINGS=$(jq '.warningCount' "$JSON")
echo "<details>" >> $GITHUB_STEP_SUMMARY
echo "<summary>## Warnings — ${TOTAL_WARNINGS} across ${WARNING_ONLY_COUNT} files (click to expand)</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# Show top 20 files by warning count
jq -r '
[.files[] | select(.errorCount == 0 and .warningCount > 0)]
| sort_by(-.warningCount)
| .[:20]
| .[]
| "### \u26a0\ufe0f `\(.path)` — \(.warningCount) warnings",
"",
"| Line | Col | Check | Message |",
"|------|-----|-------|---------|",
(.offenses | sort_by(.start_row)
| .[] | "| \(.start_row) | \(.start_column) | `\(.check)` | \(.message | gsub("\n"; " ")) |"),
""
' "$JSON" >> $GITHUB_STEP_SUMMARY

REMAINING=$((WARNING_ONLY_COUNT - 20))
if [ "$REMAINING" -gt 0 ]; then
echo "...and ${REMAINING} more files with warnings only." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi

echo "</details>" >> $GITHUB_STEP_SUMMARY
fi
else
echo "## No output file found" >> $GITHUB_STEP_SUMMARY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
assign last_message = g.messages.results.first

if last_message.id == message.id
assign event_object = null | hash_merge: message_id: message.id, app_host: app_host
assign event_object = {"message_id": message.id, "app_host": app_host}

function _ = 'modules/core/commands/events/publish', type: 'message_notification_to_send', object: event_object
endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
app_host
---
{% liquid
assign c = '{ "errors": {}, "valid": true }' | parse_json
assign c = { "errors": {}, "valid": true }

function c = 'modules/core/validations/presence', c: c, object: event, field_name: 'message_id'
function c = 'modules/core/validations/presence', c: c, object: event, field_name: 'app_host'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ metadata:
app_host
---
{% liquid
assign c = '{ "errors": {}, "valid": true }' | parse_json
assign c = { "errors": {}, "valid": true }

function c = 'modules/core/validations/presence', c: c, object: event, field_name: 'message_id'
function c = 'modules/core/validations/presence', c: c, object: event, field_name: 'app_host'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ slug: inbox
if context.params.to_uuid != blank
function record = 'modules/chat/lib/queries/records/find_by_uuid', uuid: context.params['to_uuid']
endif
assign object = null | hash_merge: to_id: record.id, conversation_id: context.params['conversation_id']
assign object = {"to_id": record.id, "conversation_id": context.params['conversation_id']}
if record or context.params.conversation_id
function current_conversation = 'modules/chat/lib/commands/conversations/find_or_create', object: object, current_profile: current_profile
endif
Expand All @@ -33,7 +33,7 @@ slug: inbox
if conversations.total_entries > 0
if current_conversation and current_conversation.participants == blank
graphql participants = 'modules/user/profiles/search', ids: current_conversation.participant_ids
hash_assign current_conversation['participants'] = participants.records.results
assign current_conversation.participants = participants.records.results
endif

render 'modules/chat/inbox', current_conversation: current_conversation, conversations: conversations, current_profile: current_profile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
function conversation = 'modules/chat/lib/queries/conversations/find_by_participant', id: room_id, participant_id: current_profile.id, include_messages: null
if conversation
assign message_safe = context.params.message | raw_escape_string
assign object = '{}' | parse_json
hash_assign object['conversation_id'] = conversation.id
hash_assign object['autor_id'] = current_profile.id
hash_assign object['message'] = message_safe
assign object = { "conversation_id": conversation.id, "autor_id": current_profile.id, "message": message_safe }
function message = 'modules/chat/lib/commands/messages/create', object: object
if message.valid != true
log message, 'ERROR receive message'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<script type="module" defer src="{{ 'modules/chat/js/pos-chat.js' | asset_url }}"></script>

<!-- message templates -->
{% assign dummy_message = '{ "message": "", "created_at": null }' | parse_json %}
{% assign dummy_message = { "message": "", "created_at": null } %}
<template id="pos-chat-template-message-received">
{% render 'modules/chat/message', message: dummy_message, authored: false, timezone: null %}
</template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{% liquid
assign data = '{}' | parse_json
hash_assign data['participant_ids'] = object.participant_ids
hash_assign data['participant_read_ids'] = current_profile.id
assign data = { "participant_ids": object.participant_ids, "participant_read_ids": current_profile.id }

return data
%}
%}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{% liquid
assign c = '{ "errors": {}, "valid": true }' | parse_json
assign c = { "errors": {}, "valid": true }

function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'participant_ids'
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'participant_ids', minimum: 2, allow_blank: null
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'participant_read_ids'

hash_assign object['valid'] = c.valid
hash_assign object['errors'] = c.errors
assign object.valid = c.valid
assign object.errors = c.errors

return object
%}
%}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
function conversation = 'modules/chat/lib/queries/conversations/find_by_participants', participant_ids: object.participant_ids, include_messages: true
unless conversation
function conversation = 'modules/chat/lib/commands/conversations/create', object: object, current_profile: current_profile
hash_assign conversation['created'] = true
assign conversation.created = true
endunless
endif

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{% liquid
assign participants = '[]' | parse_json | add_to_array: current_profile.id | add_to_array: object['to_id'] | uniq | compact | sort
assign data = '{}' | parse_json
hash_assign data['participant_ids'] = participants
hash_assign data['conversation_id'] = object.conversation_id
assign participants = [current_profile.id, object.to_id] | uniq | compact | sort
assign data = { "participant_ids": participants, "conversation_id": object.conversation_id }

return data
%}
%}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

assign types = object.participants | map: 'type' | uniq
if types.size == 1 and types.first == 'profile'
hash_assign object['valid'] = false
assign object.valid = false
endif
endcomment

return object
%}
%}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
{% liquid
assign data = '{}' | parse_json
hash_assign data['id'] = conversation.id
hash_assign data['participant_read_ids'] = conversation.participant_read_ids
hash_assign data['participant_id'] = participant_id
assign data = { "id": conversation.id, "participant_read_ids": conversation.participant_read_ids, "participant_id": participant_id }

return data
%}
%}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{% liquid
assign c = '{ "errors": {}, "valid": true }' | parse_json
assign c = { "errors": {}, "valid": true }

function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'id'
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'participant_id'

hash_assign object['valid'] = c.valid
hash_assign object['errors'] = c.errors
assign object.valid = c.valid
assign object.errors = c.errors

return object
%}
%}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{% liquid
assign data = '{}' | parse_json
hash_assign data['id'] = conversation.id
hash_assign data['participant_read_ids'] = current_profile.id
assign data = { "id": conversation.id, "participant_read_ids": current_profile.id }

return data
%}
%}
Loading
Loading