Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/pubspec.yaml @uxcam/maintainers
/.github/ @uxcam/maintainers @uxcam/security-team
/.github/workflows/ @uxcam/maintainers @uxcam/security-team
217 changes: 132 additions & 85 deletions .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,106 +1,153 @@
name: Publish Flutter Package

on:
workflow_dispatch:
inputs:
publish:
description: Publish flutter package
description: Publish flutter package to pub.dev
type: boolean
default: false
required: true

permissions: {}

concurrency:
group: publish-${{ github.ref }}
cancel-in-progress: false

jobs:
job_release:
runs-on: ubuntu-latest
name: 'Release a new version'
validate:
name: Validate package
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Check out current commit (${{github.sha}})
uses: actions/checkout@v3
- name: Harden runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
token: ${{ secrets.GH_RELEASE_PAT }}
fetch-depth: 0
- name: Set git user credentials
run: |
git config user.email "uxcam-mobile@uxcam.com"
git config user.name "UXCam"
- name: Get version name
id: get-version
run: |
version=$(grep '^version:' pubspec.yaml | awk '{ print $2 }')
echo $version
echo "version=$version" >> $GITHUB_OUTPUT
# Install dependencies
egress-policy: audit
disable-sudo: true

- name: Check out ${{ github.sha }}
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: Install Flutter 🎯
uses: subosito/flutter-action@v2
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: 'stable'
channel: stable

- name: Install dependencies 📚
run: |
flutter pub get
run: flutter pub get

- name: Verify version
run: |
dart pub publish --dry-run
- name: Publish package
if: ${{ inputs.publish }}
- name: Read package version
id: version
run: |
mkdir -p $HOME/.config/dart
CREDENTIALS="${{ secrets.PUB_CREDENTIALS }}"
CREDENTIALS=$( echo -n $CREDENTIALS | base64 --decode)
cat <<EOF > $HOME/.config/dart/pub-credentials.json
$CREDENTIALS
EOF
dart pub publish -f
- name: Add new tag to github
if: ${{ inputs.publish }}
run: |
version="v${{ steps.get-version.outputs.version }}"
git tag -a $version -m "Release: $version"
git push origin --tags
- name: Generate Changelogs
id: changelogs
version="$(grep '^version:' pubspec.yaml | awk '{ print $2 }')"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Resolved version: v$version"

- name: Verify package (dry run)
run: dart pub publish --dry-run

publish:
name: Publish to pub.dev
needs: validate
if: ${{ inputs.publish }}
runs-on: ubuntu-24.04
timeout-minutes: 20
environment: "pub.dev"
permissions:
contents: write # create tag + GitHub Release
id-token: write # pub.dev OIDC publishing
steps:
- name: Harden runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-sudo: true

- name: Check out ${{ github.sha }}
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-depth: 0
persist-credentials: false

- name: Install Flutter 🎯
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
with:
channel: stable

- name: Install dependencies 📚
run: flutter pub get

- name: Publish to pub.dev 🚀
run: dart pub publish --force

- name: Generate changelog
id: changelog
run: |
if ${{ inputs.publish }}; then
current_tag=$(git describe --tags --abbrev=0)
else
current_tag=HEAD
fi

previous_tag=$(git describe --tags --abbrev=0 ${current_tag}^)
logs=$(git log ${current_tag}...${previous_tag} --pretty=format:"%s" -i --grep="^feat.*:" --grep="^fix.*:" --no-merges)

#santize commit logs
logs=$(awk -F ":" '{ print $2 }' <<< $logs | sed -e 's/^ *//g' | sed -e 's/^./\u&/g')

#prepend line number
logs=$(awk '{print NR, "-", $0}' <<< $logs)

# Remove new line in multiline change logs as sed doesn't support it
logs=$((sed -e '$ ! s/$/\\n/g' | tr -d '\n') <<< $logs)
echo "logs=${logs}" >> $GITHUB_OUTPUT
echo $logs
#save logs to new file
touch changelog.txt
echo "$logs" > changelog.txt

- name: Generate Slack notification payload
id: slack-payload
previous_tag="$(git describe --tags --abbrev=0 2>/dev/null || echo '')"
range="HEAD"
[ -n "$previous_tag" ] && range="${previous_tag}..HEAD"

