|
638 | 638 | --prefix PATH : ${pkgs.nushell}/bin
|
639 | 639 | '';
|
640 | 640 | # Script to run the AMI build and tests locally
|
641 |
| - testinfra-env = pkgs.runCommand "testinfra-env" |
| 641 | + build-test-ami = pkgs.runCommand "build-test-ami" |
642 | 642 | {
|
643 | 643 | buildInputs = with pkgs; [
|
644 | 644 | packer
|
645 | 645 | awscli2
|
646 | 646 | yq
|
647 | 647 | jq
|
648 | 648 | openssl
|
649 |
| - pythonEnv |
650 | 649 | git
|
651 | 650 | coreutils
|
652 | 651 | aws-vault
|
653 | 652 | ];
|
654 | 653 | } ''
|
655 | 654 | mkdir -p $out/bin
|
656 |
| - cat > $out/bin/testinfra-env << 'EOL' |
| 655 | + cat > $out/bin/build-test-ami << 'EOL' |
657 | 656 | #!/usr/bin/env bash
|
658 | 657 | set -euo pipefail
|
659 | 658 |
|
|
663 | 662 | yq
|
664 | 663 | jq
|
665 | 664 | openssl
|
666 |
| - pythonEnv |
667 | 665 | git
|
668 | 666 | coreutils
|
669 | 667 | aws-vault
|
|
680 | 678 | # Check AWS Vault profile
|
681 | 679 | if [ -z "''${AWS_VAULT:-}" ]; then
|
682 | 680 | echo "Error: AWS_VAULT environment variable must be set with the profile name"
|
683 |
| - echo "Usage: aws-vault exec supabase-dev -- nix run .#testinfra-env 15" |
| 681 | + echo "Usage: aws-vault exec supabase-dev -- nix run .#build-test-ami 15" |
684 | 682 | exit 1
|
685 | 683 | fi
|
686 | 684 |
|
|
725 | 723 | -var "git_sha=$GIT_SHA" \
|
726 | 724 | stage2-nix-psql.pkr.hcl
|
727 | 725 |
|
| 726 | + # Cleanup instances from AMI builds |
| 727 | + cleanup_instances() { |
| 728 | + aws ec2 --region $REGION describe-instances \ |
| 729 | + --filters "Name=tag:packerExecutionId,Values=$RUN_ID" \ |
| 730 | + --query "Reservations[].Instances[].InstanceId" \ |
| 731 | + --output text | xargs -r aws ec2 terminate-instances \ |
| 732 | + --region $REGION --instance-ids || true |
| 733 | + } |
| 734 | +
|
| 735 | + trap cleanup_instances EXIT |
| 736 | +
|
| 737 | + # Print the AMI name for use with run-testinfra |
| 738 | + echo "supabase-postgres-$RANDOM_STRING" |
| 739 | + EOL |
| 740 | + chmod +x $out/bin/build-test-ami |
| 741 | + ''; |
| 742 | + |
| 743 | + run-testinfra = pkgs.runCommand "run-testinfra" |
| 744 | + { |
| 745 | + buildInputs = with pkgs; [ |
| 746 | + pythonEnv |
| 747 | + awscli2 |
| 748 | + aws-vault |
| 749 | + ]; |
| 750 | + } '' |
| 751 | + mkdir -p $out/bin |
| 752 | + cat > $out/bin/run-testinfra << 'EOL' |
| 753 | + #!/usr/bin/env bash |
| 754 | + set -euo pipefail |
| 755 | +
|
| 756 | + export PATH="${pkgs.lib.makeBinPath (with pkgs; [ |
| 757 | + pythonEnv |
| 758 | + awscli2 |
| 759 | + aws-vault |
| 760 | + ])}:$PATH" |
| 761 | +
|
| 762 | + # Check for required tools |
| 763 | + for cmd in aws-vault; do |
| 764 | + if ! command -v $cmd &> /dev/null; then |
| 765 | + echo "Error: $cmd is required but not found" |
| 766 | + exit 1 |
| 767 | + fi |
| 768 | + done |
| 769 | +
|
| 770 | + # Check AWS Vault profile |
| 771 | + if [ -z "''${AWS_VAULT:-}" ]; then |
| 772 | + echo "Error: AWS_VAULT environment variable must be set with the profile name" |
| 773 | + echo "Usage: aws-vault exec supabase-dev -- nix run .#run-testinfra <ami-name>" |
| 774 | + exit 1 |
| 775 | + fi |
| 776 | +
|
| 777 | + # Check for AMI name argument |
| 778 | + if [ -z "''${1:-}" ]; then |
| 779 | + echo "Error: AMI name must be provided" |
| 780 | + echo "Usage: aws-vault exec supabase-dev -- nix run .#run-testinfra <ami-name>" |
| 781 | + exit 1 |
| 782 | + fi |
| 783 | +
|
| 784 | + AMI_NAME="$1" |
| 785 | + REGION="ap-southeast-1" |
| 786 | + RUN_ID=$(date +%s) |
| 787 | +
|
728 | 788 | # Run tests
|
729 |
| - AMI_NAME="supabase-postgres-$RANDOM_STRING" |
730 | 789 | ${pythonEnv}/bin/pytest -vv -s testinfra/test_ami_nix.py --ami-name="$AMI_NAME"
|
731 | 790 |
|
732 |
| - # Cleanup |
733 |
| - cleanup() { |
734 |
| - # Terminate instances |
| 791 | + # Cleanup test instance |
| 792 | + cleanup_instance() { |
735 | 793 | aws ec2 --region $REGION describe-instances \
|
736 |
| - --filters "Name=tag:packerExecutionId,Values=$RUN_ID" \ |
| 794 | + --filters "Name=tag:testinfra-run-id,Values=$RUN_ID" \ |
737 | 795 | --query "Reservations[].Instances[].InstanceId" \
|
738 | 796 | --output text | xargs -r aws ec2 terminate-instances \
|
739 | 797 | --region $REGION --instance-ids || true
|
740 |
| -
|
741 |
| - # Deregister AMIs |
742 |
| - for AMI_PATTERN in "supabase-postgres-ci-ami-test-stage-1" "$RANDOM_STRING"; do |
743 |
| - aws ec2 describe-images --region $REGION --owners self \ |
744 |
| - --filters "Name=name,Values=$AMI_PATTERN" \ |
745 |
| - --query 'Images[*].ImageId' --output text | while read -r ami_id; do |
746 |
| - echo "Deregistering AMI: $ami_id" |
747 |
| - aws ec2 deregister-image --region $REGION --image-id "$ami_id" || true |
748 |
| - done |
749 |
| - done |
750 | 798 | }
|
751 | 799 |
|
752 |
| - trap cleanup EXIT |
| 800 | + trap cleanup_instance EXIT |
| 801 | + EOL |
| 802 | + chmod +x $out/bin/run-testinfra |
| 803 | + ''; |
| 804 | + |
| 805 | + cleanup-ami = pkgs.runCommand "cleanup-ami" |
| 806 | + { |
| 807 | + buildInputs = with pkgs; [ |
| 808 | + awscli2 |
| 809 | + aws-vault |
| 810 | + ]; |
| 811 | + } '' |
| 812 | + mkdir -p $out/bin |
| 813 | + cat > $out/bin/cleanup-ami << 'EOL' |
| 814 | + #!/usr/bin/env bash |
| 815 | + set -euo pipefail |
| 816 | +
|
| 817 | + export PATH="${pkgs.lib.makeBinPath (with pkgs; [ |
| 818 | + awscli2 |
| 819 | + aws-vault |
| 820 | + ])}:$PATH" |
| 821 | +
|
| 822 | + # Check for required tools |
| 823 | + for cmd in aws-vault; do |
| 824 | + if ! command -v $cmd &> /dev/null; then |
| 825 | + echo "Error: $cmd is required but not found" |
| 826 | + exit 1 |
| 827 | + fi |
| 828 | + done |
| 829 | +
|
| 830 | + # Check AWS Vault profile |
| 831 | + if [ -z "''${AWS_VAULT:-}" ]; then |
| 832 | + echo "Error: AWS_VAULT environment variable must be set with the profile name" |
| 833 | + echo "Usage: aws-vault exec supabase-dev -- nix run .#cleanup-ami <ami-name>" |
| 834 | + exit 1 |
| 835 | + fi |
| 836 | +
|
| 837 | + # Check for AMI name argument |
| 838 | + if [ -z "''${1:-}" ]; then |
| 839 | + echo "Error: AMI name must be provided" |
| 840 | + echo "Usage: aws-vault exec supabase-dev -- nix run .#cleanup-ami <ami-name>" |
| 841 | + exit 1 |
| 842 | + fi |
| 843 | +
|
| 844 | + AMI_NAME="$1" |
| 845 | + REGION="ap-southeast-1" |
| 846 | +
|
| 847 | + # Deregister AMIs |
| 848 | + for AMI_PATTERN in "supabase-postgres-ci-ami-test-stage-1" "$AMI_NAME"; do |
| 849 | + aws ec2 describe-images --region $REGION --owners self \ |
| 850 | + --filters "Name=name,Values=$AMI_PATTERN" \ |
| 851 | + --query 'Images[*].ImageId' --output text | while read -r ami_id; do |
| 852 | + echo "Deregistering AMI: $ami_id" |
| 853 | + aws ec2 deregister-image --region $REGION --image-id "$ami_id" || true |
| 854 | + done |
| 855 | + done |
| 856 | + EOL |
| 857 | + chmod +x $out/bin/cleanup-ami |
| 858 | + ''; |
| 859 | + |
| 860 | + trigger-nix-build = pkgs.runCommand "trigger-nix-build" |
| 861 | + { |
| 862 | + buildInputs = with pkgs; [ |
| 863 | + gh |
| 864 | + git |
| 865 | + coreutils |
| 866 | + ]; |
| 867 | + } '' |
| 868 | + mkdir -p $out/bin |
| 869 | + cat > $out/bin/trigger-nix-build << 'EOL' |
| 870 | + #!/usr/bin/env bash |
| 871 | + set -euo pipefail |
| 872 | +
|
| 873 | + export PATH="${pkgs.lib.makeBinPath (with pkgs; [ |
| 874 | + gh |
| 875 | + git |
| 876 | + coreutils |
| 877 | + ])}:$PATH" |
| 878 | +
|
| 879 | + # Check for required tools |
| 880 | + for cmd in gh git; do |
| 881 | + if ! command -v $cmd &> /dev/null; then |
| 882 | + echo "Error: $cmd is required but not found" |
| 883 | + exit 1 |
| 884 | + fi |
| 885 | + done |
| 886 | +
|
| 887 | + # Check if user is authenticated with GitHub |
| 888 | + if ! gh auth status &>/dev/null; then |
| 889 | + echo "Error: Not authenticated with GitHub. Please run 'gh auth login' first." |
| 890 | + exit 1 |
| 891 | + fi |
| 892 | +
|
| 893 | + # Get current branch and commit |
| 894 | + BRANCH=$(git rev-parse --abbrev-ref HEAD) |
| 895 | + COMMIT=$(git rev-parse HEAD) |
| 896 | +
|
| 897 | + # Check if we're on a standard branch |
| 898 | + if [[ "$BRANCH" != "develop" && ! "$BRANCH" =~ ^release/ ]]; then |
| 899 | + echo "Warning: Running workflow from non-standard branch: $BRANCH" |
| 900 | + echo "This is allowed but may not be the intended behavior in production." |
| 901 | + read -p "Continue? [y/N] " -n 1 -r |
| 902 | + echo |
| 903 | + if [[ ! $REPLY =~ ^[Yy]$ ]]; then |
| 904 | + echo "Aborted." |
| 905 | + exit 1 |
| 906 | + fi |
| 907 | + fi |
| 908 | +
|
| 909 | + # Trigger the workflow |
| 910 | + echo "Triggering nix-build workflow for branch $BRANCH (commit: $COMMIT)" |
| 911 | + gh workflow run nix-build.yml --ref "$BRANCH" |
| 912 | +
|
| 913 | + # Wait for workflow to start and get the run ID |
| 914 | + echo "Waiting for workflow to start..." |
| 915 | + sleep 5 |
| 916 | + |
| 917 | + # Get the latest run ID for this workflow |
| 918 | + RUN_ID=$(gh run list --workflow=nix-build.yml --limit 1 --json databaseId --jq '.[0].databaseId') |
| 919 | + |
| 920 | + if [ -z "$RUN_ID" ]; then |
| 921 | + echo "Error: Could not find workflow run ID" |
| 922 | + exit 1 |
| 923 | + fi |
| 924 | +
|
| 925 | + echo "Watching workflow run $RUN_ID..." |
| 926 | + echo "The script will automatically exit when the workflow completes." |
| 927 | + echo "Press Ctrl+C to stop watching (workflow will continue running)" |
| 928 | + echo "----------------------------------------" |
| 929 | + gh run watch "$RUN_ID" --exit-status |
753 | 930 | EOL
|
754 |
| - chmod +x $out/bin/testinfra-env |
| 931 | + chmod +x $out/bin/trigger-nix-build |
755 | 932 | '';
|
756 | 933 | };
|
757 | 934 |
|
|
1054 | 1231 | dbmate-tool = mkApp "dbmate-tool" "dbmate-tool";
|
1055 | 1232 | update-readme = mkApp "update-readme" "update-readme";
|
1056 | 1233 | show-commands = mkApp "show-commands" "show-commands";
|
1057 |
| - testinfra-env = mkApp "testinfra-env" "testinfra-env"; |
| 1234 | + build-test-ami = mkApp "build-test-ami" "build-test-ami"; |
| 1235 | + run-testinfra = mkApp "run-testinfra" "run-testinfra"; |
| 1236 | + cleanup-ami = mkApp "cleanup-ami" "cleanup-ami"; |
| 1237 | + trigger-nix-build = mkApp "trigger-nix-build" "trigger-nix-build"; |
1058 | 1238 | };
|
1059 | 1239 |
|
1060 | 1240 | # 'devShells.default' lists the set of packages that are included in the
|
|
1095 | 1275 | basePackages.start-replica
|
1096 | 1276 | basePackages.migrate-tool
|
1097 | 1277 | basePackages.sync-exts-versions
|
1098 |
| - basePackages.testinfra-env |
| 1278 | + basePackages.build-test-ami |
| 1279 | + basePackages.run-testinfra |
| 1280 | + basePackages.cleanup-ami |
1099 | 1281 | dbmate
|
1100 | 1282 | nushell
|
1101 | 1283 | pythonEnv
|
|
0 commit comments