Skip to content

Commit

Permalink
Merge pull request #129 from getBoolean/main
Browse files Browse the repository at this point in the history
Sync with main
  • Loading branch information
getBoolean committed Jan 16, 2024
2 parents 4ff6b7c + ae03036 commit 824809d
Show file tree
Hide file tree
Showing 13 changed files with 278 additions and 190 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/auto_dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Automate Dependabot
on: pull_request

permissions:
contents: write
pull-requests: write

jobs:
dependabot:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Fetch Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v1
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Approve PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
GH_TOKEN: ${{secrets.PAT}}
10 changes: 4 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@ name: CI
on:
push:
branches:
- main
- release/**
- feature/**
- fix/**
- chore/**
- dependabot/**
- '**'
- '!gh-pages'

env:
FLUTTER_CHANNEL: "stable"
Expand Down Expand Up @@ -434,6 +430,8 @@ jobs:
- name: Deploy to GitHub Pages 🚀
uses: JamesIves/github-pages-deploy-action@releases/v4
with:
# PAT required to trigger gh_pages_readme.yml workflow
token: ${{ secrets.PAT }}
branch: gh-pages # The branch the action should deploy to.
folder: build/web # The folder the action should deploy.
target-folder: "${{ steps.branch-name.outputs.current_branch }}"
19 changes: 15 additions & 4 deletions .github/workflows/gh_pages_cleanup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
with:
lfs: true
ref: gh-pages
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v8
Expand All @@ -26,7 +28,16 @@ jobs:
BASE_REF=$(printf "%q" "${{ github.event.ref }}")
BASE_REF=${BASE_REF/refs\/heads\/}
echo "Deleting folder: $BASE_REF"
git rm -rf $BASE_REF
git commit -m "Remove deleted branch"
git push
if test -d "$BASE_REF"; then
echo "Deleting folder: $BASE_REF"
git rm -rf "$BASE_REF"
git commit -m "Remove deleted branch"
else
echo "Folder $BASE_REF does not exist"
fi
- name: Push changes
uses: ad-m/github-push-action@v0.8.0
with:
# PAT required to trigger gh_pages_readme.yml workflow
github_token: ${{ secrets.PAT }}
branch: gh-pages
7 changes: 2 additions & 5 deletions .github/workflows/gh_pages_readme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ jobs:
run: |
echo "## Flutter Branch Web Previews" >> README.md
echo "" >> README.md
git branch -r | grep -v '\->' | grep -v 'origin/gh-pages' | while read remote; do
if [ -d "${remote#origin/}" ]; then
echo "- [${remote#origin/}](./${remote#origin/}/)" >> README.md
fi
done
git branch -r | grep -v '\->' | grep -v 'origin/gh-pages' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
for branch in `git branch -r | grep -v '\->' | grep -v 'origin/gh-pages'`; do echo "- [${branch#origin/}](./${branch#origin/}/)" >> README.md; done
- name: Commit and push if changed
run: |
git config --global user.name 'GitHub Actions'
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,19 @@ I highly recommend reading the article. Each `layer` has its own folder per feat
Flutter Web is deployed to GitHub Pages in a separate subfolder for each branch. The `main` branch is deployed to
[getboolean.github.io/flutter_boolean_template](https://getboolean.github.io/flutter_boolean_template).

- Currently Navigator 2.0 routes do not play well with this setup. Sub-paths break GitHub Page's ability to find which
branch application to use, they must be removed from the URL before a refresh. Consider using only path parameters
instead of sub-paths if this functionality is important.
- This GitHub Pages setup requires the Flutter `#` from [HashUrlStrategy](https://api.flutter.dev/flutter/package-flutter_web_plugins_url_strategy/HashUrlStrategy-class.html), so ensure it is not disabled for your Flutter Web CI builds deployed to GitHub Pages. If it is disabled, the Navigator 2.0 subroutes will prevent GitHub Pages from resolving the correct app when refreshed.

For example, in the CI workflow using the argument `--dart-define ENABLE_HASH_URL_STRATEGY=true`

```dart
void main() {
final useHashUrlStrategy = Platform.environment['ENABLE_HASH_URL_STRATEGY'] ?? false;
if (!useHashUrlStrategy) {
setUrlStrategy();
}
runApp(MyApp());
}
```

## Template: Getting Started

Expand Down
94 changes: 65 additions & 29 deletions docs/CI.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/icn9uo2knig43ifys7in.png)
# Flutter Web Branch Previews: Deploying Each Branch to GitHub Pages

*The generated index file is pretty barebones, but it gets the job done*

It's common for Flutter apps to include a web demo for the `main` branch hosted on Github Pages, but this can also be done for every branch in your repo. This allows any branch to be previewed and makes reviewing Pull Requests much more convenient with a live preview available.
It's common for Flutter apps to include a web demo for the `main` branch hosted on Github Pages, but this can also be done for every branch in your repo. This allows any branch to be previewed and makes reviewing Pull Requests much more convenient with a live preview available. I previously used a slightly different version of this for a Godot 3 team project and all the team members really appreciated the web branch previews when doing code review.

This involves three workflow files: deploying the Flutter Web app, generating an index file, and cleaning up deleted branches.

* Live Demo: [getboolean.github.io/flutter_boolean_template](https://getboolean.github.io/flutter_boolean_template)
* Live Demo: [getboolean.github.io/flutter_deploy_branch_demo](https://getboolean.github.io/flutter_deploy_branch_demo)

## Prerequisites

This GitHub Pages setup requires the Flutter `#/HashUrlStrategy` URL strategy, so ensure it is not disabled for your web builds deployed to GitHub Pages. If it is disabled, the Navigator 2.0 subroutes will prevent GitHub Pages from resolving the correct app when refreshed. (You might want to use a --dart-define environment variable for this)
This GitHub Pages setup requires the Flutter `#` from [HashUrlStrategy](https://api.flutter.dev/flutter/package-flutter_web_plugins_url_strategy/HashUrlStrategy-class.html), so ensure it is not disabled for your Flutter Web CI builds deployed to GitHub Pages. If it is disabled, the Navigator 2.0 subroutes will prevent GitHub Pages from resolving the correct app when refreshed.

For example, in your CI workflow using the argument `--dart-define ENABLE_HASH_URL_STRATEGY=true`

```dart
void main() {
final useHashUrlStrategy = Platform.environment['ENABLE_HASH_URL_STRATEGY'] ?? false;
if (!useHashUrlStrategy) {
setUrlStrategy();
}
runApp(MyApp());
}
```

## Workflow 1 - Deploy Flutter Web Branch Previews

This workflow file can be added to your `.github/workflows` directory, or integrated into your existing CI workflow. It will build Flutter for Web and deploy it to `gh-pages` under the branch name folder.
This workflow file can be added to your `.github/workflows` directory, or integrated into your existing CI workflow. It will build Flutter for Web and deploy it to `gh-pages` under the branch name folder. After this section, the app should now be viewable at URL `gh_pages_url/branch_name`.

This workflow is configured to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) so that the index file workflow will be triggered. The PAT can be omitted if you do not add the index file workflow, or only run it manually.

```yaml
name: Deploy Branch Previews

# Can also be restricted by branches if you choose.
on:
push:
branches:
- '**'
- '!gh-pages'

# Write permissions need to be enabled for the workflow to write to GitHub Pages.
permissions:
Expand All @@ -42,7 +57,7 @@ jobs:
cache: true
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
- name: Get branch name
- name: Get branch name from event
id: branch-name
uses: tj-actions/branch-names@v8
- name: Build Web
Expand All @@ -52,23 +67,31 @@ jobs:
- name: Deploy to GitHub Pages 🚀
uses: JamesIves/github-pages-deploy-action@releases/v4
with:
branch: gh-pages # The branch the action should deploy to.
folder: build/web # The folder the action should deploy.
# required for index file workflow to be triggered automatically
token: ${{ secrets.PAT }}
branch: gh-pages
folder: build/web
target-folder: "${{ steps.branch-name.outputs.current_branch }}"
```
Finally, enable read and write permissions for GitHub Actions and enable GitHub Pages for your repository. Your app should now be viewable at URL `gh_pages_url/` + `branch_name`.
### Repository Settings
(We aren't done yet, we still need to clean up deleted branches and create an index file to link to each branch preview.)
* Enable read and write permissions for GitHub Actions
* `Repository Settings > Actions > General > Workflows permissions`
* Enable GitHub Pages for your repository, see the below images for how it should look.
* `Repository Settings > Pages`
* Source: Deploy from a branch
* Branch: `gh-pages` with `/ (root)` path

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5zd8ga3axhrb5txz70b.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ve8aiv937gv97npgqwe.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72uu08bz39lhfd54t9ha.png)

## Workflow 2 - Generating the Index File

This workflow file should be added to your `.github/workflows` directory. It will create a `README.md` file in the `gh-pages` branch that links to each branch preview deployed to GitHub Pages.
This workflow *must* be pushed to the `gh-pages` branch, otherwise it will not run.
This workflow file should be added to your `.github/workflows` directory. It will create a `README.md` file in the `gh-pages` branch that links to each branch preview deployed to GitHub Pages. This workflow *must* be pushed to the `gh-pages` branch, otherwise it will not run.

This workflow requires the other two workflow files to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) to run automatically. If you are not comfortable with this, omit this workflow or only run it manually using `workflow_dispatch`.

```yaml
name: gh_pages_readme
Expand All @@ -86,18 +109,15 @@ jobs:
with:
fetch-depth: 0
ref: gh-pages
- name: Delete README.md
- name: Delete gh-pages README.md
run: rm -f README.md
# get list of branches and generate links to each branch's subfolder in the README.md file
- name: Generate README.md
- name: Generate gh-pages README.md
run: |
echo "## Flutter Branch Web Previews" >> README.md
echo "" >> README.md
git branch -r | grep -v '\->' | grep -v 'origin/gh-pages' | while read remote; do
if [ -d "${remote#origin/}" ]; then
echo "- [${remote#origin/}](./${remote#origin/}/)" >> README.md
fi
done
git branch -r | grep -v '\->' | grep -v 'origin/gh-pages' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
for branch in `git branch -r | grep -v '\->' | grep -v 'origin/gh-pages'`; do echo "- [${branch#origin/}](./${branch#origin/}/)" >> README.md; done
- name: Commit and push if changed
run: |
git config --global user.name 'GitHub Actions'
Expand All @@ -107,18 +127,23 @@ jobs:
git push
```
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9vdw2ljmgtwpgia1nlff.png)
*The generated index file is pretty barebones, but it gets the job done.*
## Workflow 3 - Deleted Branch Cleanup
Finally, we need to clean up deleted branches from gh-pages, otherwise the repository size will grow indefinitely.
This workflow will run on branch deletions and remove the associated folder from gh-pages.
Finally, we need to clean up deleted branches from `gh-pages`, otherwise the repository size will grow indefinitely. This workflow will run on branch deletions and remove the folder from `gh-pages` with the same name as the branch.

This workflow is configured to use a [Personal Access Token (PAT)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) so that the index file workflow will be triggered.

```yaml
name: gh-pages-cleanup
on: delete
jobs:
cleanup:
name: Cleanup gh-pages
name: Cleanup deleted branch from gh-pages
runs-on: ubuntu-latest
if: github.event.ref_type == 'branch'
steps:
Expand All @@ -129,6 +154,8 @@ jobs:
with:
lfs: true
ref: gh-pages
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v8
Expand All @@ -141,10 +168,19 @@ jobs:
BASE_REF=$(printf "%q" "${{ github.event.ref }}")
BASE_REF=${BASE_REF/refs\/heads\/}
echo "Deleting folder: $BASE_REF"
git rm -rf $BASE_REF
git commit -m "Remove deleted branch $BASE_REF"
git push
if test -d "$BASE_REF"; then
echo "Deleting folder: $BASE_REF"
git rm -rf "$BASE_REF"
git commit -m "Remove deleted branch"
else
echo "Folder $BASE_REF does not exist"
fi
- name: Push changes
uses: ad-m/github-push-action@v0.8.0
with:
# required for index file workflow to be triggered automatically
github_token: ${{ secrets.PAT }}
branch: gh-pages
```

Thanks for reading, hope it helps. I previously used an older version of this process for a Godot project, so most of this should be reusable in other languages/frameworks.
17 changes: 10 additions & 7 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,15 @@ class App extends ConsumerWidget {
);
});

final bannerEnabled = settings.bannerEnabled;
if (bannerEnabled) {
return FlavorBanner(
child: materialApp,
);
}
return materialApp;
return Stack(
alignment: Alignment.topRight,
children: [
materialApp,
if (settings.bannerEnabled)
const SafeArea(
child: FlavorBanner(),
),
],
);
}
}
Loading

0 comments on commit 824809d

Please sign in to comment.