johnmccutchan/rfwpad #2610
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Fork - Clone - Build flutter App - Deploy to gh-pages | |
run-name: ${{ github.event.inputs.owner }}/${{ github.event.inputs.repo }} | |
on: | |
workflow_dispatch: | |
inputs: | |
owner: | |
description: "Repository Owner" | |
required: true | |
repo: | |
description: "Repository" | |
required: true | |
fork-org: | |
description: "Fork organization" | |
required: true | |
run-id: | |
description: "Run identifier" | |
required: true | |
jobs: | |
webfolder: | |
runs-on: ubuntu-latest | |
env: | |
new-repo-name: ${{ github.event.inputs.owner }}-${{ github.event.inputs.repo }} | |
delay-miliseconds-to-validate-fork-finished: 5000 | |
timeout-minutes: 7 | |
steps: | |
- name: ${{ github.event.inputs.run-id }} | |
run: | | |
echo "run identifier ${{ github.event.inputs.run-id }}" | |
echo "new-repo-name ${{ env.new-repo-name }}" | |
- name: Fork repository | |
uses: actions/github-script@v4 | |
with: | |
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
script: | | |
const owner = '${{ github.event.inputs.owner }}'; | |
const repo = '${{ github.event.inputs.repo }}'; | |
const org = '${{ github.event.inputs.fork-org }}'; | |
const name = '${{ env.new-repo-name }}'; | |
async function forkRepo() { | |
try { | |
const response = await github.repos.createFork({ | |
owner: owner, | |
repo: repo, | |
organization: org, | |
name: name | |
}); | |
console.log(`Repository ${response.data.full_name} forked to organization ${org}`); | |
} catch (error) { | |
console.error('Failed to fork repository:', error); | |
if(error.status === 404){ | |
console.error('Repository not found. Stop workflow'); | |
throw error | |
} | |
} | |
} | |
forkRepo(); | |
- name: Wait until the fork finishes | |
uses: actions/github-script@v4 | |
with: | |
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
script: | | |
const owner = '${{ github.event.inputs.fork-org }}'; | |
const repo = '${{ env.new-repo-name }}'; | |
const delayTime = ${{ env.delay-miliseconds-to-validate-fork-finished }}; | |
async function repoExists() { | |
try { | |
const response = await github.repos.get({ | |
owner: owner, | |
repo: repo | |
}); | |
console.log(`Repository ${response.data.full_name} was found.`); | |
} catch (error) { | |
console.error('Failed to get repository', error); | |
throw error; | |
} | |
} | |
async function repoHasCommits() { | |
try { | |
const response = await github.repos.listCommits({ | |
owner: owner, | |
repo: repo | |
}); | |
if(response.status !== 200){ | |
console.log(`Didn't find commits for the repository ${repo}. Response ${response}`); | |
return false; | |
} | |
console.log(`Repository ${repo} has commits.`); | |
return true; | |
} catch (error) { | |
console.error(`Failed to list commits of repository ${repo}`, error); | |
return false; | |
} | |
} | |
function delay(time) { | |
console.log(`Delay for ${time} miliseconds`) | |
return new Promise(resolve => setTimeout(resolve, time)); | |
} | |
repoExists(); | |
let hasCommits = await repoHasCommits(); | |
while(!hasCommits){ | |
await delay(delayTime) | |
hasCommits = await repoHasCommits(); | |
} | |
- name: Clone or Checkout repository | |
uses: actions/checkout@v2 | |
with: | |
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
repository: ${{ github.event.inputs.fork-org }}/${{ env.new-repo-name }} | |
- name: Find Flutter project path | |
id: flutter-project-project-path | |
run: | | |
# Find the directory containing the file with the string 'project_type: app' | |
METADATA_DIR=$(dirname $(grep -Eril "project_type: app" *) | sort -u) | |
if [ ! -z "$METADATA_DIR" ]; then | |
echo "Found .metadata file under '$METADATA_DIR' folder" | |
echo "FLUTTER_PROJECT_PATH=$METADATA_DIR" >> "$GITHUB_OUTPUT" | |
else | |
# Find the directory containing the file 'pubspec.lock' | |
PUBSPEC_LOCK_DIR=$(find . -name "pubspec.lock" -exec dirname {} \;) | |
if [ ! -z "$PUBSPEC_LOCK_DIR" ]; then | |
echo "pubspec.lock file was found." | |
while IFS= read -r dir | |
do | |
if [[ -d "$dir/web" || -d "$dir/android" || -d "$dir/ios" || -d "$dir/linux" || -d "$dir/windows" || -d "$dir/macos" ]]; then | |
echo "Found pubspec.lock in the same folder as the other important flutter folders. This is under '$dir'" | |
echo "FLUTTER_PROJECT_PATH=$dir" >> "$GITHUB_OUTPUT" | |
exit 0 | |
else | |
shift | |
fi | |
done <<< "$PUBSPEC_LOCK_DIR" | |
echo "None of the pubspec.lock files was found in the same folder as the other important flutter folders." | |
fi | |
# Find the first directory containing the file 'pubspec.yaml' | |
PUBSPEC_DIR=$(dirname $(find . -name "pubspec.yaml" | head -n 1)) | |
if [ -z "$PUBSPEC_DIR" ]; then | |
echo "pubspec.yaml file was not found. Stop workflow." | |
exit 1 | |
else | |
echo "pubspec.yaml file was found under '$PUBSPEC_DIR'." | |
echo "FLUTTER_PROJECT_PATH=$PUBSPEC_DIR" >> "$GITHUB_OUTPUT" | |
fi | |
fi | |
- name: Find supported Flutter version | |
id: flutter-version-finder | |
uses: ukoreh/actions/flutter-version-finder@master | |
with: | |
project-path: ${{ steps.flutter-project-project-path.outputs.FLUTTER_PROJECT_PATH }} | |
- name: Set up Flutter | |
uses: subosito/flutter-action@v2 | |
with: | |
flutter-version: ${{ steps.flutter-version-finder.outputs.flutter-version }} | |
channel: ${{ steps.flutter-version-finder.outputs.flutter-channel }} | |
- name: Setup Flutter web | |
run: | | |
channel=${{ steps.flutter-version-finder.outputs.flutter-channel }} | |
echo "on channel: $channel" | |
if [ "$channel" = "beta" ]; then | |
flutter config --enable-web | |
fi | |
- name: Check if 'web' folder exists | |
id: web-folder | |
run: | | |
cd ${{ steps.flutter-project-project-path.outputs.FLUTTER_PROJECT_PATH }} | |
echo "path now: ${{ steps.flutter-project-project-path.outputs.FLUTTER_PROJECT_PATH }}" | |
if [ -d "web" ]; then | |
echo "'web' folder exists in the same directory as 'pubspec.yaml'." | |
echo "WEB_FOLDER_LOCATION=$PWD" >> "$GITHUB_OUTPUT" | |
else | |
echo "'web' folder does not exist in the same directory as 'pubspec.yaml'. So create it!!!" | |
flutter create --org com.ukoreh.actions --platforms web . | |
echo "WEB_FOLDER_LOCATION=$PWD" >> "$GITHUB_OUTPUT" | |
fi | |
- name: Clean flutter | |
run: | | |
cd ${{ steps.web-folder.outputs.WEB_FOLDER_LOCATION }} | |
flutter clean | |
- name: Get packages | |
run: | | |
cd ${{ steps.web-folder.outputs.WEB_FOLDER_LOCATION }} | |
flutter pub get | |
- name: Build web app | |
run: | | |
cd ${{ steps.web-folder.outputs.WEB_FOLDER_LOCATION }} | |
flutter_version=${{ steps.flutter-version-finder.outputs.flutter-version }} | |
base_href="/${{ env.new-repo-name }}/" | |
if [[ "$flutter_version" =~ [1|2]\.[0-4]{1,}.+ ]]; then | |
flutter build web --release | |
sed -i "s|<base href=.*>|<!-- empty -> g" build/web/index.html | |
sed -i "s|<head>|<head><base href=\"$base_href\">|g" build/web/index.html | |
else | |
flutter build web --release --base-href $base_href | |
fi | |
- name: Deploy to GitHub Pages | |
uses: peaceiris/actions-gh-pages@v3 | |
with: | |
personal_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
publish_dir: ${{ steps.web-folder.outputs.WEB_FOLDER_LOCATION }}/build/web | |
external_repository: ${{ github.event.inputs.fork-org }}/${{ env.new-repo-name }} | |
publish_branch: gh-pages | |
- name: Create issue in the forked repository | |
if: ${{ vars.FF_STEP_CREATE_ISSUE == 'true' }} | |
uses: actions/github-script@v4 | |
with: | |
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
script: | | |
const owner = '${{ github.event.inputs.owner }}'; | |
const repo = '${{ github.event.inputs.repo }}'; | |
const org = '${{ github.event.inputs.fork-org }}'; | |
const name = '${{ env.new-repo-name }}'; | |
const title = "Your web app is ready! 🚀"; | |
const body = `Hey! 👋 | |
Someone has requested a demo of your project using [Ukoreh](https://ukoreh.fun/)! 🧙♂️. | |
The app compiled fine and is now live at https://${org}.github.io/${name}`; | |
async function createIssue() { | |
try { | |
const newIssue = await github.issues.create({ | |
owner: owner, | |
repo: repo, | |
title: title, | |
body: body, | |
}); | |
console.log(`Created issue ${newIssue.data.number}: ${newIssue.data.title}`); | |
} catch (error) { | |
console.error('Failed to create issue:', error); | |
if(error.status === 410){ | |
console.error('Issues are disabled in the repository'); | |
} | |
} | |
} | |
async function issueExists() { | |
try { | |
const { data: issues } = await github.issues.listForRepo({ | |
owner: owner, | |
repo: repo, | |
state: 'all' | |
}); | |
const existingIssue = issues.find(issue => issue.title === title); | |
const exists = existingIssue !== undefined; | |
console.log(`Issue with title "${title}" exists: ${exists}`); | |
return exists; | |
} catch (error) { | |
console.error('Failed to validate if issue already exists:', error); | |
} | |
} | |
const exists = await issueExists(); | |
if (!exists) { | |
console.log(`Creating issue with title ${title}`); | |
createIssue(); | |
} |