logs="$(git log "$range" --no-merges --pretty=format:'%s' -i \
--grep='^feat.*:' --grep='^fix.*:' \
| awk -F ':' '{ sub(/^ */, "", $2); print "- " $2 }')"

{
echo "logs<<CHANGELOG_EOF"
echo "$logs"
echo "CHANGELOG_EOF"
} >> "$GITHUB_OUTPUT"
echo "$logs"

- name: Create tag and GitHub Release
id: release
env:
VERSION: ${{ needs.validate.outputs.version }}
BODY: ${{ steps.changelog.outputs.logs }}
GH_TOKEN: ${{ github.token }}
run: |
DATE=$(date +'%d/%m/%Y')
ESCAPED_DATE=$(echo "$DATE" | sed -e 's/[\/&]/\\&/g')
payload_path='./.github/workflows/slack-payload.json'
payload=$(cat $payload_path)
logs="${{ steps.changelogs.outputs.logs }}"
logs=$(sed -e 's/\\n/\\\\n/g' <<< $logs)
echo $logs

echo "$payload" | sed -e "s/__FLUTTER_VERSION__/${{ steps.get-version.outputs.version }}/g" -e "s/__RELEASE_DATE__/${ESCAPED_DATE}/g" -e "s/__CHANGELOG__/$logs/g" > $payload_path
cat $payload_path
- name: Send notification to Slack
id: slack
uses: slackapi/slack-github-action@v1.18.0
with:
payload-file-path: './.github/workflows/slack-payload.json'
url="$(gh release create "v$VERSION" \
--target "$GITHUB_SHA" \
--title "v$VERSION" \
--notes "$BODY" \
--latest)"
echo "url=$url" >> "$GITHUB_OUTPUT"

- name: Notify Slack
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
PKG_VERSION: v${{ needs.validate.outputs.version }}
CHANGELOG: ${{ steps.changelog.outputs.logs }}
RELEASE_URL: ${{ steps.release.outputs.url }}
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload-templated: true
payload: |
text: ":rocket: UXCam Flutter Plugin {{ env.PKG_VERSION }} released :rocket:"
blocks:
- type: section
text:
type: mrkdwn
text: "<!here> UXCam Flutter Plugin *{{ env.PKG_VERSION }}* has been released. :rocket:"
- type: section
fields:
- type: mrkdwn
text: "*SDK*\nFlutter Plugin"
- type: mrkdwn
text: "*Version*\n{{ env.PKG_VERSION }}"
- type: section
text:
type: mrkdwn
text: "*CHANGELOG (Internal):*\n{{ env.CHANGELOG }}"
- type: section
text:
type: mrkdwn
text: "<{{ env.RELEASE_URL }}|View release notes>"
34 changes: 0 additions & 34 deletions .github/workflows/slack-payload.json

This file was deleted.

45 changes: 45 additions & 0 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: GitHub Actions security audit (zizmor)

on:
push:
branches: [main]
paths:
- ".github/workflows/**"
- ".github/actions/**"
pull_request:
paths:
- ".github/workflows/**"
- ".github/actions/**"
workflow_dispatch: {}

permissions: {}

concurrency:
group: zizmor-${{ github.ref }}
cancel-in-progress: true

jobs:
zizmor:
name: Audit workflows
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
security-events: write
actions: read
steps:
- name: Harden runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
disable-sudo: true

- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: Run zizmor
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
with:
advanced-security: true
47 changes: 25 additions & 22 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
Copyright (c) 2019-2024, UXCam. All rights reserved.
BSD 3-Clause License

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Copyright (c) UXCam

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13 changes: 13 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Security Policy

We welcome reports from security researchers, and we'll work with you to confirm and fix any issue you find.

## Reporting a vulnerability

Please don't report security issues through public GitHub issues, pull requests or discussions. Anyone can see them, and we don't want a security issue to become public before we have fixed it. Please use one of the private channels below instead.

Our preferred channel is the bug bounty program at https://uxcam.com/bug-bounty, where you'll find our scope, rules, and how to submit a report.

If you'd rather not use the program, you're welcome to email us at security@uxcam.com. For sensitive details, you can encrypt your report with our PGP key: https://github.com/uxcamsec.gpg

Reports submitted through the bug bounty program are eligible for a reward and a place in our Hall of Fame: https://uxcam.com/bug-bounty-hall-of-fame