mirror of
https://github.com/wearepixel/laravel-quickbooks.git
synced 2026-11-14 22:11:50 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3ba7e82e2 | ||
|
|
c94788fdb8 | ||
|
|
3a5c51d3d0 | ||
|
|
f7d07f45e5 | ||
|
|
b4a5d00439 | ||
|
|
524a09d545 | ||
|
|
c75ab43346 | ||
|
|
32266f6dd5 |
+6
-4
@@ -3,14 +3,16 @@ root = true
|
|||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[*.yml]
|
[*.{yml,yaml}]
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[docker-compose.yml]
|
||||||
|
indent_size = 4
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
*.blade.php diff=html
|
||||||
|
*.css diff=css
|
||||||
|
*.html diff=html
|
||||||
|
*.md diff=markdown
|
||||||
|
*.php diff=php
|
||||||
|
|
||||||
|
/.github export-ignore
|
||||||
|
CHANGELOG.md export-ignore
|
||||||
|
.styleci.yml export-ignore
|
||||||
@@ -8,6 +8,7 @@ updates:
|
|||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
groups:
|
groups:
|
||||||
actions:
|
actions:
|
||||||
|
applies-to: version-updates
|
||||||
patterns: ["*"]
|
patterns: ["*"]
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "chore"
|
prefix: "chore"
|
||||||
@@ -23,9 +24,13 @@ updates:
|
|||||||
open-pull-requests-limit: 10
|
open-pull-requests-limit: 10
|
||||||
groups:
|
groups:
|
||||||
php-minor-patch:
|
php-minor-patch:
|
||||||
|
applies-to: version-updates
|
||||||
update-types:
|
update-types:
|
||||||
- "minor"
|
- "minor"
|
||||||
- "patch"
|
- "patch"
|
||||||
|
php-security:
|
||||||
|
applies-to: security-updates
|
||||||
|
patterns: ["*"]
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "chore"
|
prefix: "chore"
|
||||||
include: "scope"
|
include: "scope"
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
name: Dependabot Auto-merge
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["Tests"]
|
||||||
|
types: [completed]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
auto-merge:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
github.event.workflow_run.conclusion == 'success' &&
|
||||||
|
github.event.workflow_run.event == 'pull_request' &&
|
||||||
|
github.event.workflow_run.actor.login == 'dependabot[bot]'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Find PR and check update type
|
||||||
|
id: check
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
||||||
|
run: |
|
||||||
|
PR_DATA=$(gh pr list --repo "${{ github.repository }}" --head "$HEAD_BRANCH" --json number,title,url,author --jq '.[0]')
|
||||||
|
|
||||||
|
PR_URL=$(echo "$PR_DATA" | jq -r '.url')
|
||||||
|
PR_AUTHOR=$(echo "$PR_DATA" | jq -r '.author.login')
|
||||||
|
PR_TITLE=$(echo "$PR_DATA" | jq -r '.title')
|
||||||
|
|
||||||
|
echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
if [ "$PR_AUTHOR" != "app/dependabot" ]; then
|
||||||
|
echo "is_safe=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "Not a Dependabot PR, skipping."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse major version numbers from title: "bump X from A[.B.C] to D[.E.F]"
|
||||||
|
# Works for both "from 4.0.0 to 4.1.0" and "from 4 to 6" (GitHub Actions)
|
||||||
|
FROM_MAJOR=$(echo "$PR_TITLE" | grep -oP 'from \K[0-9]+')
|
||||||
|
TO_MAJOR=$(echo "$PR_TITLE" | grep -oP 'to \K[0-9]+')
|
||||||
|
|
||||||
|
echo "PR: $PR_TITLE (major: $FROM_MAJOR -> $TO_MAJOR)"
|
||||||
|
|
||||||
|
if [ "$FROM_MAJOR" = "$TO_MAJOR" ]; then
|
||||||
|
echo "is_safe=true" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "is_safe=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "Major version bump, skipping auto-merge."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Merge minor and patch updates
|
||||||
|
if: steps.check.outputs.is_safe == 'true'
|
||||||
|
run: gh pr merge --merge "${{ steps.check.outputs.pr_url }}"
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
name: Dependabot Slack Alert
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
notify:
|
||||||
|
name: Notify Slack of major update
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.actor == 'dependabot[bot]'
|
||||||
|
steps:
|
||||||
|
- name: Check if major version bump
|
||||||
|
id: check
|
||||||
|
env:
|
||||||
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
run: |
|
||||||
|
from_major=$(echo "$PR_TITLE" | grep -oP 'from \K[0-9]+' | head -1)
|
||||||
|
to_major=$(echo "$PR_TITLE" | grep -oP 'to \K[0-9]+' | head -1)
|
||||||
|
|
||||||
|
if [ -n "$from_major" ] && [ -n "$to_major" ] && [ "$from_major" != "$to_major" ]; then
|
||||||
|
echo "is_major=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "Major bump detected: $from_major -> $to_major"
|
||||||
|
else
|
||||||
|
echo "is_major=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "Minor/patch bump, skipping"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Send Slack alert
|
||||||
|
if: steps.check.outputs.is_major == 'true'
|
||||||
|
env:
|
||||||
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
||||||
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
REPO: ${{ github.repository }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$SLACK_WEBHOOK_URL" ]; then
|
||||||
|
echo "SLACK_WEBHOOK_URL not configured for this repo, skipping"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
payload=$(jq -n \
|
||||||
|
--arg repo "$REPO" \
|
||||||
|
--arg title "$PR_TITLE" \
|
||||||
|
--arg url "$PR_URL" \
|
||||||
|
--arg pr "#$PR_NUMBER" \
|
||||||
|
'{
|
||||||
|
blocks: [
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
text: {
|
||||||
|
type: "mrkdwn",
|
||||||
|
text: ":dependabot: *Major dependency update requires review*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
fields: [
|
||||||
|
{type: "mrkdwn", text: ("*Repository*\n`" + $repo + "`")},
|
||||||
|
{type: "mrkdwn", text: ("*Pull Request*\n<" + $url + "|" + $pr + ">") }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
text: {
|
||||||
|
type: "mrkdwn",
|
||||||
|
text: $title
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "context",
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "mrkdwn",
|
||||||
|
text: "Major version bumps are not auto-merged as they may contain breaking changes."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "actions",
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "button",
|
||||||
|
text: {type: "plain_text", text: "Review PR"},
|
||||||
|
url: $url,
|
||||||
|
style: "primary"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}')
|
||||||
|
|
||||||
|
curl -s -o /dev/null -w "%{http_code}" -X POST "$SLACK_WEBHOOK_URL" \
|
||||||
|
-H "Content-type: application/json" \
|
||||||
|
--data "$payload" | grep -q "^200$" \
|
||||||
|
&& echo "Slack notification sent" \
|
||||||
|
|| echo "Slack notification failed"
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wearepixel/laravel-quickbooks",
|
"name": "wearepixel/laravel-quickbooks",
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"description": "Laravel Client for QuickBooks.",
|
"description": "Laravel Client for QuickBooks.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"quickbooks",
|
"quickbooks",
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
"illuminate/routing": "^10.0|^11.0|^12.0",
|
"illuminate/routing": "^10.0|^11.0|^12.0",
|
||||||
"illuminate/support": "^10.0|^11.0|^12.0",
|
"illuminate/support": "^10.0|^11.0|^12.0",
|
||||||
"nesbot/carbon": "^2.62.1|^3.0",
|
"nesbot/carbon": "^2.62.1|^3.0",
|
||||||
"quickbooks/v3-php-sdk": "^5.4.6"
|
"quickbooks/v3-php-sdk": "^6.3.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"laravel/pint": "^1.2",
|
"laravel/pint": "^1.2",
|
||||||
"mockery/mockery": "^1.6",
|
"mockery/mockery": "^1.6",
|
||||||
"pestphp/pest": "^3.0",
|
"pestphp/pest": "^5.3",
|
||||||
"psy/psysh": "^0.12"
|
"psy/psysh": "^0.12"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
{
|
{
|
||||||
"preset": "laravel",
|
"preset": "laravel",
|
||||||
"rules": {
|
"rules": {
|
||||||
"no_superfluous_phpdoc_tags": true
|
"concat_space": {
|
||||||
|
"spacing": "one"
|
||||||
|
},
|
||||||
|
"class_attributes_separation": false,
|
||||||
|
"ordered_imports": {
|
||||||
|
"sort_algorithm": "length"
|
||||||
|
},
|
||||||
|
"not_operator_with_space": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-9
@@ -181,12 +181,6 @@ public function hasValidRefreshToken(): bool
|
|||||||
* 2) Have valid refresh token, so renew access token & then use
|
* 2) Have valid refresh token, so renew access token & then use
|
||||||
* 3) No existing token, so need to link account
|
* 3) No existing token, so need to link account
|
||||||
*
|
*
|
||||||
* useJson() is applied in every case: the SDK's default XML deserializer reflects
|
|
||||||
* declared properties on its Data classes and throws when QuickBooks adds a new
|
|
||||||
* response field the installed SDK version doesn't know about yet. The JSON
|
|
||||||
* deserializer builds instances from the class's own properties and silently
|
|
||||||
* ignores unrecognised keys instead, so it tolerates QuickBooks-side schema drift.
|
|
||||||
*
|
|
||||||
* @throws SdkException
|
* @throws SdkException
|
||||||
* @throws ServiceException
|
* @throws ServiceException
|
||||||
*/
|
*/
|
||||||
@@ -209,7 +203,7 @@ protected function makeDataService(): DataService
|
|||||||
'QBORealmID' => $this->token->realm_id,
|
'QBORealmID' => $this->token->realm_id,
|
||||||
'refreshTokenKey' => $this->token->refresh_token,
|
'refreshTokenKey' => $this->token->refresh_token,
|
||||||
]),
|
]),
|
||||||
)->useJson();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have refresh, so update access & allow app to run
|
// Have refresh, so update access & allow app to run
|
||||||
@@ -220,7 +214,7 @@ protected function makeDataService(): DataService
|
|||||||
'QBORealmID' => $this->token->realm_id,
|
'QBORealmID' => $this->token->realm_id,
|
||||||
'refreshTokenKey' => $this->token->refresh_token,
|
'refreshTokenKey' => $this->token->refresh_token,
|
||||||
]),
|
]),
|
||||||
)->useJson();
|
);
|
||||||
|
|
||||||
$oauth_token = $data_service->getOAuth2LoginHelper()->refreshToken();
|
$oauth_token = $data_service->getOAuth2LoginHelper()->refreshToken();
|
||||||
|
|
||||||
@@ -232,7 +226,7 @@ protected function makeDataService(): DataService
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create new...
|
// Create new...
|
||||||
return DataService::Configure($this->parseDataConfigs())->useJson();
|
return DataService::Configure($this->parseDataConfigs());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use QuickBooksOnline\API\Core\Http\Serialization\SerializationFormat;
|
|
||||||
use QuickBooksOnline\API\DataService\DataService;
|
use QuickBooksOnline\API\DataService\DataService;
|
||||||
use QuickBooksOnline\API\Exception\ServiceException;
|
use QuickBooksOnline\API\Exception\ServiceException;
|
||||||
use Wearepixel\QuickBooks\Client;
|
use Wearepixel\QuickBooks\Client;
|
||||||
@@ -131,27 +130,6 @@
|
|||||||
it('returns a report service using the data service')
|
it('returns a report service using the data service')
|
||||||
->skip('Once we figure out how to test around the static DataService::Configure');
|
->skip('Once we figure out how to test around the static DataService::Configure');
|
||||||
|
|
||||||
it('configures the data service to use JSON serialization so unrecognised QuickBooks response fields do not throw', function () {
|
|
||||||
$this->token_mock
|
|
||||||
->shouldReceive('getAttribute')
|
|
||||||
->twice()
|
|
||||||
->with('hasValidAccessToken')
|
|
||||||
->andReturnFalse();
|
|
||||||
|
|
||||||
$this->token_mock
|
|
||||||
->shouldReceive('getAttribute')
|
|
||||||
->once()
|
|
||||||
->with('hasValidRefreshToken')
|
|
||||||
->andReturnFalse();
|
|
||||||
|
|
||||||
$format = $this->client
|
|
||||||
->getDataService()
|
|
||||||
->getServiceContext()
|
|
||||||
->IppConfiguration->Message->Request->SerializationFormat;
|
|
||||||
|
|
||||||
expect($format)->toBe(SerializationFormat::Json);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has logging off by default')
|
it('has logging off by default')
|
||||||
->skip('Have to figure out how to test this with the new code in 5.x');
|
->skip('Have to figure out how to test this with the new code in 5.x');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user